Hi all,
I have succesfully used the following program to invoke remote based SAS EG in windows using powershell and retrieve the log and listing to the powershell console. However I would like to take this a step further and create a delimited txt file to save on my local or a network drive. Can I alter the following program to do so? I would like to alter the powershell comands as I am unable to simply include a proc export due to restrictions on my local and network drives.
I think you're looking for the code to download a file using PowerShell, via SAS Integration Technologies. Read that blog post. Here's the full code on GitHub.
Note that even though you want to download a CSV file (text), I recommend using the binary file stream method. That will avoid transcoding issues that can occur with characters outside of your session encoding range. If the remote system is UNIX, you might need to fix line-endings on the Windows side after the download (as UNIX and Windows use different conventions for line ending characters).
As far as I can read your code, you are not using a remote Enterprise Guide, but connecting directly to a Workspace Server on a remote SAS host.
Since @ChrisHemedinger has created a custom task for Enterprise Guide to transfer any type of file using the IOM connection, I guess he could help you out with how to write that in Powershell.
I think you're looking for the code to download a file using PowerShell, via SAS Integration Technologies. Read that blog post. Here's the full code on GitHub.
Note that even though you want to download a CSV file (text), I recommend using the binary file stream method. That will avoid transcoding issues that can occur with characters outside of your session encoding range. If the remote system is UNIX, you might need to fix line-endings on the Windows side after the download (as UNIX and Windows use different conventions for line ending characters).
The code in my example should work to retrieve your file -- just download the CSV file instead of the PNG.
To then convert the line endings in the CSV (which might not be important to you, depending what your next step is), some straight PowerShell code can help. Here's an example I modified from stackoverflow to convert all CSV files in a local directory.
Get-ChildItem * -Include *.csv | ForEach-Object { ## If contains UNIX line endings, replace with Windows line endings if (Get-Content $_.FullName -Delimiter "`0" | Select-String "[^`r]`n") { $content = Get-Content $_.FullName $content | Set-Content $_.FullName } }
If you're just going to use the CSV file in Excel, I think you can skip this step. But if you think people will open these CSV files in a local text viewer on Windows, it's probably a good idea to convert.
If your objective is simply to write logs / text files / output from your SAS server session to a file share then I'd suggest it would be a lot easier just to do this directly from SAS to a server-accessible file share.
Something was amiss in that script, the way the binary stream was assembled for the target file. Try this example -- instead of writing the destination file in pieces, this one assembles the bytes in memory and uses WriteAllBytes.
# Example of how to use PowerShell to script the # SAS Integration Technologies client # You can connect to a remote SAS Workspace # and run a program, retrieve the SAS log and download a file # To use: change this script to reference your SAS Workspace # node name, port (if different), and user credentials # create the Integration Technologies objects $objFactory = New-Object -ComObject SASObjectManager.ObjectFactoryMulti2 $objServerDef = New-Object -ComObject SASObjectManager.ServerDef $objServerDef.MachineDNSName = "yourhost.company.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" try { # create and connect to the SAS session $objSAS = $objFactory.CreateObjectByServer( "SASApp", # server name $true, $objServerDef, # built server definition "sasdemo", # user ID "Password" # password ) } catch [system.exception] { Write-Host "Could not connect to SAS session: " $_.Exception.Message } # change these to your own SAS-session-based # file path and file name $destPath = "/u/userid/temp" $destFile = "class" # local directory for downloaded file $localPath = "c:\temp" # program to run # could be read from external file $program = "Filename csv '$destPath/$destFile.csv'; Data _null_; Set sashelp.class; File csv dlm=','; Put (_all_) (+0); Run;" # run the program $objSAS.LanguageService.Submit($program); # flush the log - could redirect to external file Write-Output "SAS LOG:" $log = "" do { $log = $objSAS.LanguageService.FlushLog(1000) Write-Output $log } while ($log.Length -gt 0) # now download the image file $fileref = "" # assign a Fileref so we can use FileService from IOM $objFile = $objSAS.FileService.AssignFileref( "csv", "DISK", "$destPath/$destFile.csv", "", [ref] $fileref); $StreamOpenModeForReading = 1 $objStream = $objFile.OpenBinaryStream($StreamOpenModeForReading) # define an array of bytes [Byte[]] $bytes = 0x0 $allbytes = @() $endOfFile = $false $byteCount = 0 do { # read bytes from source file, 1K at a time $objStream.Read(1024, [ref]$bytes) $allbytes += $bytes # if less than requested bytes, we're at EOF $endOfFile = $bytes.Length -lt 1024 # add to byte count for tally $byteCount = $byteCount + $bytes.Length } while (-not $endOfFile) [io.file]::WriteAllBytes("$localPath\$destFile.csv",$allbytes) # close input and output files $objStream.Close() # free the SAS fileref $objSAS.FileService.DeassignFileref($objFile.FilerefName) Write-Output "Downloaded $localPath\$destFile.csv: SIZE = $byteCount bytes" $objSAS.Close()
Output for me:
Downloaded c:\temp\class.csv: SIZE = 384 bytes
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.