I am attempting to use a script that shuts down my Hyper-V VMs, copies their VHDs to a target share, then boots them back up. I found the script on spiceworks just a couple days ago. I always receive errors that the system name intended for shutdown is a null value.
General info:
- I have been running powershell as an admin.
- I set my ExecutionPolicy to "RemoteSigned" so that local powershell files will execute.
- I appear to be running PowerShell v 2.0
- I am running HyperV in Server 2008 R2
- I am executing this script directly on the VM host
Below is the script and an explanation of where I encounter the error and exactly what that error is:
$waitstart = 200
$waitshutdown = 120
if ($args[1] -match "0") {
$inputfile=get-content $args[0]
foreach ($guest in $inputfile) {
write-host "Starting $guest"
$vm = gwmi -namespace root\virtualization -query "select * from msvm_computersystem where elementname='$guest'"
$result = $vm.requeststatechange(2)
if ($result.returnvalue -match "0") {
start-sleep -s $waitstart
write-host ""
write-host "$guest is started" -foregroundcolor green
write-host ""
}
else {
write-host ""
write-host "unable to start $guest" -foregroundcolor red
write-host ""
}}}
if ($args[1] -match "1") {
$inputfile=get-content $args[0]
foreach ($guest in $inputfile) {
write-host "shutting down $guest"
$vm = gwmi -namespace root\virtualization -query "select * from msvm_computersystem where elementname='$guest'"
$vmname = $vm.name
$vmshut = gwmi -namespace root\virtualization -query "SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='$vmname'"
$result = $vmshut.InitiateShutdown("$true","no comment")
if ($result.returnvalue -match "0") {
start-sleep -s $waitshutdown
write-host ""
write-host "no error while shutting down $guest"
write-host "shutdown of $guest completed" -foregroundcolor green
write-host ""}
else {
write-host ""
write-host "unable to shutdown $guest" -foregroundcolor red
write-host ""
}}}
else {
write-host "USAGE: to shutdown VMs," -nonewline; write-host ".\managehyperV.ps1 c:\hosts.txt 1" -foregroundcolor yellow
write-host "USAGE: to start VMs," -nonewline; write-host ".\managehyperV.ps1 c:\hosts.txt 0" -foregroundcolor yellow
}
The script takes in the argument "1" or "0" to determine whether the VMs in the "guests" text list should be shut down or started.
Running Powershell as an admin I can successfully run the following query:
$vm = gwmi -namespace root\virtualization -query "select * from msvm_computersystem where elementname='$guest'"
This returns a string of some kind that represents the system name of the VM.
However, the following query always returns a null value:
$vmshut = gwmi -namespace root\virtualization -query "SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='$vmname'"
It seems as though the 'Msvm_ShutdownComponent' class doesn't exist on my system... when I execute the following line:
$result = $vmshut.InitiateShutdown("$true","no comment")
I always receive an error that states "You cannot call a method on a null-valued expression". I have spent about a day and a half trying to find the mistake I am making that causes this, but I can't narrow it down.
I appear to be running PowerShell v 1.0
- I doubt that, you are probably using at least 2.0. What do you see on$PSVersionTable
.