PowerCLI

 View Only
  • 1.  Shutting down VMs with and without VMware tools installed

    Posted Nov 30, 2012 06:30 PM

    So after a major power failure where I work occured where the UPS's batteries only ran about 10 minutes and the backup generator didn't kick in, I've been put in charge of writing a script that kicks off to shut down VMs and servers within a given cluster. Now as I'm fairly new to the enviroment here so I'm not sure if all vms have the tools installed. I want to cover all the bases and cover vms that don't have tools installed. What my script currently does is it initiates the guest shutdown on all vms and checks every 10 seconds up to 120 seconds for the VMs to go offline If after 120 seconds there are still vms online it issues a power off command on all servers that haven't shut down. Now this will catch all the VMs but I don't want the machine have to wait the full 2 minutes if it can be avoided (remember this script will be ran when the datacenter goes to UPS power so every watt counts to keep the critical systems online). the script does throw an error when it can't shutdown because no tools are installed so I was thinking I could use a try/catch block to catch the error and send just a strait power off command to those vms. I've attempted to do so, but no success.

    Is there a way that I can either catch the error, or shutdown all VMs that don't have tools installed?

    Attached is my code maybe you can spot what I can do to shutdown the VMs without tools within the do/while loop when the errors first occur.

    Add-PSSnapin VMware.VimAutomation.Core
    $server = $args[0]
    $cluster = $args[1]
    Connect-VIServer -Server $server
    $counter = 0
    do {
    if (Get-Cluster -Name $cluster | get-vm | where {$_.powerstate -eq "poweredon"}){
      if ($counter -eq 0) {
       Get-Cluster -Name $cluster |get-vm | where {$_.powerstate -eq "poweredon"} | shutdown-VMGuest -Confirm:$false
      }
      Write-Host "VMs are powered on waiting "(120-$counter)" Seconds"
      $counter = $counter + 10
      Sleep 10
      }
    }
    while ($counter -le 110) -or ((Get-VMHost | Get-VM | where {$_.powerstate -eq "poweredon"}).count) -ne 0
    if ($counter = 120) {
    Write-Host "Some VMs failed to shut down gracefully, powering down now"
    Get-Cluster -name $cluster |get-vm | where {$_.powerstate -eq "poweredon"} | Stop-VM -Confirm:$false
    }
    Write-Host "Putting servers into maintenance mode."
    Get-cluster -name $cluster | get-vmhost | where {$_.state -eq "connected"} | Set-VMHost -State "Maintenance"
    sleep 10
    Write-Host "Shutting down servers."
    Get-cluster -name $cluster | get-vmhost | where {$_.state -eq "Maintenance"} | Stop-VMHost -Confirm:$false
    Disconnect-VIServer -Confirm:$false


  • 2.  RE: Shutting down VMs with and without VMware tools installed

    Posted Nov 30, 2012 07:29 PM

    Question)

    Why aren't tools installed, not only are they recommended and useful, they are critical to VM functionality.  They aren't any different from using OEM drivers on stand alone servers, and even more compatible because they are tailor made for VM guest OS they support.

    You can do OS level shutdown using a script from the AD to directly communicate with the OS by name also.



  • 3.  RE: Shutting down VMs with and without VMware tools installed

    Posted Nov 30, 2012 08:48 PM

    I agree that the tools should be installed, but that doesn't mean that they always are. With a large enviroment there's a good possibility that a server or two have been missed. I was just hoping that if I ran into a VM like that, I could bring it down quicker than waiting the full 120 seconds.



  • 4.  RE: Shutting down VMs with and without VMware tools installed
    Best Answer

    Posted Nov 30, 2012 10:06 PM

    Try something like this

    $vm = Get-VM
    $vm | where {$_.Guest.State -eq "Running"} | Shutdown-VMGuest -Confirm:$false
    $vm | where {$_.Guest.State -eq "NotRunning"} | Stop-VM -Confirm:$false

    The VMs where the VMware Tools are running will get a Guest shutdown, while the VMs that not have the VMware Tools running, will get a poweroff.



  • 5.  RE: Shutting down VMs with and without VMware tools installed

    Posted Dec 03, 2012 04:15 PM

    Thanks for the commands. Do I need any other snapin installed besides the VMware.VimAutomation.Core? I ask because when I attempt to run the command, I get the "is not recognized as as the name of a cmdlet, function, script file or operable program."

    additionally while debugging my script, I noticed that my while section that is checking the time or for running vms, it doesn't detect that there aren't any running vms.

    More specifically, I tested the commands (Get-VM | where {$_.powerstate -eq "poweredon"}).count and (Get-VM |where {&_.powerstate -eq "poweredoff"}).count and noticed that from the commandline it'll respond with counts 0-"number of VMs" but from a script it returns nothing for 0 or 1 VM. Anyone have experience with this?

    **EDIT**

    nevermind about the whole count issue, it's because I'm not explicitly declairing the variable as an array...

    Funny how you get deeper into it, the easier it is to miss the little things.



  • 6.  RE: Shutting down VMs with and without VMware tools installed

    Posted Dec 03, 2012 04:25 PM

    You did load the snapin with Add-PSSnapin I assume ?

    Did you do a Connect-VIServer to a vCenter or an ESXi host ?



  • 7.  RE: Shutting down VMs with and without VMware tools installed

    Posted Dec 03, 2012 05:05 PM

    Well don't I feel silly, for some reason I wasn't bright enough to reboot my connections after a weekend of inactivity. the commands work beautifully.

    Now correct me if I'm wrong, but would it be a fair statement to say that machines returned by the command "notrunning" are those that are both running without tools installed and vms that are currently powered off? From my tests it seems like it.



  • 8.  RE: Shutting down VMs with and without VMware tools installed

    Posted Dec 03, 2012 05:53 PM

    Not exactly, when the tools are not running you might also see "toolsNotRunning".

    The possible values can be found in the VirtualMachineToolsStatus enumeration.

    When in doubt always consult the SDK Reference :smileygrin:



  • 9.  RE: Shutting down VMs with and without VMware tools installed

    Posted Dec 03, 2012 06:45 PM

    Thanks for all the information. I need to wait for a test cluster to free up to test my script against some physical hardware and integration testing (with our UPS and stuff like that). Here's my code in case anyone has a need similar to what I do.

    #Written by Travis C
    #
    #This script is designed to as gracefully as possible shut down all vms in a cluster and power the hardware down.
    #
    #Requirements to run: PowerCLI installed, Credentials cached on the server and account the script will be ran from.
    #Command: New-VICredentialStoreItem -host {hostname} -User {Username} -Password {Password}
    #
    Add-PSSnapin VMware.VimAutomation.Core
    $server = $args[0]
    $cluster = $args[1]
    Connect-VIServer -Server $server
    $counter = 0
    do {
    if (Get-Cluster -Name $cluster | get-vm | where {$_.powerstate -eq "poweredon"}){
      if ($counter -eq 0) {
       Get-Cluster -Name $cluster | Get-VM | where {$_.guest.state -eq "notrunning"} | Where {$_.powerstate -eq "poweredon"} | Stop-VM -Confirm:$false
       Get-Cluster -Name $cluster | Get-vm | where {$_.powerstate -eq "poweredon"} | shutdown-VMGuest -Confirm:$false
      }
      Write-Host "VMs are powered on waiting "(120-$counter)" Seconds"
      $counter = $counter + 10
      Sleep 10
      }
    }
    until ((@(Get-VMHost | Get-VM | where {$_.powerstate -eq "poweredon"}).count -eq 0 ) -or ($counter -ge 120))
    if ($counter -eq 120) {
    Write-Host "Some VMs failed to shut down gracefully, powering down now"
    get-cluster -name $ cluster | get-vm | where {$_.powerstate -eq "poweredon"} | Stop-VM -Confirm:$false
    }
    Write-Host "Putting servers into maintenance mode."
    Get-cluster -name $cluster | get-vmhost | where {$_.state -eq "connected"} | Set-VMHost -State "Maintenance"
    sleep 10
    Write-Host "Shutting down servers."
    Get-cluster -name $cluster | get-vmhost | where {$_.state -eq "Maintenance"} | Stop-VMHost -Confirm:$false
    Disconnect-VIServer -Confirm:$false