BookmarkSubscribeRSS Feed
Akshay5
Fluorite | Level 6
Hello Expperts,
 
Wanted to create a sas program that help creating new user profile [based on existing profile (template user for assigning same groups and roles) and if ever no template user is specified it assign a default group (group name we will define later it will a group to give basic seg access) to user].
Sas 9.4 M8
Can anyone help correcting below script as am getting error message when ruuning it:
ERROR 71-185: The METADATA_RESOLVE function call does not have enough arguments.
 
 
Thanking you in advance
 
 
/*=====================================================
SAS Metadata User Creation & Cloning Script with Logging
=======================================================*/
 
/* Securely handle metadata server credentials */
%let metaserver = "YourMetaServer";
%let metaport = 8561;
%let metauser = "Administrator";
%let metapass = "YourPassword"; /* Consider external configuration for security */
 
options metaserver=&metaserver
metarepository="Foundation"
        metaport=&metaport
        metauser=&metauser
        metapass=&metapass;
 
%let new_user_id = 1;           /* User ID for new user */
%let new_user_name = zz;        /* Full name for new user */
%let template_user_id = 2;      /* ID of template user (leave blank if none) */
%let default_group_name = "DefaultGroup";   /* Default group */
 
 
/*-------------------------------------------------------
Step 0: Initialize log dataset
--------------------------------------------------------*/
data user_creation_log;
    length NewUserID $50 NewUserName $100 TemplateUserID $50 Groups $500 Roles $500 Status $50 Timestamp $20;
    stop;
run;
 
/*-------------------------------------------------------
Step 1: Check if new user already exists
--------------------------------------------------------*/
data _null_;
    length userUri $200 rc 8;
    rc = metadata_resolve(cats("omsobj:Person?@UserId='&new_user_id'"), userUri);
    if rc > 0 then call symputx("userExists", "1");
    else call symputx("userExists", "0");
run;
 
%macro create_user_with_clone;
%if &userExists = 1 %then %do;
    %put NOTE: User ID &new_user_id already exists. No action taken.;
 
    /* Log existing user */
    data user_creation_log;
        NewUserID="&new_user_id";
        NewUserName="&new_user_name";
        TemplateUserID="&template_user_id";
        Groups="NA";
        Roles="NA";
        Status="Already Exists";
        Timestamp=datetime();
        format Timestamp datetime.;
        output;
    run;
 
%end;
%else %do;
 
    /*-------------------------------------------------------
    Step 2: Create new user
    --------------------------------------------------------*/
    data _null_;
        length newUserUri $200 rc 8;
        rc = metadata_createobj("omsobj:Person",
                                cats("Name='&new_user_name' ",
                                     "UserId='&new_user_id' "), 
                                newUserUri);
        if rc = 0 then do;
            put "NOTE: New user &new_user_name created: " newUserUri;
            call symputx("newUserUri", newUserUri);
            call symputx("createStatus","Created");
        end;
        else do;
            put "ERROR: Unable to create user, rc=" rc;
            call symputx("createStatus","Error");
        end;
    run;
 
    /*-------------------------------------------------------
    Step 3: Assign groups and roles
    --------------------------------------------------------*/
    %macro assign_groups_roles_log(newUserUri=, templateUserId=, defaultGroup=);
 
    %local templateUserUri groupsCount rolesCount i j groupUri roleUri groupsList rolesList;
 
    %let groupsList=;
    %let rolesList=;
 
    %if &templateUserId ne %then %do;
 
        /* Resolve template user URI */
        data _null_;
            length uri $200 rc 8;
            rc = metadata_resolve(cats("omsobj:Person?@UserId='&templateUserId'"), uri);
            if rc > 0 then call symputx("templateUserUri", uri);
            else call symputx("templateUserUri", "");
        run;
 
        /* Clone Groups */
        data _null_;
            length rc 8 groupUri $200;
            rc = metadata_getnasn("&templateUserUri", "Groups", groupUri, 1);
            if rc > 0 then do i=1 to rc;
                call symputx(cats("groupUri", i), groupUri);
            end;
            call symputx("groupsCount", rc);
        run;
 
        %if &groupsCount > 0 %then %do i=1 %to &groupsCount;
            data _null_;
                rc = metadata_setnasn("&newUserUri", "Groups", symget(cats("groupUri", &i)));
                if rc = 0 then put "NOTE: Group &i assigned successfully.";
                else put "ERROR: Failed to assign group &i, rc=" rc;
            run;
 
            /* Get group names for logging */
            data _null_;
                length groupName $100;
                rc = metadata_getattr(symget(cats("groupUri", &i)), "Name", groupName);
                call symputx(cats("gName", &i), groupName);
            run;
 
            %let groupsList=&groupsList &gName&i;
 
        %end;
 
        /* Clone Roles */
        data _null_;
            length rc 8 roleUri $200;
            rc = metadata_getnasn("&templateUserUri", "Roles", roleUri, 1);
            if rc > 0 then do j=1 to rc;
                call symputx(cats("roleUri", j), roleUri);
            end;
            call symputx("rolesCount", rc);
        run;
 
        %if &rolesCount > 0 %then %do j=1 %to &rolesCount;
            data _null_;
                rc = metadata_setnasn("&newUserUri", "Roles", symget(cats("roleUri", &j)));
                if rc = 0 then put "NOTE: Role &j assigned successfully.";
                else put "ERROR: Failed to assign role &j, rc=" rc;
            run;
 
            /* Get role names for logging */
            data _null_;
                length roleName $100;
                rc = metadata_getattr(symget(cats("roleUri", &j)), "Name", roleName);
                call symputx(cats("rName", &j), roleName);
            run;
 
            %let rolesList=&rolesList &rName&j;
        %end;
 
    %end;
    %else %do;
        /* No template user: assign default group only */
        data _null_;
            length groupUri rc rc2 8;
            rc = metadata_resolve(cats("omsobj:IdentityGroup?@Name='&defaultGroup'"), groupUri);
            if rc > 0 then do;
                rc2 = metadata_setnasn("&newUserUri", "Groups", groupUri);
                if rc2 = 0 then put "NOTE: Default group assigned to new user.";
                else put "ERROR: Failed to assign default group, rc=" rc2;
            end;
            else put "ERROR: Default group not found, rc=" rc;
        run;
        %let groupsList=&defaultGroup;
        %let rolesList=;
    %end;
 
    /* Log the created user */
    data user_creation_log;
        length NewUserID $50 NewUserName $100 TemplateUserID $50 Groups $500 Roles $500 Status $50 Timestamp $20;
        NewUserID="&new_user_id";
        NewUserName="&new_user_name";
        TemplateUserID="&template_user_id";
        Groups="&groupsList";
        Roles="&rolesList";
        Status="&createStatus";
        Timestamp=datetime();
        format Timestamp datetime.;
        output;
    run;
 
    %mend;
 
    %assign_groups_roles_log(newUserUri=&newUserUri,
                             templateUserId=&template_user_id,
                             defaultGroup=&default_group_name);
 
%end;
%mend;
 
/* Run the macro */
%create_user_with_clone;
 
/* Optional: View log */
proc print data=user_creation_log; run;

 

5 REPLIES 5
Akshay5
Fluorite | Level 6

Thanks for the update @Kurt_Bremser . I have been able to implement the profile creation but i have observed and issue with my code.

I am currently encountering an issue with our process for checking the existence of logins or display names within our metadata system. Our intended logic is to prevent any actions if either a login or display name already exists in the metadata. However, the implementation is not functioning as expected.

Specifically, we have profiles with logins such as toto234 and toto123, but we are unable to create a profile with the login toto. The system incorrectly identifies toto as an existing login, even though it does not exist in our metadata.

Below is an excerpt from the log of the run:

DEBUG: Row 1 - user_id_exists=1 user_name_exists=0
NOTE: Profile with login toto already exists. No action.

I am seeking guidance on how we can accurately perform this check to ensure that only truly existing logins or display names are flagged, thereby allowing the creation of new profiles when appropriate.

Any insights or suggestions you could provide would be greatly appreciated.

Thank you for your assistance.

Best regards

Akshay

 

Code:
%macro check_existing_user(user_id, user_name);
%global user_id_exists user_name_exists;
%let user_id_exists = 0;
%let user_name_exists = 0;

/* Check if User ID exists */
data _null_;
length loginUri userIdValue $256 rc i 8;
i = 1;
rc = metadata_getnobj("omsobj:Login?@UserID='&user_id'", i, loginUri);
do while (rc > 0);
rc = metadata_getattr(loginUri, "UserID", userIdValue);
if lowcase(userIdValue) = lowcase("&user_id") then do;
call symputx("user_id_exists", "1");
leave;
end;
i + 1;
rc = metadata_getnobj("omsobj:Login?@UserID='&user_id'", i, loginUri);
end;
run;

/* Check if User Name exists */
data _null_;
length personUri displayNameValue $256 rc j 8;
j = 1;
rc = metadata_getnobj("omsobj:Person?@DisplayName='&user_name'", j, personUri);
do while (rc > 0);
rc = metadata_getattr(personUri, "DisplayName", displayNameValue);
if lowcase(displayNameValue) = lowcase("&user_name") then do;
call symputx("user_name_exists", "1");
leave;
end;
j + 1;
rc = metadata_getnobj("omsobj:Person?@DisplayName='&user_name'", j, personUri);
end;
run;
%mend;

Tom
Super User Tom
Super User

You appear to be capturing the return code from the function calls

rc = metadata_getattr(loginUri, "UserID", userIdValue);

, but you are not testing the return code to check if the function succeeded before checking the value of the data set variable.

if lowcase(userIdValue) = lowcase("&user_id") then do;

Perhaps the call is failing and this is the cause of the false hits?

 

Akshay5
Fluorite | Level 6
Hello Expperts,
 
Wanted to create a sas program that help creating new user profile [based on existing profile (template user for assigning same groups and roles) and if ever no template user is specified it assign a default group (group name we will define later it will a group to give basic seg access) to user].
Sas 9.4 M8
Can anyone help correcting below script as am getting error message when ruuning it:
ERROR 71-185: The METADATA_RESOLVE function call does not have enough arguments.
 
 
Thanking you in advance
 
 
/*=====================================================
SAS Metadata User Creation & Cloning Script with Logging
=======================================================*/
 
/* Securely handle metadata server credentials */
%let metaserver = "YourMetaServer";
%let metaport = 8561;
%let metauser = "Administrator";
%let metapass = "YourPassword"; /* Consider external configuration for security */
 
options metaserver=&metaserver
metarepository="Foundation"
        metaport=&metaport
        metauser=&metauser
        metapass=&metapass;
 
%let new_user_id = 1;           /* User ID for new user */
%let new_user_name = zz;        /* Full name for new user */
%let template_user_id = 2;      /* ID of template user (leave blank if none) */
%let default_group_name = "DefaultGroup";   /* Default group */
 
 
/*-------------------------------------------------------
Step 0: Initialize log dataset
--------------------------------------------------------*/
data user_creation_log;
    length NewUserID $50 NewUserName $100 TemplateUserID $50 Groups $500 Roles $500 Status $50 Timestamp $20;
    stop;
run;
 
/*-------------------------------------------------------
Step 1: Check if new user already exists
--------------------------------------------------------*/
data _null_;
    length userUri $200 rc 8;
    rc = metadata_resolve(cats("omsobj:Person?@UserId='&new_user_id'"), userUri);
    if rc > 0 then call symputx("userExists", "1");
    else call symputx("userExists", "0");
run;
 
%macro create_user_with_clone;
%if &userExists = 1 %then %do;
    %put NOTE: User ID &new_user_id already exists. No action taken.;
 
    /* Log existing user */
    data user_creation_log;
        NewUserID="&new_user_id";
        NewUserName="&new_user_name";
        TemplateUserID="&template_user_id";
        Groups="NA";
        Roles="NA";
        Status="Already Exists";
        Timestamp=datetime();
        format Timestamp datetime.;
        output;
    run;
 
%end;
%else %do;
 
    /*-------------------------------------------------------
    Step 2: Create new user
    --------------------------------------------------------*/
    data _null_;
        length newUserUri $200 rc 8;
        rc = metadata_createobj("omsobj:Person",
                                cats("Name='&new_user_name' ",
                                     "UserId='&new_user_id' "), 
                                newUserUri);
        if rc = 0 then do;
            put "NOTE: New user &new_user_name created: " newUserUri;
            call symputx("newUserUri", newUserUri);
            call symputx("createStatus","Created");
        end;
        else do;
            put "ERROR: Unable to create user, rc=" rc;
            call symputx("createStatus","Error");
        end;
    run;
 
    /*-------------------------------------------------------
    Step 3: Assign groups and roles
    --------------------------------------------------------*/
    %macro assign_groups_roles_log(newUserUri=, templateUserId=, defaultGroup=);
 
    %local templateUserUri groupsCount rolesCount i j groupUri roleUri groupsList rolesList;
 
    %let groupsList=;
    %let rolesList=;
 
    %if &templateUserId ne %then %do;
 
        /* Resolve template user URI */
        data _null_;
            length uri $200 rc 8;
            rc = metadata_resolve(cats("omsobj:Person?@UserId='&templateUserId'"), uri);
            if rc > 0 then call symputx("templateUserUri", uri);
            else call symputx("templateUserUri", "");
        run;
 
        /* Clone Groups */
        data _null_;
            length rc 8 groupUri $200;
            rc = metadata_getnasn("&templateUserUri", "Groups", groupUri, 1);
            if rc > 0 then do i=1 to rc;
                call symputx(cats("groupUri", i), groupUri);
            end;
            call symputx("groupsCount", rc);
        run;
 
        %if &groupsCount > 0 %then %do i=1 %to &groupsCount;
            data _null_;
                rc = metadata_setnasn("&newUserUri", "Groups", symget(cats("groupUri", &i)));
                if rc = 0 then put "NOTE: Group &i assigned successfully.";
                else put "ERROR: Failed to assign group &i, rc=" rc;
            run;
 
            /* Get group names for logging */
            data _null_;
                length groupName $100;
                rc = metadata_getattr(symget(cats("groupUri", &i)), "Name", groupName);
                call symputx(cats("gName", &i), groupName);
            run;
 
            %let groupsList=&groupsList &gName&i;
 
        %end;
 
        /* Clone Roles */
        data _null_;
            length rc 8 roleUri $200;
            rc = metadata_getnasn("&templateUserUri", "Roles", roleUri, 1);
            if rc > 0 then do j=1 to rc;
                call symputx(cats("roleUri", j), roleUri);
            end;
            call symputx("rolesCount", rc);
        run;
 
        %if &rolesCount > 0 %then %do j=1 %to &rolesCount;
            data _null_;
                rc = metadata_setnasn("&newUserUri", "Roles", symget(cats("roleUri", &j)));
                if rc = 0 then put "NOTE: Role &j assigned successfully.";
                else put "ERROR: Failed to assign role &j, rc=" rc;
            run;
 
            /* Get role names for logging */
            data _null_;
                length roleName $100;
                rc = metadata_getattr(symget(cats("roleUri", &j)), "Name", roleName);
                call symputx(cats("rName", &j), roleName);
            run;
 
            %let rolesList=&rolesList &rName&j;
        %end;
 
    %end;
    %else %do;
        /* No template user: assign default group only */
        data _null_;
            length groupUri rc rc2 8;
            rc = metadata_resolve(cats("omsobj:IdentityGroup?@Name='&defaultGroup'"), groupUri);
            if rc > 0 then do;
                rc2 = metadata_setnasn("&newUserUri", "Groups", groupUri);
                if rc2 = 0 then put "NOTE: Default group assigned to new user.";
                else put "ERROR: Failed to assign default group, rc=" rc2;
            end;
            else put "ERROR: Default group not found, rc=" rc;
        run;
        %let groupsList=&defaultGroup;
        %let rolesList=;
    %end;
 
    /* Log the created user */
    data user_creation_log;
        length NewUserID $50 NewUserName $100 TemplateUserID $50 Groups $500 Roles $500 Status $50 Timestamp $20;
        NewUserID="&new_user_id";
        NewUserName="&new_user_name";
        TemplateUserID="&template_user_id";
        Groups="&groupsList";
        Roles="&rolesList";
        Status="&createStatus";
        Timestamp=datetime();
        format Timestamp datetime.;
        output;
    run;
 
    %mend;
 
    %assign_groups_roles_log(newUserUri=&newUserUri,
                             templateUserId=&template_user_id,
                             defaultGroup=&default_group_name);
 
%end;
%mend;
 
/* Run the macro */
%create_user_with_clone;
 
/* Optional: View log */
proc print data=user_creation_log; run;

 

Kurt_Bremser
Super User

I merged your identical questions; posting a question once is sufficient. Superusers can move a topic to a different community if this is necessary.

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 375 views
  • 1 like
  • 3 in conversation