Morning, (for those in the US )
Question on PowerState. I am trying to shutdown and delete a number of VMs. Script is simple, but I want to have a catch if the VM is running, turn off the power. I cant get it to work. I have checked a number of sites, pretty sure my code is correct. I went ahead and created a simple "Is the server up" script and that is in fact whats failing. My shutdown commands and delete commands are working fine on their own, only when paired with a PowerState does it fail.
Here is the simple script:
Foreach ($vm in $list)
{
IF ($vm.PowerState -eq "PoweredOn")
{
Write-Output $vm "IS ON"
}
ELSE
{
Write-Output $vm "IS OFF"
}
}
The simple script fails every time. All servers return "IS OFF". The servers I am deleting are Linux boxes.. does VMTools have to be installed for PowerState to return a correct value??
Thanks,
Boston Tech Guy
The problem in your first version of the script was that you were looping through the names of the VMs.
So that $vm variable had a [string] value, the name of the VM.
And a [string] doesn't have a PowerState property, so that explains why all the VMs went through to the Else part of you If statement.
In the 2nd script, you $vm variable actually holds a VirtualMachine object, since you did a Get-VM.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
What does this return ?
Get-VM | Select Name,PowerState
Are the PowerState values correct ?
Stupid question, but how did you populate the $list variable ?
$list = Get-VM
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Get the list from GET-Content
$list = (Get-Content "C:\scripts\lists.txt")
Lists.txt just has server names
Server1
Server2
Server3
For shutting down, works fine. For Deleting, again works fine.
As for the Get-VM script... interesting result (edit for security)
Here is the full script I wrote to get the value
Connect-VIServer "myvcenter"
$VM = (Get-VM -Name "myvm" | Select Name,Powerstate)
Write-Output $VM
Disconnect-VIServer -Confirm:$false
RESULT:
Name | Port User | |
---- | ---- ---- | |
myvcenter | ### Domain\Boston Tech Guy |
Name | : myvm |
PowerState : PoweredOn
So that script gave the correct result....
Also my original script that is failing, its on both Windows and Linux VMs. I just tested it just to be sure.
Hang on a second.. now all my servers are coming back all POWERSTATE = ON. I just ran through a number of servers that are off and on.. they all came back ON..
Now I am totally confused of what is going on.
Testing Script:
Connect-VIServer "myvc"
$list = (Get-Content "C:\Scripts\lists.txt")
Foreach ($vm in $lists)
{
$Power = (Get-VM -Name $vm | Select Powerstate)
IF ($Power = "PoweredOn")
{
Write-Output $vm "IS ON"
}
ELSE
{
Write-Output $vm "IS OFF"
}
}
Disconnect-VIServer -Confirm:$false
Further testing, I kept it simple. Went back to the GET PowerState value script on a server that is off. I got PoweredOFF as a result. GOOD! Seems when I place the PowerState Scripts into an IF Statement, the whole things stops working
The problem in your first version of the script was that you were looping through the names of the VMs.
So that $vm variable had a [string] value, the name of the VM.
And a [string] doesn't have a PowerState property, so that explains why all the VMs went through to the Else part of you If statement.
In the 2nd script, you $vm variable actually holds a VirtualMachine object, since you did a Get-VM.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ok.. will be completely honest, I am not following (still learning though). You saying my logic and variable placement is the problem..
Soooooo..
If I do this:
Connect-VIServer "myvcenter"
$vm = "vm that is on"
$Power = (Get-VM -Name $vm | Select Name,Powerstate)
IF ($Power.PowerState -eq "PoweredOn")
{
Stop-VM -VM $vm -Confirm:$false
}
ELSE
{
Write-Output $vm "IS OFF"
}
Disconnect-VIServer -Confirm:$false
It should work.... TESTING... AND IT DOES!
Now if I place it into a loop:
Connect-VIServer "myvcenter"
$list = (Get-Content "C:\Scripts\list.txt")
Foreach ($vm in $list)
{
$Power = (Get-VM -Name $vm | Select Name,Powerstate)
IF ($Power.PowerState -eq "PoweredOn")
{
Stop-VM -VM $vm -Confirm:$false
}
ELSE
{
Write-Output $vm "IS OFF"
}
}
Disconnect-VIServer -Confirm:$false
Test with servers all on - SUCCESS
Test with servers all off - SUCCESS
Test with servers some on/some off - SUCCESS
OK!
LucD thank you for the help.
Now to place it into my larger Deletion Script.
Thanks!
OH I GET IT!
When you said:
The problem in your first version of the script was that you were looping through the names of the VMs.So that $vm variable had a [string] value, the name of the VM.
And a [string] doesn't have a PowerState property, so that explains why all the VMs went through to the Else part of you If statement.
You mean that my first script $VM = Server1, Server1 didnt mean anything but a word.. $VM is a word at that point, not a VM Server!! $vm.powerstate wouldnt mean anything at that time in the script.
Once I assigned value of GET-VM then Powerstate was usable.
Thanks!