Calling Windows PowerShell from SAS: a simple example

As I mentioned in my introductory post about Windows PowerShell, you can use PowerShell commands as a simple and concise method to collect data from your Windows systems -- information that is ripe for analysis within SAS.

In this example, I'll show a technique for using a SAS program to call PowerShell and funnel the results directly into your SAS session for analysis. This example uses the Get-Process cmdlet (pronounced /command-let/) to collect information about running processes on a given Windows machine.

I built this example in pieces, making sure that each part worked before putting it all together:

I ran the powershell command from a command prompt console, and redirected the output to a text file. For example:

powershell -Command "Get-Process -ComputerName L73391"
> c:\temp\outProcesses.txt

I worked with the text file in SAS and SAS Enterprise Guide to develop a DATA step that could read/interpret it

I combined the command and DATA step into a program using FILENAME PIPE syntax

I tested the program on different machines, just to make sure that the behavior of the command and the text file didn't change across machines.

In order to run this example, you need the following conditions to be true:

You should enable PowerShell scripts to run, as I described in my previous post.

Your SAS session must be running on Windows, on a machine where PowerShell is available. Most modern Windows machines will have PowerShell already. But if you are running Windows XP or Windows Server 2003, you might need to download and install Windows PowerShell.

Your SAS session needs access to the FILENAME PIPE feature. This is linked to the ability to run system commands. If you're running the program through SAS Enterprise Guide, you'll need to check that proper XCMD options are enabled.

/* name of a machine on my network where I have admin rights */
%let machine = L73391;
filename process pipe
"powershell -Command ""Get-Process -ComputerName &machine.""";
data processes;
infile process firstobs=4;
length
Handles 8
WorkingSet 8
CPU 8
ID $ 8
ProcessName $ 255;
format
WorkingSet comma12.
Handles comma6.;
input @1 Handles
@25 WorkingSet
@42 CPU 42-50
@51 ID
@59 ProcessName;
run;

title "Processes on &machine";
/* with an ODS destination active, this will create a report */
proc sql;
select * from processes order by WorkingSet desc;
quit;

proc means data=processes;
var Handles WorkingSet;
run;

This produces a simple report of the active processes on the given machine. Here is a partial example of the output, in descending order of "Working Set" (which is one measurement of the amount of system memory in use by a process).