diff --git a/all.sas b/all.sas
index da2460e..a3b9ec9 100644
--- a/all.sas
+++ b/all.sas
@@ -29758,6 +29758,103 @@ Usage:
%mend mx_getcode;
/**
+ @file
+ @brief Fetches all groups or the groups for a particular member
+ @details When building applications that run on multiple flavours of SAS, it
+ is convenient to use a single macro (like this one) to fetch the groups
+ regardless of the flavour of SAS being used
+
+ The alternative would be to compile a generic macro in target-specific
+ folders (SASVIYA, SAS9 and SASJS). This avoids compiling unnecessary macros
+ at the expense of a more complex sasjsconfig.json setup.
+
+
+ @param [in] mdebug= (0) Set to 1 to enable DEBUG messages
+ @param [in] user= (0) Provide the username on which to filter
+ @param [in] uid= (0) Provide the userid on which to filter
+ @param [in] repo= (foundation) SAS9 only, choose the metadata repo to query
+ @param [in] access_token_var= (ACCESS_TOKEN) VIYA only.
+ The global macro variable to contain the access token
+ @param [in] grant_type= (sas_services) VIYA only.
+ Valid values are "password" or "authorization_code" (unquoted).
+ @param [out] outds= (work.mx_getgroups) This output dataset will contain the
+ list of groups. Format:
+|GROUPNAME:$32.|GROUPDESC:$256.|GROUPURI:best.|
+|---|---|---|
+|`SomeGroup `|`A group `|`1`|
+|`Another Group`|`this is a different group`|`2`|
+|`admin`|`Administrators `|`3`|
+
+
SAS Macros
+ @li mf_getplatform.sas
+ @li mm_getgroups.sas
+ @li ms_getgroups.sas
+ @li mv_getgroups.sas
+ @li mv_getusergroups.sas
+
+**/
+
+%macro mx_getgroups(
+ mdebug=0,
+ user=0,
+ uid=0,
+ repo=foundation,
+ access_token_var=ACCESS_TOKEN,
+ grant_type=sas_services,
+ outds=work.mx_getgroups
+)/*/STORE SOURCE*/;
+%local platform name shortloc;
+%let platform=%mf_getplatform();
+
+%if &platform=SASJS %then %do;
+ %ms_getgroups(
+ user=&user,
+ uid=&uid,
+ outds=&outds,
+ mdebug=&mdebug
+ )
+ data &outds;
+ length groupuri groupname $32 groupdesc $128 ;
+ set &outds;
+ keep groupuri groupname groupdesc;
+ groupuri=cats(groupid);
+ groupname=name;
+ groupdesc=description;
+ run;
+ proc sort; by groupname; run;
+%end;
+%else %if &platform=SAS9 or &platform=SASMETA %then %do;
+ %if &user=0 %then %let user=;
+ %mm_getGroups(
+ user=&user
+ ,outds=&outds
+ ,repo=&repo
+ ,mDebug=&mdebug
+ )
+ proc sort data=&outds; by groupname; run;
+%end;
+%else %if &platform=SASVIYA %then %do;
+ %if &user=0 %then %do;
+ %mv_getgroups(access_token_var=&access_token_var
+ ,grant_type=&grant_type
+ ,outds=&outds
+ )
+ %end;
+ %else %do;
+ %mv_getusergroups(&user
+ ,outds=&outds
+ ,access_token_var=&access_token_var
+ ,grant_type=&grant_type
+ )
+ %end;
+ proc sort
+ data=&outds(rename=(id=groupuri name=groupname description=groupdesc))
+ out=&outds (keep=groupuri groupname groupdesc);
+ by groupname;
+ run;
+%end;
+
+%mend mx_getgroups;/**
@file
@brief Will execute a SASjs web service on SAS 9, Viya or SASjs Server
@details Prepares the input files and retrieves the resulting datasets from
diff --git a/tests/x-platform/mx_getgroups.test.sas b/tests/x-platform/mx_getgroups.test.sas
new file mode 100644
index 0000000..58793a1
--- /dev/null
+++ b/tests/x-platform/mx_getgroups.test.sas
@@ -0,0 +1,41 @@
+/**
+ @file
+ @brief Testing mx_getgroups.test.sas macro
+
+ Be sure to run %let mcTestAppLoc=/Public/temp/macrocore; when
+ running in Studio
+
+ SAS Macros
+ @li mf_nobs.sas
+ @li mf_getuser.sas
+ @li mp_assert.sas
+ @li mx_getgroups.sas
+
+**/
+
+
+%mx_getgroups(outds=work.test1)
+
+%mp_assert(
+ iftrue=(%mf_nobs(work.test1)>0),
+ desc=groups were found,
+ outds=work.test_results
+)
+%mp_assertcols(work.test1,
+ cols=groupuri groupname groupdesc,
+ test=ALL,
+ desc=check all columns exist
+)
+
+%mx_getgroups(outds=work.test2,user=%mf_getuser())
+
+%mp_assert(
+ iftrue=(%mf_nobs(work.test2)>0),
+ desc=groups for current user were found,
+ outds=work.test_results
+)
+%mp_assertcols(work.test2,
+ cols=groupuri groupname groupdesc,
+ test=ALL,
+ desc=check all columns exist
+)
\ No newline at end of file
diff --git a/xplatform/mx_getgroups.sas b/xplatform/mx_getgroups.sas
new file mode 100644
index 0000000..7a9b098
--- /dev/null
+++ b/xplatform/mx_getgroups.sas
@@ -0,0 +1,98 @@
+/**
+ @file
+ @brief Fetches all groups or the groups for a particular member
+ @details When building applications that run on multiple flavours of SAS, it
+ is convenient to use a single macro (like this one) to fetch the groups
+ regardless of the flavour of SAS being used
+
+ The alternative would be to compile a generic macro in target-specific
+ folders (SASVIYA, SAS9 and SASJS). This avoids compiling unnecessary macros
+ at the expense of a more complex sasjsconfig.json setup.
+
+
+ @param [in] mdebug= (0) Set to 1 to enable DEBUG messages
+ @param [in] user= (0) Provide the username on which to filter
+ @param [in] uid= (0) Provide the userid on which to filter
+ @param [in] repo= (foundation) SAS9 only, choose the metadata repo to query
+ @param [in] access_token_var= (ACCESS_TOKEN) VIYA only.
+ The global macro variable to contain the access token
+ @param [in] grant_type= (sas_services) VIYA only.
+ Valid values are "password" or "authorization_code" (unquoted).
+ @param [out] outds= (work.mx_getgroups) This output dataset will contain the
+ list of groups. Format:
+|GROUPNAME:$32.|GROUPDESC:$256.|GROUPURI:best.|
+|---|---|---|
+|`SomeGroup `|`A group `|`1`|
+|`Another Group`|`this is a different group`|`2`|
+|`admin`|`Administrators `|`3`|
+
+ SAS Macros
+ @li mf_getplatform.sas
+ @li mm_getgroups.sas
+ @li ms_getgroups.sas
+ @li mv_getgroups.sas
+ @li mv_getusergroups.sas
+
+**/
+
+%macro mx_getgroups(
+ mdebug=0,
+ user=0,
+ uid=0,
+ repo=foundation,
+ access_token_var=ACCESS_TOKEN,
+ grant_type=sas_services,
+ outds=work.mx_getgroups
+)/*/STORE SOURCE*/;
+%local platform name shortloc;
+%let platform=%mf_getplatform();
+
+%if &platform=SASJS %then %do;
+ %ms_getgroups(
+ user=&user,
+ uid=&uid,
+ outds=&outds,
+ mdebug=&mdebug
+ )
+ data &outds;
+ length groupuri groupname $32 groupdesc $128 ;
+ set &outds;
+ keep groupuri groupname groupdesc;
+ groupuri=cats(groupid);
+ groupname=name;
+ groupdesc=description;
+ run;
+ proc sort; by groupname; run;
+%end;
+%else %if &platform=SAS9 or &platform=SASMETA %then %do;
+ %if &user=0 %then %let user=;
+ %mm_getGroups(
+ user=&user
+ ,outds=&outds
+ ,repo=&repo
+ ,mDebug=&mdebug
+ )
+ proc sort data=&outds; by groupname; run;
+%end;
+%else %if &platform=SASVIYA %then %do;
+ %if &user=0 %then %do;
+ %mv_getgroups(access_token_var=&access_token_var
+ ,grant_type=&grant_type
+ ,outds=&outds
+ )
+ %end;
+ %else %do;
+ %mv_getusergroups(&user
+ ,outds=&outds
+ ,access_token_var=&access_token_var
+ ,grant_type=&grant_type
+ )
+ %end;
+ proc sort
+ data=&outds(rename=(id=groupuri name=groupname description=groupdesc))
+ out=&outds (keep=groupuri groupname groupdesc);
+ by groupname;
+ run;
+%end;
+
+%mend mx_getgroups;
\ No newline at end of file