Using Windows PowerShell to connect to a SAS Workspace server

This post is another in my series about creating apps with SAS Integration Technologies, a topic that I'm preparing for SAS Global Forum 2013.

In this article, I'll describe how to use Windows PowerShell to connect to a remote SAS Workspace, run a SAS program, and retrieve the results. This can be a useful method to implement a batch-style SAS job that you initiate from a client machine -- a common requirement in many SAS shops. The complete code example is on GitHub as SasWorkspaceExample.ps1.

Like my previous example with the SAS Metadata Server, this example begins with using SAS Object Manager. Use SAS Object Manager to create a ServerDef object that you use to connect to a SAS Workspace. This time we'll use the Workspace server port (by default, 8591) and the ClassIdentifier value for a SAS Workspace object. Remember, I used PROC IOMOPERATE to remind me which value that is, since I've never been any good at memorizing a 32-character hexadecimal value.

$objFactory = New-Object -ComObject SASObjectManager.ObjectFactoryMulti2
$objServerDef = New-Object -ComObject SASObjectManager.ServerDef
$objServerDef.MachineDNSName = "server.mycompany.com" # SAS Workspace node
$objServerDef.Port = 8591 # workspace server port
$objServerDef.Protocol = 2 # 2 = IOM protocol
# Class Identifier for SAS Workspace
$objServerDef.ClassIdentifier = "440196d4-90f0-11d0-9f41-00a024bb830c"

Connecting to a SAS Workspace

With an instance of an ObjectFactory class and the ServerDef class, you can now establish a connection to the server:

# create and connect to the SAS session
$objSAS = $objFactory.CreateObjectByServer(
"SASApp", # server name
$true,
$objServerDef, # used server definition for Workspace
"sasdemo", # user ID
"Password1" # password
)

When this statement completes successfully the $objSAS variable contains a connection to the SAS Workspace. With this connection, you can run SAS programs, read SAS data, and transfer files between the SAS Workspace and your application. (I'll cover how to transfer files in a future post.)

Running a SAS program with LanguageService

The SAS Workspace provides an API called LanguageService, which allows you to run SAS programs and retrieve the text-based results, including the SAS log and the SAS listing output. Here is a simple example using the $objSAS variable from the previous example:

$program = "ods listing; proc means data=sashelp.cars; run;"

# run the program
$objSAS.LanguageService.Submit($program);

These statements will run the program, but they won't retrieve your results. To see the contents of the SAS log, use the FlushLog method as in this example:

# flush the log - could redirect to external file
Write-Output "LOG:"
$log = ""
do
{
$log = $objSAS.LanguageService.FlushLog(1000)
Write-Output $log
} while ($log.Length -gt 0)

The FlushLog method requires that you specify the number of bytes that you want to retrieve in a single call. In the above example, we used 1000. But what if your SAS log is greater than 1000 characters? That's the reason for the do..while loop. In this example, the PowerShell statements will continue to retrieve and emit the SAS log content until the FlushLog method no longer returns any content (that is, while the length of the $log variable is greater than 0).

You can retrieve the SAS listing output in a similar way by using the FlushList method:

# flush the output - could redirect to external file
Write-Output "Output:"
$list = ""
do
{
$list = $objSAS.LanguageService.FlushList(1000)
Write-Output $list
} while ($list.Length -gt 0)

This picture shows the Windows PowerShell ISE (scripting environment) with the script output:

Closing the SAS Session

It's important to manage the lifetime of the SAS session in a responsible way. If you create a SAS Workspace connection and use it within your application, you should call the Close method on the SAS.Workspace object when your work is complete. This is especially true if your application is designed to stay running for a long time, even when the SAS session is not in use.

To close the SAS Workspace session, use the Close() method:

# end the SAS session
$objSAS.Close()