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_ComputerShutdownEvent
can 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