VMware Communities
oldskool6868
Contributor
Contributor

Helpful scripts

I was recently trying to shutdown my guests in order to perform maintenance. I wanted to do it without touching each machine. I found two scripts that did exactly what I needed. Here they are.


The first script disconnects removable drives in order to run the suspend/shutdown/resume script

"removableDrives.ps1 Version 1.0a starting"
connect-viserver ($env:computername + "." + $env:userdnsdomain) | out-null
Get-Vm | Where-Object {
  (((Get-CDDrive -VM $_ | Where-Object { (($_.ConnectionState.Connected -eq $True) -or ($_.ConnectionState.StartConnected -eq $True))} ) -ne $Null) `
  -or `
  ((Get-FloppyDrive -VM $_ | Where-Object { (($_.ConnectionState.Connected -eq $True) -or ($_.ConnectionState.StartConnected -eq $True))} ) -ne $Null))
  } | %{
  "VM: " + $_.Name + " (" + $_.PowerState + ")"
  Get-CDDrive -VM $_ | ForEach-Object { "  " + $_.Name + " Connected=" + $_.ConnectionState.Connected + " ConnectAtPowerUp=" + $_.ConnectionState.StartConnected }
  Get-FloppyDrive -VM $_ | ForEach-Object { "  " + $_.Name + " Connected=" + $_.ConnectionState.Connected + " ConnectAtPowerUp=" + $_.ConnectionState.StartConnected }
  }
if ("Y" -eq (Read-Host `
    ("Do you want to disconnect all removable drives, and disable the connect `n" + `
     "  at startup?  If you don't see any VMs everything is OK and you should `n" + `
     "  select N here.  Type Y or N"))) {
  Get-Vm | Where-Object {
    (((Get-CDDrive -VM $_ | Where-Object { (($_.ConnectionState.Connected -eq $True) -or ($_.ConnectionState.StartConnected -eq $True))} ) -ne $Null) `
    -or `
    ((Get-FloppyDrive -VM $_ | Where-Object { (($_.ConnectionState.Connected -eq $True) -or ($_.ConnectionState.StartConnected -eq $True))} ) -ne $Null))
    } | %{
    "VM: " + $_.Name + " (" + $_.PowerState + ")"
    Get-CDDrive -VM $_ | ForEach-Object { Set-CDDRIVE -CD $_ -StartConnected $False -Connected $False -Confirm:$False | %{ "  Changed " + $_.Name} }
    Get-FloppyDrive -VM $_ | ForEach-Object { Set-FloppyDRIVE -Floppy $_ -StartConnected $False -Connected $False -Confirm:$False | %{ "  Changed " + $_.Name} }
  }
}
"removableDrives.ps1 finished."
This script actually performs the suspend/shutdown/resume operation. Simpy change the verbs where necessary.
#Connect-VIServer MyVIServer
# Get All the ESX Hosts
$ESXSRV = Get-VMHost
# For each of the VMs on the ESX hosts
Foreach ($VM in ($ESXSRV | Get-VM)){
    # Shutdown the guest cleanly
    $VM | Suspend-VMGuest -Confirm:$false
}
# Set the amount of time to wait before assuming the remaining powered on guests are stuck
$waittime = 200 #Seconds
$Time = (Get-Date).TimeofDay
do {
    # Wait for the VMs to be Shutdown cleanly
    sleep 1.0
    $timeleft = $waittime - ($Newtime.seconds)
    $numvms = ($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count
    Write "Waiting for suspension of $numvms VMs or until $timeleft seconds"
    $Newtime = (Get-Date).TimeofDay - $Time
    } until ((@($ESXSRV | Get-VM | Where { $_.PowerState -eq "poweredOn" }).Count) -eq 0 -or ($Newtime).Seconds -ge $waittime)
# Shutdown the ESX Hosts
#'$ESXSRV | Foreach {Get-View $_.ID} | Foreach {$_.ShutdownHost_Task($TRUE)}
Write-Host "Suspension Complete"
These were very useful to me.
Reply
0 Kudos
0 Replies