3

The situation

In our organisation I made a GPO that creates a scheduled task. This task triggers at logon of two user accounts.

It executes a powershell script that changes the DNS servers for the network connection. (To block some websites for these users, using dnsmasq. I know this is not a bulletproof solution, but its good enough.)

The action for the scheduled task is this command:

C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe

And these are the parameters:

-ExecutionPolicy Bypass –NoProfile –Command "& {C:\ProgramData\ORGNAME\scripts\SetDNS.ps1}" > C:\ProgramData\ORGNAME\scripts\SetDNS.log

As you can see, the output gets sent to a log file.

This is the content of the script:

$wmi = get-wmiobject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'"
foreach($adapter in $wmi)
{
    if($adapter.description -NotLike "*VMware*")
    {
        $adapter.SetDNSServerSearchOrder("XXX.XXX.XXX.XXX")
    }
}

invoke-expression -command "c:\windows\system32\ipconfig /flushdns"

The problem

The problem is that this works fine, approximately 9 out of 10 times. When it doesn't work, the task scheduler still reports exit code 0, but it seems the script does not even begin to execute because, nothing happens and the log file is not created.

Some extra info

  • The task runs under the SYSTEM account
  • It runs with highest privilleges
  • When the task is ran on demand it works fine
  • All computers run Windows 7 enterprise (x64)

Some things i've tried

  • I thought maybe the task scheduler was triggering the script too fast and some things might not yet have initialized so i tried setting a 30s delay.

  • Re-running the task every 5 minutes for 15 minutes.

  • Restarting the task when it fails, this obviously doesn't work, since powershell.exe seems to return error code 0.

2
  • What does the & do in your command-line? I've not used that when running Powershell tasks.
    – uSlackr
    Jun 7, 2016 at 13:38
  • @uSlackr That's the call operator.
    – jscott
    Jun 8, 2016 at 10:57

2 Answers 2

8

I think the exit code task scheduler is reporting is for running powershell.exe not your script.

Try changing it to this:

-ExecutionPolicy Bypass –NoProfile –Command "& {C:\ProgramData\ORGNAME\scripts\SetDNS.ps1; exit $LastExitCode}" > C:\ProgramData\ORGNAME\scripts\SetDNS.log

$LastExitCode has the exit code of the your script, you have to bubble it up one level to the task scheduler.

It would also be a good idea to add some error handling to your script and use Exit statements to set the actual exit codes.

2
  • This seems like a logical explenation. I've added error handling and $LastExitCode to the scheduled task action. It works on a test machine. At least the task now finishes with a proper exit code when something went wrong and "retry on fail" will work. We are doing a larger test at the moment. Thanks a lot so far! Jun 9, 2016 at 13:06
  • I had to use this technique to get the result of the Exit statements in my PowerShell script. It's as though the -ExecutionPolicy Cmdlet eats the results otherwise.
    – Mike
    Apr 29, 2021 at 13:19
1

Remove the -Command from your script parameters and instead use -File . Command is meant to be used when you are entering powershell commands but you have a script file instead.

Details here

2
  • This saved me today. When i use -command Errors thrown in a imported Exchange session were not thrown, only when started via Scheduler.
    – fbehrens
    Feb 23, 2017 at 10:46
  • 3
    The reason that he suggested using -Command is because he needs a second command to return the exit code returned by the script file. Since -File will not result in the exit code being propagated, it doesn't satisfy OP's scenario.
    – bwerks
    Apr 20, 2017 at 19:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .