I am looking for a vm shutdown script...
Script will work well but i have some Questions Or Clarifications that are needed
$csv = import-csv C:\xxx.csv
Foreach ($line in $csv)
{
Write-Host “====================================================================”
Write-Host “Processing $line ”
$vminfo = get-view -Id ($line.vm).ID
Write-Host “Checking VMware Tools on $line ….”
# If we have VMware tools installed
if ($vminfo.config.Tools.ToolsVersion -eq 0)
{
Write-Host “($line.vm) doesn’t have vmware tools installed, hard power this one”
# Hard Power Off
Stop-VM ($line.vm) -confirm:$false
}
else
{
write-host “I will attempt to shutdown $vm”
# Power off gracefully
Get-VM ($line.vm) | Shutdown-VMGuest -Confirm:$false | Out-Null
}
}
1. My below code what i missing/or doing wrong ?
$vminfo = get-view -Id ($line.vm).ID
Write-Host “Checking VMware Tools on $line ….”
2. Tools has many combination
tools installed - but not running
tools not install
Are both will need stop-vm ?
3.
I got a simple code, will it cover the stuff of tools ?
$vm = Get-VM
$vm | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm:$false
$vm | where {$_.Guest.State -eq "NotRunning"} | Stop-VM -Confirm:$false
4. I want to shutdown 50 vms at a time, how the
Your script seems to be ok.
When the VMware Tools are installed you can do a gracefull stop (Stop-VMGuest) from within the guest OS, hence the requirement for the VMware Tools.
The next option is to stop the VM (Stop-VM), with what would be the Power button on a physical machine.
No graceful OS shutdown, and a potential risk on OS corruption.
With the RunAsync switch the cmdlet will return immediately, it will not wait till the underlying vSphere method is completed.
The method will continue, but in the background.
You will have to check these background tasks (Get-Task), to monitor proper completion.
To handle the VMs in batches of 25 and wait 60 seconds between batches, you could do something like this
$vms = Get-VM
$step = 25
$start = 0
for($loop=0;$loop -le ([math]::Ceiling($vms.Count/$step)-1);$loop++){
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm:$false -RunAsync
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "NotRunning"} | Stop-VM -Confirm:$false -RunAsync
sleep 60
$start += $step
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
4. Pt cont
$allLines = @() # Line added
Get-VM -Name (Get-Content -Path "C:\vms.txt") |`
ForEach-Object {
If ($_.Powerstate -eq "poweredOff") {
echo $_ is powered off
}
Else {
Shutdown-VMGuest $_ -Confirm:$false -RunAsync
}
}
4a. what will -RunAsync do here , all at same time ? or one vm down & then next ?
4b. How will i tell script wait 60 sec after bunch of say 25 vm all together shitdown start ?
Thanks
I remember 1 more combination
tools installed but at this point are not runing tho box is up ...
so looks like it boils down to tools running or not ..
Your script seems to be ok.
When the VMware Tools are installed you can do a gracefull stop (Stop-VMGuest) from within the guest OS, hence the requirement for the VMware Tools.
The next option is to stop the VM (Stop-VM), with what would be the Power button on a physical machine.
No graceful OS shutdown, and a potential risk on OS corruption.
With the RunAsync switch the cmdlet will return immediately, it will not wait till the underlying vSphere method is completed.
The method will continue, but in the background.
You will have to check these background tasks (Get-Task), to monitor proper completion.
To handle the VMs in batches of 25 and wait 60 seconds between batches, you could do something like this
$vms = Get-VM
$step = 25
$start = 0
for($loop=0;$loop -le ([math]::Ceiling($vms.Count/$step)-1);$loop++){
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm:$false -RunAsync
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "NotRunning"} | Stop-VM -Confirm:$false -RunAsync
sleep 60
$start += $step
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks.
1. I need check on power status here, if its already power off why bother.
2. I think i should do run -RunAsync in
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm: $false
to
$vms[$start..($start+$step-1)] | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm:$false -RunAsync
As i want to do batch of 25 nodes.
3. What is the this part, [int]($vms.Count/$step+1
if vms.count is 100 then, are we doingin below
$step = 25
...
for($loop=0;$loop -le ([int]($vms.Count/$step+1));$loop++){
..
int (100/25+1 ) which would be 5
This part is not clear
I was working on part of the diff code
Foreach ($line in $csv)
{
$vminfo = get-vm $($line.vm) | % { get-view $_.id } | select @{ Name="ToolsRunningStatus"; Expression={$_.Guest.ToolsRunningStatus}}
Write-Host “On box $($line.vm) the status of the tools is $vminfo ”
}
the output is
On box xxxx the status of the tools is @{ToolsRunningStatus=guestToolsNotRunning}
===
I need the output as
On box xxxx the status of the tools is guestToolsNotRunning
==
But get-vm $($line.vm) | % { get-view $_.id } | select @{ Name="ToolsRunningStatus"; Expression={$_.Guest.ToolsRunningStatus}} gives correct output, how to fix the o/p ?
Thanks
Ok, I changed the determination of the number of loops.
Now it uses [Math]::Ceiling, that should be better.
To get the value instead of an object with Select-Object, use the ExpandProperty parameter
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks .. not very easy to understand the logic
Again, LucD if you can tell me what i am missing in below...
=========
Foreach ($line in $csv)
{
$vminfo = get-vm $($line.vm) | % { get-view $_.id } | select @{ Name="ToolsRunningStatus"; Expression={$_.Guest.ToolsRunningStatus}}
Write-Host “On box $($line.vm) the status of the tools is $vminfo ”
}
the output is
On box xxxx the status of the tools is @{ToolsRunningStatus=guestToolsNotRunning}
====
I need output as
On box xxxx the status of the tools is guestToolsNotRunning
Thanks
Try with this line
Write-Host “On box $($line.vm) the status of the tools is $($vminfo.ToolsRunningStatus) ”
The logic is not that hard, but perhaps hard to read from the code.
Hope that makes it a bit clearer :smileycool:
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You are Gem, Words are hard to find to explain your passion for powercli
Not a single post of mine you have not responded.
BTW in my case i am making my life easy by reading the input from xls. Its entire shutdown of vms so this is something i can not actually test
Also there are more complications like u need to keep vm which are down before activity start .. so tracking in xls its easy
I also do not have inputs how the storage will act when i do even 50 vm in 1 slot .. i have have to tune it to lower number & so on ..
Again thanks
Thanks
Note that vSphere also has a queuing mechanism build in, it will schedule only a set of background jobs at the time.
And there are some limits, they are documented in the Configuration Maximums documents.
See KB1003497 for the document pointers.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks my point was on IO load on my Tier II storage due to 100s of VM shutting down at same time.