There are many articles on the web about how to shutdown and poweron VMs with a script. My version of powering on VMs is here. Here is the script for powering off a list of VMs.


  • First a CSV file (poweredonvms.csv) containing list of servers to be updated.




  • And here is the actual Windows Powershell script. To run from  vSphere PowerCLI, remove "Add-PSSnapin VMware.VimAutomation.Core" at the beginning of the code. After shutting off the vms, it sends out an email with the list of vms.
  • It first checks if a vm is powered on and if it has VMware Tools are installed. If vm is powered off already, it will be skipped. If VMware Tools are installed, there will be graceful shutdown of the guest OS else there will be a hard shutdown. The list will show which method was used.


Add-PSSnapin VMware.VimAutomation.Core

$vcenter="<vcenter name>"

#Connect to vcenter server
connect-viserver $vcenter

#Import vm name from csv file
Import-Csv E:\Scripts\power\poweredonvms.csv |
foreach {
    $strNewVMName = $

    #Generate a view for each vm to determine power state
    $vm = Get-View -ViewType VirtualMachine -Filter @{"Name" = $strNewVMName}

    #If vm is powered on then VMware Tools status is checked
           if ($vm.Runtime.PowerState -ne "PoweredOff") {
               if ($vm.config.Tools.ToolsVersion -ne 0) {

                   Write-Host "VMware tools installed. Graceful OS shutdown ++++++++ $strNewVMName ----"
                   Shutdown-VMGuest $strNewVMName -Confirm:$false
                   #For generating email
                   $Report += $strNewVMName + " --- VMware tools installed. Graceful OS shutdown `r`n"
               else {

                      Write-Host "VMware tools not installed. Force VM shutdown ++++++++ $strNewVMName ----"
                      Stop-VM $strNewVMName -Confirm:$false
                   #For generating email
                   $Report += $strNewVMName + " --- VMware tools not installed. Force VM shutdown `r`n"

write-host "Sleeping ..."
Sleep 300

#Send out an email with the names
$emailFrom = "<sender email id>"
$emailTo = "<recipient email id>"
$subject = "List of servers shutdown for maintenance"
$smtpServer = "<smtp server name>"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($emailFrom, $emailTo, $subject, $Report)

#Disconnect vcenter server
disconnect-viserver $vcenter -Confirm:$false