VMware Cloud Community
esxi1979
Expert
Expert
Jump to solution

VM shutdown

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


1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

11 Replies
esxi1979
Expert
Expert
Jump to solution

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

Reply
0 Kudos
esxi1979
Expert
Expert
Jump to solution

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 ..

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

esxi1979
Expert
Expert
Jump to solution

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





Reply
0 Kudos
esxi1979
Expert
Expert
Jump to solution

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
esxi1979
Expert
Expert
Jump to solution

Thanks .. not very easy to understand the logic Smiley Happy

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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.

  • we have a number of VMs that need to be stopped (let's say N)
  • we want to handle these VMs in batches for X VMs at a time
  • that means we have to have N/X iterations
  • this is ok, if N is exactly dividable by by X (i.e. 100 VMs in groups of 25 will be 4 iterations)
  • but if N is not exactly dividable by X (i.e 100 VM in groups of 33), then we need to add an iteration for the fractional part of the quotient
  • and that is what the Ceiling function does, it transforms for example 3.1 into 4, but keeps 4 as 4

Hope that makes it a bit clearer :smileycool:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
esxi1979
Expert
Expert
Jump to solution

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Thanks Heart

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

esxi1979
Expert
Expert
Jump to solution

Thanks my point was on IO load on my Tier II storage due to 100s of VM shutting down at same time.

Reply
0 Kudos