Windows 10: Scheduled tasks with workstation lock/unlock not being triggered
Follow the below steps to troubleshoot and resolve your problem
Task Scheduler Properties. . .
From Windows Task Scheduler
on the job properties (see bottom most screen shots) in the. . .
1. General tab, ensure that the below options are select/checked or unchecked just as shown in Print Screen A
- Uncheck
Run only when user is logged on
- Check
Run whether user is logged on or not
- Check
Run with the highest privileges
- Uncheck
2. Conditions tab, ensure that the below options are select, checked, or unchecked just as shown in Print Screen B
- Check
Wake the computer to run this task
- Check
3. Actions tab, click Edit, and enure that the
Start in (optional)
is set just as shown in the below example (DO NOT put double quote marks around it) for the full path pointing where the batch script is located WITHOUT a final backslash "\
" Print Screen C
SECURITY CONSIDERATIONS
Once you press OK (2. above) it should prompt you for the credential to run this as, and that credential is what will need access to
EXECUTE
the batch file where it exist, and it will also need access to do whatever the batch file is running that you scripted out.It may be best to setup a static service/proxy user account for this process and then use its credentials to run the process. You'd need to ensure its password is strong and it set to never expire—and it needs access to
EXECUTE
the batch and run whatever the batch scripted process is running and any commands and resources, ect. it utilizes as well.It seems the option
Run whether user is logged on or not
you MUST check the optionRun with highest privileges
for it to actually run as expected from the Task Scheduler.
Error Checking
If there is an issue with the actual batch script but the Windows Task Scheduler actually does execute it to run it but the batch script logic errors out, etc. for whatever reason, the Task Scheduler may not see this failure at this level. From its perspective (by default most of the time), it’s executing the batch file so as long as it can execute it and has access to do so, its job is done successfully.
Add error checking or logging to the batch script logic to catch (or troubleshoot) issues at this level including ensuring that the security context which the batch scheduler executes it as has appropriate access to commands, resources, etc. which the batch script runs as.
Group Policy Considerations
CHECK GROUP POLICY AND LOG ON AS A BATCH JOB PERMISSIONS
Answer: On Windows, this privilege is granted through the Local or Domain Security Policy. To do this using the Local Security Policy, follow these steps.
- In the Control Panel, open Administrative Tools, then Local Security Policy.
- Beneath Security Settings, open Local Policies and highlight User Rights Assignment.
- Locate Log on as a batch job. Open the properties and add any users that need this right.
- When finished, save your changes and close the Local Security Settings window.
Your changes should take effect immediately. To make changes to the Domain Security Policy, on a domain controller, use the Domain Security Policy utility in the Control Panel
Batch Script Logic with Mapped Drives or Full UNC Path, and issues. . .
If your script is referencing a mapped network drive but you want it to Run whether the user is logged on or not
, then under this context, the drive mapping may not actually be there for the batch process to do what’s expected.
If possible, use UNC
paths in your batch script logic rather than a mapped drive letter to avoid issues. Otherwise, you may need to use PUSHD \\ServerName\ShareName
at the beginning of the batch process and then use POPD
at the end of the batch process. You could map the drive with NET USE X: \\ServerName\ShareName
at the beginning of the batch process and then disconnect the drive with NET USE X: /DELETE
at the end of the batch process.
- NET USE
- PUSHD
- POPD
Print Screens
Print Screen A
Print Screen B
Print Screen C
WinSCP Batch Script Examples
Below are two very basic and dumbed-down examples of an FTP script to upload to and an FTP script to download from an FTP server using WinSCP.com
. Be sure the SET winscplogin=
variable is set to the name of the FTP connection you have defined from within the WinSCP GUI.
This way builds the script dynamically and you build the FTP commands from within the batch script but you can also just simply point it to a static WinSCP script with the FTP commands in them otherwise too which is easy to setup.
Upload to an FTP Server
@ECHO ON
SET logfile=C:\folder\path\log.log
::SET WinSCP variables, etc.
SET prgwinscp="C:\Program Files\WinSCP3\WinSCP.com"
SET winscplogin="ABC Company"
SET winscpfile=C:\folder\path\ABCompany_FTP_OUT_WinSCP.txt
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"
:ftpout
ECHO. >> "%logfile%"
ECHO *******************FTP OUT******************* >> "%logfile%"
ECHO Delivering file(s) to ABC Company FTP server >> "%logfile%"
SET ftpdir="ToABC"
ECHO option batch on >> %winscpfile%
ECHO option confirm off >> %winscpfile%
ECHO option transfer binary >> %winscpfile%
ECHO open %winscplogin% >> %winscpfile%
ECHO cd %ftpdir% >> %winscpfile%
ECHO put "C:\Folder\Path\*.*" >> %winscpfile%
ECHO dir >> %winscpfile%
ECHO close >> %winscpfile%
ECHO exit >> %winscpfile%
ECHO %winscpfile% >> "%logfile%"
TYPE %winscpfile% >> "%logfile%"
ECHO - - - - - - - - - - - - - - - - - - - - - - >> "%logfile%"
%prgwinscp% /script=%winscpfile% >> "%logfile%"
ECHO - - - - - - - - - - - - - - - - - - - - - - >> "%logfile%"
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"
ECHO Transmission complete >> "%logfile%"
Download from an FTP Server
@ECHO ON
SET logfile=C:\folder\path\log.log
::SET WinSCP variables, etc.
SET prgwinscp="C:\Program Files\WinSCP3\WinSCP.com"
SET winscplogin="ABC Company"
SET winscpfile=C:\folder\path\ABCompany_FTP_IN_WinSCP.txt
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"
:ftpin
ECHO. >> %logfile%
ECHO *******************FTP IN******************* >> %logfile%
ECHO Retrieving files from ABC Company server >> %logfile%
SET ftpdir="FromABC"
ECHO option batch on >> %winscpfile%
ECHO option confirm off >> %winscpfile%
ECHO option transfer binary >> %winscpfile%
ECHO open %winscplogin% >> %winscpfile%
ECHO cd %ftpdir% >> %winscpfile%
ECHO ls >> %winscpfile%
ECHO get "*.*" "C:\Folder\path\" >> %winscpfile%
ECHO close >> %winscpfile%
ECHO exit >> %winscpfile%
ECHO %winscpfile% >> %logfile%
TYPE %winscpfile% >> %logfile%
ECHO ------------------------------------------- >> %logfile%
%prgwinscp% /script=%winscpfile% >> %logfile%
ECHO ------------------------------------------- >> %logfile%
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"
ECHO FTP Downloading Complete >> %logfile%
ECHO Transmission complete >> %logfile%
Custom Example Scripts
Be sure to use both the options of Run whether user is logged on or not
and Run with the highest privileges
when you schedule the batch script. Once you apply these changes you will need to put in credentials to run the task as explicitly. Be sure to use an account that has execute access to the C:\Program Files (x86)\WinSCP\WinSCP.com
file and that also meets the other general prerequisites as listed above.
If you still have issues and want to confirm it's not OS security related, create a new local account on the machine and give it a strong password, set it to never expire, and to have the run as batch permissions. You can also make it a local admin and test just to be thorough to see if giving the account local admin access on the machine makes any difference.
This would mean you have two files: a batch script and a WinSCP. The batch script will pass the WinSCP script to WinSCP.com and you can just execute it to run the process. Be sure this script works as the same user while logged on by simply executing it to test and then test with that same account while logged onto the machine session with the Run only when user is logged on
option to confirm it works from Task Scheduler as well before you set it to run whether logged on or not, etc.
The Task Scheduler Actions
tab will only use the Program/Script:
field with all other fields left blank but the Program/Script:
field will have a value of C:\folder\path\yourbatchscript.cmd
.
Batch Script
@ECHO ON
SET prgwinscp="C:\Program Files (x86)\WinSCP\WinSCP.com"
%prgwinscp% /script=lock-arch.winscp
EXIT
WinSCP Script
open sftp://[email protected]:2222/ -hostkey="ssh-rsa 2048
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
call cinnamon-screensaver-command -d
close
exit
I solved this by bypassing the "On Workstation Lock/Unlock" trigger types, and setting triggers to look at the windows event log directly.
It's not ideal, but should be sustainable. Definitely still curious about why the triggers provided by Task Scheduler aren't working though.
Configure Lock/Unlock Events
By default, the lock/unlock events are not audited to the event log, you will need to enable logging of these events. You can do so from the group policy editor:
run -> gpedit.msc
and configuring the following category:
Computer Configuration ->
Windows Settings ->
Security Settings ->
Advanced Audit Policy Configuration ->
System Audit Policies - Local Group Policy Object ->
Logon/Logoff ->
Audit Other Login/Logoff Events
(In the Explain tab it says "... allows you to audit ... Locking and unlocking a workstation".)
Credit: https://stackoverflow.com/a/15904838/1216896
Create Triggers
From there, you can set up triggers to the 4800 (lock) and 4801 (unlock) events like so:
The Win10 task scheduler has a lot of bugs -- especially in the GUI. See: https://www.ctrl.blog/entry/idle-task-scheduler-powershell
You might have some luck re-compiling the interface:
mofcomp c:\Windows\System32\wbem\SchedProv.mof
You may also want to create the task via COM interface in PowerShell. I prefer using a string variable containing the XML definition. You can export the XML of the GUI-created task and clean it up/correct it. Then:
$TaskService = new-object -ComObject('Schedule.Service')
$TaskService.connect()
$Task = $TaskService.NewTask($null)
$task.XmlText = $XMLstring
$null = $Global:TaskFolder.RegisterTaskDefinition('Lock Arch Workstation', $Task, 6, $null, $null, 3)
Good luck!