Introduction
I saw a tweet from well known Irish MVP Rory Monaghan here where he was explaining how he automates shutting down his home lab to save on electricity costs. I thought to myself that’s a great idea !
The price of electricity right now is insane in Europe and very high in Southern Sweden (where I live). So any saving will help, especially in the coming Winter when prices will surely rise to ridiculous levels. If you look at how quickly they rose last year (from July 2021 forward).
These prices have already been beaten this month and it’s only August! It’s easy to see that 2022 will be even worse.
Graph source.
Rory’s method was pretty ingenious and used some 3rd party software but I thought I’d try doing something similar with Powershell and scheduled tasks.
part 1. Automating graceful shutdown <- you are here
part 2. Starting the previously running vms after power on
part 3. Using WOL to wake the lab on demand
Creating the scheduled task
I decided to create a simple scheduled task which would run nightly at 11:30pm and gracefully save any running virtual machine (like a hibernate) before pausing 30 seconds and issuing a shutdown command to the hyperv host.
Here’s the scheduled task, make sure to enabled ‘Run with highest privileges‘ and run as NT AUTHORITY\SYSTEM
runs nightly @ 11:30pm
Actions, start a program
looks like this
and that’s it,
The Powershell script
here’s the Powershell script (very simple, no logging, will add that later…)
# use this to run as a scheduled task (highest permissions) to 'save' any running hyper-v virtual machine # once it's done with saving them, i'll pause for 30 seconds before issuing a shutdown command (which waits a further 90 seconds incase you want to abort the shutdown) # Niall Brady 2022/08/08 # # version: 0.1 2022/08/08 script created # version: 0.2 2022/08/09 added ability to write the names of the running virtual machines to a text file so that we can resume them when the computer starts again $GroupMembers = $null $arrayofrunningvms = get-vm | where state -eq 'running' #write-host $arrayofrunningvms ForEach-Object { $GroupMembers += ($arrayofrunningvms | select -expandproperty name) } #$GroupMembers.GetType() # write the text file If($GroupMembers) { $GroupMembers | Out-File -force C:\RunningVirtualMachines.txt } # now 'save' all those running vms get-vm | where state -eq 'running' | stop-vm –Save sleep 30 shutdown -s -t 90
GIF showing it in action
and here you see it in action…
Related reading
Check out this great post by Jeff Hicks which gives you lots of ways of saving or powering on your hyper-v virtual machines with Powershell
https://www.altaro.com/hyper-v/control-hyper-v-with-powershell/
cheers !
niall