2

I've been looking into Group Managed Service Accounts (gmsa) accounts and I've been using them to run scheduled tasks on Server 2012R2 and PowerShell 5.0.10586.117.

After I've been using them a while I've encountered some very weird behavior.

The problem seem to be some kind of timing issue/race condition somewhere when a task is run as a gmsa account. Some core commands might not exists/be loaded while running the script.

Example:

Script called in the task C:\temp\broken-task\test.cmd

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy "ByPass" -File "C:\temp\broken-task\test.ps1" > "C:\temp\broken-task\test.cmd.txt"

The actual script with weird behavior C:\temp\broken-task\test.ps1

<#

.SYNOPSIS
Broken task.

.DESCRIPTION
Broken task.

#>

[CmdletBinding()] Param ()

Process {
    $ErrorActionPreference
    Set-Variable -Name "ErrorActionPreference" -Scope "Script" -Value "Stop"
    Set-Variable -Name "ErrorActionPreference" -Scope "Script" -Value "Stop"
    $ErrorActionPreference
}

I then create and run a task in C:\temp\broken-task\task.ps1

$Action = New-ScheduledTaskAction -Execute "C:\Windows\System32\cmd.exe" -Argument "/C C:\temp\broken-task\test.cmd"
$Principal = New-ScheduledTaskPrincipal -UserID "my-gmsa-user$" -LogonType "Password"
New-ScheduledTask -Action $Action -Principal $Principal | Register-ScheduledTask -TaskPath "\test\" -TaskName "test123" | Out-Null
Start-ScheduledTask -TaskPath "\test\" -TaskName "test123"

After task completion the content of C:\temp\broken-task\test.cmd.txt is the following:

Continue
Set-Variable : The term 'Set-Variable' is not recognized as the name of a cmdle
t, function, script file, or operable program. Check the spelling of the name, 
or if a path was included, verify that the path is correct and try again.
At C:\temp\broken-task\test.ps1:15 char:5
+     Set-Variable -Name "ErrorActionPreference" -Scope "Script" -Value ...
+     ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Set-Variable:String) [], Comman 
   dNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Stop

What is happening above is that Set-Variable doesn't exist on line 2 of the process block in test.ps1, but exist on line 3 (we can see that $ErrorActionPreference has changed).

If I run either the cmd script or the ps1 as myself (a normal user) I will get the expected output with no errors:

Continue
Stop

So what's going on here? The Set-Variable command is in the Microsoft.PowerShell.Utility module. Is the module somehow loaded in between the first and second call? This also happen with other commands like Get-Item "C:\".

What might be even worse is that this does not always happen. I've seen a task work properly in one run and fail in the other.

Also note that I find it hard to create good examples and this does not always yield the same weird results (but the above example has currently failed without exception in my tests).

Is the combination of powershell, gmsa and task scheduler broken somehow?

I can't really trust the system to do as I which when it has this inconsistent behavior.

A workaround might be explicit loading of the Microsoft.PowerShell.Utility module before calling Set-Variable, but I'm not sure if this is due to timing or something else..

henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
Paal Braathen
  • 178
  • 1
  • 11

0 Answers0