Using Windows PowerShell to connect to a SAS Metadata Server

SAS Integration Technologies provides a flexible platform to create all types of apps, from simple utilities to full-blown applications. As part of the research for my SAS Global Forum 2013 paper (Create Your Own Client Apps Using SAS Integration Technologies), I've been trying to invent some useful examples that you can run from your Windows desktop. In this post I'll cover how you can use Windows PowerShell plus the SAS Integration Technologies client to connect to a SAS Metadata Server.

Creating objects with SAS Object Manager

When working with the SAS Integration Technologies client, you need a way to create the objects that represent the connections to the SAS services. For that, you must use the SAS Object Manager.

The SAS Object Manager includes a class named ObjectFactory. As the name implies, the "object factory" class is where your subsequent objects will be created. In our examples, we will use the ObjectFactoryMulti2 class to create the connection to the SAS server for use in our applications. After creating that connection, you can use methods on the connection object to get to the other services we need.

To get started with the SAS Object Manager in Windows PowerShell, use the New-Object -ComObject command.

$objFactory = New-Object -ComObject SASObjectManager.ObjectFactoryMulti2

Before you can connect to a SAS server, you must define its attributes to SAS Object Manager. A SAS server has several attributes: a host name, TCP port number, and a Class Identifier. The Class Identifier is a 32-character GUID (unique ID) that indicates the type of SAS server that you expect to connect to.

How to Find the Correct Class Identifier
If you search support.sas.com you may be able to find a "lookup" table for the Class Identifier values to map to the specific types of SAS servers. However, the most reliable source for these values, and usually the easiest to access, can come from SAS itself by way of PROC IOMOPERATE. Here is an example program:

proc iomoperate;
list types;
quit;

Here's an excerpt of the SAS log, which contains the values:

SAS Metadata Server
Short type name : Metadata
Class identifier : 0217e202-b560-11db-ad91-001083ff6836

SAS Stored Process Server
Short type name : StoredProcess
Class identifier : 15931e31-667f-11d5-8804-00c04f35ac8c

SAS Workspace Server
Short type name : Workspace
Class identifier : 440196d4-90f0-11d0-9f41-00a024bb830c

You use the SAS Object Manager to create a ServerDef object, and then use the CreateObjectByServer method to establish the connection. You name the SAS Metadata Server port (which is 8561 in a default installation) and the SAS Metadata Server value for the ClassIdentifier. Here is an example:

$objFactory = New-Object -ComObject SASObjectManager.ObjectFactoryMulti2
$objServerDef = New-Object -ComObject SASObjectManager.ServerDef

# assign the attributes of your metadata server
$objServerDef.MachineDNSName = "yournode.company.com"
$objServerDef.Port = 8561 # metadata server port
$objServerDef.Protocol = 2 # 2 = IOM protocol
# Class Identifier for SAS Metadata Server
$objServerDef.ClassIdentifier = "0217E202-B560-11DB-AD91-001083FF6836"

# connect to the server
# we'll get back an OMI handle (Open Metadata Interface)
try
{
$objOMI = $objFactory.CreateObjectByServer(
"",
$true,
$objServerDef,
"sasdemo", # metadata user ID
"Password1" # password
)
Write-Host "Connected to " $objServerDef.MachineDNSName
}
catch [system.exception]
{
Write-Host "Could not connect to SAS metadata server: " $_.Exception
exit -1
}

CreateObjectByServer returns a connection to the SAS Metadata Server, sometimes called OMI (which stands for "Open Metadata Interface" and is easily confused with IOM). In the above example program, the connection is in the PowerShell variable named $objOMI.

Most metadata operations require that you know the metadata ID for the repository in which your metadata resides. For most applications that's the Foundation repository. Even though it has a standard name ("Foundation"), the ID value can differ in each installation. So the next step is to use the GetRepositories method to find the ID value for the Foundation repository.

The GetRepositories method returns information within an XML-formatted structure, which you must then parse to get the information you need. Here is an example result from the GetRepositories method:

<Repositories>
<Repository Id="A0000001.A5B4FV3C"
Name="Foundation" Desc="" DefaultNS="SAS"/>
<Repository Id="A0000001.A5Q23NT1"
Name="BILineage" Desc="BILineage" DefaultNS="SAS"/>
</Repositories>

The nugget of information that you need from this example is A0000001.A5B4FV3C, which is the ID for the Foundation repository in this installation. Fortunately, Windows PowerShell provides an XML data type that makes it easy to filter and parse. The following code segment does the job:

# get list of repositories
$reps="" # this is an "out" param we need to define
$rc = $objOMI.GetRepositories([ref]$reps,0,"")

# parse the results as XML
[xml]$result = $reps

# filter down to "Foundation" repository
$foundationNode = $result.Repositories.Repository | ? {$_.Name -match "Foundation"}
$foundationId = $foundationNode.Id

Write-Host "Foundation ID is $foundationId"

There! The connection is made, and you know the Foundation ID. The next step is to use the metadata API methods (such as GetMetadataObjects) to retrieve useful information from the SAS Metadata Server.

I'll describe that in my next post, but if you want a sneak peak you can see the complete code for the example here (hosted on GitHub).