2

My Task Scheduler calls a Powershell script that starts a SAS program, which in turn executes a Windows command using %sysexec (and does a lot of other stuff on the side).

When I run the Powershell script interactively or start it manually in the Task Scheduler, the %sysexec command is executed correctly in the SAS program.

If the Powershell script is not started interactively by the Task Scheduler and I am not logged in on the computer, the %sysexec command is not executed. Nevertheless, it returns sysrc=0 as a result (success).

On the old machine with Windows Server 2012 it worked, on the new machine with Windows 2019 it does not.

I have written a highly simplified example here.

Task Scheduler Action:

powershell -executionpolicy bypass "C:\temp\test_sas.ps1"

Powershell Script test_sas.ps1:

$sasrootdirStr = "D:\sas\SASHome\SASFoundation\9.4"
$pgmdirStr = "C:\temp"
$pgmnameStr= "test_sas"
$logdirStr = "C:\temp"
$logfileStr = $logdirStr + "\" + $pgmnameStr + ".log"
& "$sasrootdirStr\sas.exe" "$pgmdirStr\$pgmnameStr.sas" -log "$logfileStr"

SAS program test_sas.sas:

%macro test_sas;
   %local macroname;
   %let macroname= test_sas;
   %let newdir = %str(C:\temp\martin);
   %let sysrc = -1;
   %sysexec "mkdir" &newdir..; 
   %if &sysrc ne 0 %then %do;
      %put ERROR: &macroname: Could not execute command mkdir (sysrc: &sysrc.).;
   %end;
   %put sysrc: &sysrc;
%mend test_sas;
%test_sas;

Result in logfile test_sas.log (the %sysexec command mkdir was not executed):

sysrc: 0
NOTE: SAS Institute Inc, SAS Campus Drive, Cary, NC USA 27513-2414
NOTE: The SAS System used:
      real time 0.60 seconds
      cpu time 0.68 seconds

Used software versions:

new (with error):

  • SAS 9.04.01M7P080520
  • Windows Server 2019 Standard Version 1809
  • Powershell 5.1.17763.2931

old (without errors):

  • SAS 9.04.01M4P110916
  • Windows Server 2012 R2 Standard
  • Powershell 4.0

What is wrong?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Martin F.
  • 57
  • 6
  • 1
    `mkdir` is not an executable. Try `%sysexec cmd /c mkdir &newdir;` – Mathias R. Jessen Aug 30 '22 at 15:41
  • 1
    In actual script (not simplified here), what was the subprocess and if it is not SAS specific, why use SAS and not PowerShell itself? – Parfait Aug 30 '22 at 15:57
  • 1
    Did you trying using PIPE instead of %SYSEXEC so your SAS code can retrieve any messages the operating system is outputting in response to your attempt to run a command? `data _null_; infile "mkdir ""&newdir""" pipe; input; put _infile_; run;` – Tom Aug 30 '22 at 16:12
  • It looks like you may have downgraded a SAS version as well? Your old server shows 9.4M7 while your new server shows 9.4M4. I don't know if that's the cause but it could be a factor. – Stu Sztukowski Aug 30 '22 at 17:04
  • Sorry, my fault. Old SAS version was 9.04.01M4, new version is 9.04.01M7. – Martin F. Aug 31 '22 at 07:49
  • In the actual script I use SAS to perform some database transactions. The Powershell script is needed only to perform some administrative activities before and after calling SAS. In the SAS program I need to execute some Windows commands in subprocesses, e.g. start another SAS session, delete or move some files with Powershell or Xcopy, transfer some files with winscp.com. – Martin F. Aug 31 '22 at 08:55
  • With `%sysexec cmd /c mkdir` the problem still remains. – Martin F. Aug 31 '22 at 09:35

2 Answers2

0
data _null_; infile "mkdir ""&newdir""" pipe; input; put _infile_; run;

works. But the result code of the datastep is always zero (syserr=0, success), even if the windows command could not be successfully executed.

How can I get a useful return value from the command executed in the pipe? I really need this one.

Martin F.
  • 57
  • 6
0

The following code for the powershell script works. Instead of using the call operator (&), I can use the start-process comandlet. The %sysexec command in the child SAS program will then execute correctly under all circumstances, even if it is triggered in a task scheduler action.

Powershell script test_sas.ps1:

$process = (Start-Process -FilePath "$sasrootdirStr\sas.exe" -ArgumentList "`"$pgmdirStr\$pgmnameStr.sas`" -log `"$logfileStr`"" -PassThru -Wait)
Write-Host "Process terminated with return code: " $process.ExitCode
Martin F.
  • 57
  • 6