“omsobj: type/ID” or “omsobj: type?@attribute='value'”type is the name of the metadata type that represents the entity in the SAS Metadata Model. The
ID value or attribute= ‘value’ pair is used as a filter to locate
the objects that meet the criteria.
"omsobj:type?@Id contains '.'" The URI can return multiple objects.
The GETNOBJ DATA step function returns output in a two-dimensional
array. Each call to GETNOBJ retrieves the URI representing the nth
object returned from the query. In the examples, n=1 specifies to get the first object in the array. n+1 specifies to iterate through the content of the array.
/*Connect to the metadata server. */
options metaserver="myserver"
metaport=8561
metauser="sasadm@saspw"
metapass="adminpw"
metarepository="Foundation";
/* Begin the query. The DATA statement names the output data set. */
data metadata_libraries;
/* The LENGTH statement defines variables for function arguments and
assigns the maximum length of each variable. */
length liburi upasnuri $256 name $128 type id $17 libref engine $8 path
mdschemaname schema $256;
/* The KEEP statement defines the variables to include in the
output data set. */
keep name libref engine path mdschemaname schema;
/* The CALL MISSING routine initializes the output variables to missing values. */
call missing(liburi,upasnuri,name,engine,libref);
/* The METADATA_GETNOBJ function specifies to get the SASLibrary objects
in the repository. The argument nlibobj=1 specifies to get the first object that
matches the requested URI. liburi is an output variable. It will store the URI
of the returned SASLibrary object. */
nlibobj=1;
librc=metadata_getnobj("omsobj:SASLibrary?@Id contains '.'",nlibobj,liburi);
/* The DO statement specifies a group of statements to be executed as a unit
for each object that is returned by METADATA_GETNOBJ. The METADATA_GETATTR function
is used to retrieve the values of the Name, Engine, and Libref attributes of
the SASLibrary object. */
do while (librc>0);
/* Get Library attributes */
rc=metadata_getattr(liburi,'Name',name);
rc=metadata_getattr(liburi,'Engine',engine);
rc=metadata_getattr(liburi,'Libref',libref);
/* The METADATA_GETNASN function specifies to get objects associated to the
library via the UsingPackages association. The n argument specifies to return the
first associated object for that association type. upasnuri is an output variable.
It will store the URI of the associated metadata object, if one is found. */
n=1;
uprc=metadata_getnasn(liburi,'UsingPackages',n,upasnuri);
/* When a UsingPackages association is found, the METADATA_RESOLVE function
is called to resolve the URI to an object on the metadata server. The CALL MISSING
routine assigns missing values to output variables. */
if uprc > 0 then do;
call missing(type,id,path,mdschemaname,schema);
rc=metadata_resolve(upasnuri,type,id);
/* If type='Directory', the METADATA_GETATTR function is used to get its
path and output the record */
if type='Directory' then do;
rc=metadata_getattr(upasnuri,'DirectoryName',path);
output;
end;
/* If type='DatabaseSchema', the METADATA_GETATTR function is used to get
the name and schema, and output the record */
else if type='DatabaseSchema' then do;
rc=metadata_getattr(upasnuri,'Name',mdschemaname);
rc=metadata_getattr(upasnuri,'SchemaName',schema);
output;
end;
/* Check to see if there are any more Directory objects */
n+1;
uprc=metadata_getnasn(liburi,'UsingPackages',n,upasnuri);
end; /* if uprc > 0 */
/* Look for another library */
nlibobj+1;
librc=metadata_getnobj("omsobj:SASLibrary?@Id contains '.'",nlibobj,liburi);
end; /* do while (librc>0) */
run;
/* Print the metadata_libraries data set */
proc print data=metadata_libraries; run;
/*Connect to the metadata server with the metadata system options,
as shown in the previous example. */
data work.Libraries;
/* The LENGTH statement defines variables for function arguments and
assigns the maximum length for each variable. */
length LibId LibName $ 32 LibRef LibEngine $ 8 LibPath $ 256
ServerContext uri uri2 type $ 256 server $ 32;
/* The LABEL statement assigns descriptive labels to variables. */
label
LibId = "Library Id"
LibName = "Library Name"
LibRef = "SAS Libref"
LibEngine = "Library Engine"
ServerContext = "Server Contexts"
LibPath = "Library Path"
;
/* The CALL MISSING routine initializes output variables to missing values. */
call missing(LibId,LibName,LibRef,LibEngine,LibPath,
ServerContext,uri,uri2,type,server);
n=1;
n2=1;
/* The METADATA_GETNOBJ function gets the first Library object. If none
are found, the program prints an informational message. */
rc=metadata_getnobj("omsobj:SASLibrary?@Id contains '.'",n,uri);
if rc<=0 then put "NOTE: rc=" rc
"There are no Libraries defined in this repository"
" or there was an error reading the repository.";
/* The DO statement specifies a group of statements to be executed as a unit
for the object that is returned by METADATA_GETNOBJ. The METADATA_GETATTR
function gets the values of the Id, Name, LibRef, and Engine attributes
of the SASLibrary object. */
do while(rc>0);
objrc=metadata_getattr(uri,"Id",LibId);
objrc=metadata_getattr(uri,"Name",LibName);
objrc=metadata_getattr(uri,"Libref",LibRef);
objrc=metadata_getattr(uri,"Engine",LibEngine);
/* The METADATA_GETNASN function gets objects associated
via the DeployedComponents association. If none are found, the program
prints an informational message. */
objrc=metadata_getnasn(uri,"DeployedComponents",n2,uri2);
if objrc<=0 then
do;
put "NOTE: There is no DeployedComponents association for "
LibName +(-1)", and therefore no server context.";
ServerContext="";
end;
/* When an association is found, the METADATA_GETATTR function gets
the server name. */
do while(objrc>0);
objrc=metadata_getattr(uri2,"Name",server);
if n2=1 then ServerContext=quote(trim(server));
else ServerContext=trim(ServerContext)||" "||quote(trim(server));
/* Look for another ServerContext */
n2+1;
objrc=metadata_getnasn(uri,"DeployedComponents",n2,uri2);
end; /*do while objrc*/
n2=1;
/* The METADATA_GETNASN function gets objects associated via the
UsingPackages association. The program prints a message if an
association is not found.*/
objrc=metadata_getnasn(uri,"UsingPackages",n2,uri2);
if objrc<=0 then
do;
put "NOTE: There is no UsingPackages association for "
LibName +(-1)", and therefore no Path.";
LibPath="";
end;
/* When a UsingPackages association is found, the METADATA_RESOLVE function
is called to resolve the URI to an object on the metadata server. */
do while(objrc>0);
objrc=metadata_resolve(uri2,type,id);
/*if type='Directory', the METADATA_GETATTR function is used to get its path */
if type='Directory' then objrc=metadata_getattr(uri2,"DirectoryName",LibPath);
/*if type='DatabaseSchema', the METADATA_GETATTR function is used to get
the name */
else if type='DatabaseSchema' then objrc=metadata_getattr(uri2, "Name", LibPath);
else LibPath="*unknown*";
/* output the records */
output;
LibPath="";
/* Look for other directories or database schemas */
n2+1;
objrc=metadata_getnasn(uri,"UsingPackages",n2,uri2);
end; /*do while objrc*/
ServerContext="";
n+1;
/* Look for other libraries */
n2=1;
rc=metadata_getnobj("omsobj:SASLibrary?@Id contains '.'",n,uri);
end; /*do while rc*/
/* The KEEP statement defines the variables to include in the output data set. */
keep
LibId
LibName
LibRef
LibEngine
ServerContext
LibPath;
run;
/* Write a basic listing of data */
proc print data=work.Libraries label;
/* subset results if you wish
where indexw(ServerContext,'"SASMain"') > 0; */
run;
/*Connect to the metadata server using the metadata system options
shown in the first example.*/
data logins;
/* The LENGTH statement defines variables for function arguments and assigns
the maximum length for each variable. */
length LoginObjId UserId IdentId AuthDomId $ 17
IdentType $ 32
Name DispName Desc uri uri2 uri3 AuthDomName $ 256;
/* The CALL MISSING routine initializes the output variables to missing values. */
call missing
(LoginObjId, UserId, IdentType, IdentId, Name, DispName, Desc, AuthDomId, AuthDomName);
call missing(uri, uri2, uri3);
n=1;
/* The METADATA_GETNOBJ function specifies to get the Login objects
in the repository. The n argument specifies to get the first object that
matches the uri requested in the first argument. The uri argument is an output
variable. It will store the actual uri of the Login object that is returned.
The program prints an informational message if no objects are found. */
objrc=metadata_getnobj("omsobj:Login?@Id contains '.'",n,uri);
if objrc<=0 then put "NOTE: rc=" objrc
"There are no Logins defined in this repository"
" or there was an error reading the repository.";
/* The DO statement specifies a group of statements to be executed as a unit
for the Login object that is returned by METADATA_GETNOBJ. The METADATA_GETATTR
function gets the values of the object's Id and UserId attributes. */
do while(objrc>0);
arc=metadata_getattr(uri,"Id",LoginObjId);
arc=metadata_getattr(uri,"UserId",UserId);
/* The METADATA_GETNASN function specifies to get objects associated
via the AssociatedIdentity association. The AssociatedIdentity association name
returns both Person and IdentityGroup objects, which are subtypes of the Identity
metadata type. The URIs of the associated objects are returned in the uri2 variable.
If no associations are found, the program prints an informational message. */
n2=1;
asnrc=metadata_getnasn(uri,"AssociatedIdentity",n2,uri2);
if asnrc<=0 then put "NOTE: rc=" asnrc
"There is no Person or Group associated with the " UserId "user ID.";
/* When an association is found, the METADATA_RESOLVE function is called to
resolve the URI to an object on the metadata server. */
else do;
arc=metadata_resolve(uri2,IdentType,IdentId);
/* The METADATA_GETATTR function is used to get the values of each identity's
Name, DisplayName and Desc attributes. */
arc=metadata_getattr(uri2,"Name",Name);
arc=metadata_getattr(uri2,"DisplayName",DispName);
arc=metadata_getattr(uri2,"Desc",Desc);
end;
/* The METADATA_GETNASN function specifies to get objects associated
via the Domain association. The URIs of the associated objects are returned in
the uri3 variable. If no associations are found, the program prints an
informational message. */
n3=1;
autrc=metadata_getnasn(uri,"Domain",n3,uri3);
if autrc<=0 then put "NOTE: rc=" autrc
"There is no Authentication Domain associated with the " UserId "user ID.";
/* The METADATA_GETATTR function is used to get the values of each
AuthenticationDomain object's Id and Name attributes. */
else do;
arc=metadata_getattr(uri3,"Id",AuthDomId);
arc=metadata_getattr(uri3,"Name",AuthDomName);
end;
output;
/* The CALL MISSING routine reinitializes the variables back to missing values. */
call missing(LoginObjId, UserId, IdentType, IdentId, Name, DispName, Desc, AuthDomId,
AuthDomName);
/* Look for more Login objects */
n+1;
objrc=metadata_getnobj("omsobj:Login?@Id contains '.'",n,uri);
end;
/* The KEEP statement specifies the variables to include in the output data set. */
keep LoginObjId UserId IdentType Name DispName Desc AuthDomId AuthDomName;
run;
/* The PROC PRINT statement prints the output data set. */
proc print data=logins;
var LoginObjId UserId IdentType Name DispName Desc AuthDomId AuthDomName;
run;
/*Connect to the metadata server using the metadata system options as
shown in the first example. */
data users_grps;
/* The LENGTH statement defines variables for function arguments and
assigns the maximum length of each variable. */
length uri name dispname group groupuri $256
id MDUpdate $20;
/* The CALL MISSING routine initializes output variables to missing values.*/
n=1;
call missing(uri, name, dispname, group, groupuri, id, MDUpdate);
/* The METADATA_GETNOBJ function specifies to get the Person objects
in the repository. The n argument specifies to get the first Person object that is
returned. The uri argument will return the actual uri of the Person object that
is returned. The program prints an informational message if no Person objects
are found. */
nobj=metadata_getnobj("omsobj:Person?@Id contains '.'",n,uri);
if nobj=0 then put 'No Persons available.';
/* The DO statement specifies a group of statements to be executed as a unit
for the Person object that is returned by METADATA_GETNOBJ. The METADATA_GETATTR
function gets the values of the object's Name and DisplayName attributes. */
else do while (nobj > 0);
rc=metadata_getattr(uri, "Name", Name);
rc=metadata_getattr(uri, "DisplayName", DispName);
/* The METADATA_GETNASN function gets objects associated via the IdentityGroups
association. The a argument specifies to return the first associated object for
that association type. The URI of the associated object is returned in the
groupuri variable. */
a=1;
grpassn=metadata_getnasn(uri,"IdentityGroups",a,groupuri);
/* If a person does not belong to any groups, set their group
variable to 'No groups' and output their name. */
if grpassn in (-3,-4) then do;
group="No groups";
output;
end;
/* If the person belongs to many groups, loop through the list
and retrieve the Name and MetadataUpdated attributes of each group,
outputting each on a separate record. */
else do while (grpassn > 0);
rc2=metadata_getattr(groupuri, "Name", group);
rc=metadata_getattr(groupuri, "MetadataUpdated", MDUpdate);
a+1;
output;
grpassn=metadata_getnasn(uri,"IdentityGroups",a,groupuri);
end;
/* Retrieve the next person's information */
n+1;
nobj=metadata_getnobj("omsobj:Person?@Id contains '.'",n,uri);
end;
/* The KEEP statement specifies the variables to include in the output data set. */
keep name dispname MDUpdate group;
run;
/* Display the list of users and their groups */
proc report data=users_grps nowd headline headskip;
columns name dispname group MDUpdate;
define name / order 'User Name' format=$30.;
define dispname / order 'Display Name' format=$30.;
define group / order 'Group' format=$30.;
define MDUpdate / display 'Updated' format=$20.;
break after name / skip;
run;
/*Connect to the metadata server using the metadata system options as
shown in the first example. */
data work.Identities;
/* The LENGTH statement defines the lengths of variables for function arguments. */
length IdentId IdentName DispName ExtLogin IntLogin DomainName $32
uri uri2 uri3 uri4 $256;
/* The LABEL statement assigns descriptive labels to variables. */
label
IdentId = "Identity Id"
IdentName = "Identity Name"
DispName = "Display Name"
ExtLogin = "External Login"
IntLogin = "Is Account Internal?"
DomainName = "Authentication Domain";
/* The CALL MISSING statement initializes the output variables to missing values. */
call missing(IdentId, IdentName, DispName, ExtLogin, IntLogin, DomainName,
uri, uri2, uri3, uri4);
n=1;
n2=1;
/* The METADATA_GETNOBJ function specifies to get the Person objects in the repository.
The n argument specifies to get the first person object that is returned.
The uri argument will return the actual uri of the Person object. The program prints an
informational message if no objects are found. */
rc=metadata_getnobj("omsobj:Person?@Id contains '.'",n,uri);
if rc<=0 then put "NOTE: rc=" rc
"There are no identities defined in this repository"
" or there was an error reading the repository.";
/* The DO statement specifies a group of statements to be executed as a unit.
The METADATA_GETATTR function gets the values of the Person object's Id, Name,
and DisplayName attributes. */
do while(rc>0);
objrc=metadata_getattr(uri,"Id",IdentId);
objrc=metadata_getattr(uri,"Name",IdentName);
objrc=metadata_getattr(uri,"DisplayName",DispName);
/* The METADATA_GETNASN function gets objects associated via the
InternalLoginInfo association. The InternalLoginInfo association returns
internal logins. The n2 argument specifies to return the first associated object
for that association name. The URI of the associated object is returned in
the uri2 variable. */
objrc=metadata_getnasn(uri,"InternalLoginInfo",n2,uri2);
/* If a Person does not have any internal logins, set their IntLogin
variable to 'No' Otherwise, set to 'Yes'. */
IntLogin="Yes";
DomainName="**None**";
if objrc<=0 then
do;
put "NOTE: There are no internal Logins defined for " IdentName +(-1)".";
IntLogin="No";
end;
/* The METADATA_GETNASN function gets objects associated via the Logins association.
The Logins association returns external logins. The n2 argument specifies to return
the first associated object for that association name. The URI of the associated
object is returned in the uri3 variable. */
objrc=metadata_getnasn(uri,"Logins",n2,uri3);
/* If a Person does not have any logins, set their ExtLogin
variable to '**None**' and output their name. */
if objrc<=0 then
do;
put "NOTE: There are no external Logins defined for " IdentName +(-1)".";
ExtLogin="**None**";
output;
end;
/* If a Person has many logins, loop through the list and retrieve the name of
each login. */
do while(objrc>0);
objrc=metadata_getattr(uri3,"UserID",ExtLogin);
/* If a Login is associated to an authentication domain, get the domain name. */
DomainName="**None**";
objrc2=metadata_getnasn(uri3,"Domain",1,uri4);
if objrc2 >0 then
do;
objrc2=metadata_getattr(uri4,"Name",DomainName);
end;
/*Output the record. */
output;
n2+1;
/* Retrieve the next Login's information */
objrc=metadata_getnasn(uri,"Logins",n2,uri3);
end; /*do while objrc*/
/* Retrieve the next Person's information */
n+1;
n2=1;
rc=metadata_getnobj("omsobj:Person?@Id contains '.'",n,uri);
end; /*do while rc*/
/* The KEEP statement specifies the variables to include in the output data set. */
keep IdentId IdentName DispName ExtLogin IntLogin DomainName;
run;
/* The PROC PRINT statement writes a basic listing of the data. */
proc print data=work.Identities label;
run;
/* The PROC EXPORT statement can be used to write the data to an Excel spreadsheet. */
/* Change DATA= to the data set name you specified above. */
/* Change OUTFILE= to an appropriate path for your system. */
proc export data=work.Identities
dbms=EXCEL2000
outfile="C:\temp\Identities.xls"
replace;
run;