Solution for running scheduled task with 'run whether user is logged on or not' option as an AAD user?
Recently I've noticed that it is not possible to run a scheduled task as an Azure AD user (AAD) with the enabled option 'run whether user is logged on or not'. No matter if you also enable 'do not store password...' option.
The only way how you can run scheduled task as AAD user is (as far as I know) to choose the option 'run only when user is logged on'.
This has two caveats though:
- the task is run interactively
- the task is obviously run only when the user is logged on ๐
An obvious solution to the first part could be (in the case of running a PowerShell script) to call it using -windowStyle hidden
parameter. But the PowerShell console still flashes for a brief time and moreover, you will lose the previous window focus. Which is super annoying.
The solution to this matter is the old-known use of wscript.exe
inside a VBS script which will then start your original PowerShell script. WScript.exe allows you to completely hide the running window ๐
Therefore instead of calling your ps1 script directly:
Call VBS script with the path to your ps1 script as an argument:
Content of the run_hidden.vbs
script:
set WshShell = WScript.CreateObject("WScript.Shell")
' regex to distinguish ps1 scripts
Set runPs1 = New RegExp
With runPs1
.Pattern = "\.ps1$"
.IgnoreCase = True
.Global = False
End With
' regex to distinguish base64
set runBase64 = New RegExp
With runBase64
.Pattern = "^psbase64:"
.IgnoreCase = True
.Global = False
End With
If Wscript.Arguments.Count < 1 Or Wscript.Arguments.Count > 2 Then
wscript.echo "ERROR, you have to enter one or two argument(s)! First has to be the path to cmd file to run and voluntarily second one as CMDs file argument"
ElseIf Wscript.Arguments.Count = 1 Then
If runPs1.Test( WScript.Arguments(0) ) Then
' it is ps1 script
WshShell.Run "cmd /c powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File" & " " & """" & WScript.Arguments(0) & """", 0, True
ElseIf runBase64.Test( WScript.Arguments(0) ) Then
' It is base64 string
'remove part before : from passed string to get just base64
base64 = WScript.Arguments(0)
base64 = Mid(base64,instr(base64,":")+1)
WshShell.Run "cmd /c powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -EncodedCommand" & " " & """" & base64 & """", 0, True
Else
' It is something else
WshShell.Run """" & WScript.Arguments(0) & """", 0, True
End If
ElseIf Wscript.Arguments.Count = 2 Then
'wscript.echo WScript.Arguments(0)
'wscript.echo WScript.Arguments(1)
If runPs1.Test( WScript.Arguments(0) ) Then
' it is ps1 script
WshShell.Run "cmd /c powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File" & " " & """" & WScript.Arguments(0) & """" & " " & """" & WScript.Arguments(1) & """", 0, True
Else
' It isn't ps1 script
WshShell.Run """" & WScript.Arguments(0) & """" & """" & WScript.Arguments(1) & """", 0, True
End If
End If
Set WshShell = Nothing
Beware that you have to save the VBS script as a UTF8 encoded file!
Subscribe to my newsletter
Read articles from Ondrej Sebela directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ondrej Sebela
Ondrej Sebela
I work as System Administrator for more than 10 years now and I love to make my life easier by automating work & personal stuff via PowerShell (even silly things like food recipes list generation).