# onShutdown.ps1 # # for Windows 10 # - sends an MQTT message on Shutdown and a different one on Restart # - intended to switch off a Tasmota plug, delayed, after shutdown, but NOT on restart # # Prerequisites: # - download Mosquitto Windows x64 installer # - extract and copy mosquitto_pub.exe, mosquitto.dll, libssl-1_1-x64.dll and libcrypto-1_1-x64.dll to # c:\Tools\mosquitto (or anywhere and change $mosquittoPubPath accordingly) # - Windows Update PowerShell Module: # http://woshub.com/pswindowsupdate-module/ # (as Admin): Install-Module -Name PSWindowsUpdate # # This script checks if there is a Event 1074 (source: User32) in the System Event Log, that is # less than 15 seconds old. # If so, it checks the content of this event, which contains the info if we are about to # "power off" or "restart". # # The script must be set as shutdown script via Windows Group Policy (local GPO) # Setup: Start -> Run -> gpedit.msc # -> Computer Configuration -> Windows Settings -> Scripts (Startup/Shutdown) -> Shutdown # -> there, go to tab "PowerShell Scripts" and simply browse for this script. # Group Policy service seems to handle the PS Execution-Policy, # so that it does not have to be set to unrestricted system-wide. # I saved the script to C:\scripts\onShutdown.ps1 # # Starting it via Task Scheduler on Event 1074 unfortunately does not work, as the script # is getting killed before it actually has done anything most times. # Via Group Policy, the shutdown will be delayed until the script has finished its work. $logFile = "C:\LOG\onShutdown_PS.log" $mosquittoPubPath = "c:\Tools\mosquitto\mosquitto_pub.exe" $mqttHost = "mqtt.lan" $mqttUser = "script" $mqttPwd = "rlAzqusqfbAy" # Topic to send status info to (SHUTDOWN or RESTART) $mqttStatTopic = "MediaPC-SZ/ShutdownEvent" # Topic/Payload on Shutdown (i.E. send an Event to a Tasmota device) $mqttTopicOnShutdown = "cmnd/T5SZ-Media-Pwr/event" $mqttPayloadOnShutdown = "delayedOff" # Topic/Payload on Restart (i.E. send an Event to a Tasmota device) #$mqttTopicOnRestart = "" #$mqttPayloadOnRestart = "" ########### $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition $mosquittoPubUserPassword = "" if($mqttUser -and $mqttPwd -and $mqttUser -ne "" -and $mqttPwd -ne "") { $mosquittoPubUserPassword = "-u $mqttUser -P $mqttPwd " } $logDate = "{0:yyyy-MM-dd HH:mm:ss}" -f (Get-Date) if($logFile) { Write-Output $logDate >> $logFile } $WURebootRequired = Get-WURebootStatus.RebootRequired Get-WinEvent -FilterHashtable @{logname='System'; id=1074} -MaxEvents 1 | ForEach-Object { $ts_event = [datetime]$_.TimeCreated $ts_delta = (New-TimeSpan -Start $ts_event).TotalSeconds $ts_str = $ts_delta.ToString("#") $command = $_.Properties[4].Value if($logFile) { Write-Output " last shutdown-event was '$command', $ts_str s ago" >> $logFile if($WURebootRequired) { Write-Output " Windows Update reboot is required. As in this case the update will install on shutdown, Powerdown-Command to Tasmota is omitted this time." >> $logFile } } if($ts_delta -lt 15) { if($logFile) { Write-Output " ==> OK, publish MQTT messages." >> $logFile } if($command -eq "power off") { $cmdLine = "$mosquittoPubPath -h $mqttHost $mosquittoPubUserPassword-t $mqttStatTopic -m SHUTDOWN" Invoke-Expression $cmdLine if(-not $WURebootRequired -and $mqttTopicOnShutdown -and $mqttTopicOnShutdown -ne "") { $cmdLine = "$mosquittoPubPath -h $mqttHost $mosquittoPubUserPassword-t $mqttTopicOnShutdown -m $mqttPayloadOnShutdown" Invoke-Expression $cmdLine } } elseif($command -eq "restart") { $cmdLine = "$mosquittoPubPath -h $mqttHost $mosquittoPubUserPassword-t $mqttStatTopic -m RESTART" Invoke-Expression $cmdLine if($mqttTopicOnRestart -and $mqttTopicOnRestart -ne "") { $cmdLine = "$mosquittoPubPath -h $mqttHost $mosquittoPubUserPassword-t $mqttTopicOnRestart -m $mqttPayloadOnRestart" Invoke-Expression $cmdLine } } } else { if($logFile) { Write-Output " ==> too old. Nothing to do." >> $logFile } } }