This is a reliable way to run code at shutdown on Windows.
A service that accepts SERVICE_CONTROL_PRESHUTDOWN is allowed to delay the system shutdown up to 125 seconds (provided it asks for it).
The 125 second limit can be extended by editing HKLM:\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout.
See Service Control Handler Function for more details.
This is an alternative to these unreliable methods of running code at shutdown:
- Group Policy Shutdown can be terminated early, doesn't fire when fastboot is enabled (default in Win10+) and isn't supported on Server Core 1909
Register-WmiEvent -Class Win32_ComputerShutdownEventcan be terminated early, doesn't fire when fastboot is enabled (default in Win10+) and fails on Server Core 1909- Task event trigger on event id 1074 (
<Select Path="System">*[System[Provider[@Name='User32'] and EventID=1074]]</Select>) depends on EventLog and TaskScheduler and doesn't fire reliably (or at all on Server Core 1909)
The code is basically this reference service implementation with minor changes.
- Download OnShutdown to some location in SCM's PATH (ie
%systemroot%\System32) - PS>
New-Service OnShutdown -bin 'OnShutdown 30000 "powershell -noninteractive -c \"...\""' -start Automatic - ..or cmd>
sc create OnShutdown binpath= "OnShutdown 30000 \"powershell -noninteractive -c \\\"...\\\"\"" start= auto(note: sc escaping can be tricky) - The first parameter is the dwWaitHint in milliseconds
- The second parameter is the command to pass through to CreateProcess