This week we need to PoweredOff all our VMs in our VMware Infrastructure, because of a Network Maintenance. The problem Powering off 2000 VMs is the Powering ON them back an. You need to track which ones were PoweredOn when you need to PowerOn them again, and with big Infrastructures, this can be tricky.
So I decided to create a PowerCli script that will create a List of all VMs that are in PoweredOn state before I PoweredOff the VMs.
UPDATED 06/07/2017: The First script was updated with the option to Power off the VMs that are Power On (also check the VMware Tools state so that can do a hard power off, or a gracefully Power off. Depending if VMware Tools is running or not in the VM.
This update will create two files. One with all the records (power on, power off, VMware Tools running, not running and the number of VMs power off), and the second one with all VMs that was Power On so that we can use it in the second script to Power on them again.
First, let us create the VMs PoweredOn List. This script will create a simple text file with only the Virtual Machine name for future use/import.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
################################################ # Created by: Luciano Patrão # # Date: 10-05-2017 # # Power Off Virtual Infraestructure (VMs) # # Create List of all VMs powered off # ################################################ ###### Credentials and vCenter connection ###### $vCenter = "Enter vCenter IP or VMware host IP" $user = "Enter user" $pwd = "Enter password" Connect-VIServer $vCenter -User $user -Password $pwd cls $Report=@() $Record=@() $NrVMsOff = 0 $NrVMsOn = 0 $NrVMsToolson = 0 $NrVMsToolsoff = 0 #Create report per Cluster #We can check PoweredON and PoweredOff VMs, just comment this part in the next line | where { $_.PowerState -eq “PoweredOn”}, if not the script will only check PoweredON VMs. #$vms = Get-Cluster "Cluster Test" | Get-vm | where { $_.PowerState -eq “PoweredOn”} #Create report for full vCenter, remove comment if you want to use for all vCenter. $vms = Get-vm | where { $_.PowerState -eq “PoweredOn”} foreach ($vm in $vms) { $VMname = Get-VM $vm | Select Name, @{N="Powerstate";E={($_).powerstate}} #Check VM powerstate if ($VMname.Powerstate -like "PoweredOff") { Write-Host "VM --> ", $VMname.Name, " Already Power off no action needed" $NrVMsOff = $NrVMsOff + 1 } Elseif ($VMname.Powerstate -like "PoweredOn") { Write-Host "VM --> ", $VMname.Name, " is Powered ON, adding to the list" $Report += $VMname.Name $NrVMsOn = $NrVMsOn + 1 #Creating VMs report Write-Host "Processing Power off for VM -> " -f Blue -nonewline; Write-Host "$vm" -f red Write-Host “Checking for VM VMware Tools State” -ForegroundColor Blue;Write-Host #Check VM VMware Tools State $ToolsState = get-view -Id $vm.Id If ($ToolsState.config.Tools.ToolsVersion -eq 0) { $Record += “$vm ###### VMware tools not detected. I will shutdown VM" $NrVMsToolsoff = $NrVMsToolsoff + 1 #Stop-VM $VMname.Name -Confirm:$false Sleep 3 } Else { $Record += “$vm ###### VMware tools detected. I will attempt to gracefully shutdown” $NrVMsToolson = $NrVMsToolson + 1 #$vm | Shutdown-VMGuest -Confirm:$false Sleep 5 } } } $Record += "" $Record += "#### Number of VMs that were Powered off ####" $Record += " Total of " + $NrVMsToolsoff + " VMs with no VMware Tools" $Record += " Total of " + $NrVMsToolson + " VMs with VMware Tools" $Record += " Total of " + $NrVMsOn + " VMs Powered off" #Will write in the screen the VMs Totals Write-Host "Total of " $NrVMsToolsoff " VMs with no VMware Tools" Write-Host "Total of " $NrVMsToolson " VMs with VMware Tools" Write-Host "Total of " $NrVMsOn " VMs Powered off" Write-Host "Total of " $NrVMsOff " were already VMs Powered Off" Write-Host "Total of " $NrVMsOn " VMs Powered On and added to the Power ON list script" write-host "Creating reports ..." Sleep 3 $Path= "add your path here" $PowerON = "$Path\PowerOnVMs.txt" $PoweredOFF = "$Path\Record-Powered-Off-VMs.txt" $Report | Out-File $PowerON $Record | Out-File $PoweredOFF #Disconnect vCenter Server Disconnect-VIServer $vCenter -Confirm:$false |
Just run the script and will create a file (in the path you choose) called PowerOnVMs.txt
This is an output example of the file:
1 2 3 4 5 6 7 8 |
ESXi 5.5 - 003 ESXi 5.5 - 002 ESXi 5.5 - 001 - v6.0 SL 002 x64 SL 001 x32 SL 004 x32 |
Now we have a list of all VMs that have the power on state. After we power off all the VMs that we need.
When we need to Power ON the VMs back again, we just run the second script to import all VM from the file created in the initial script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
################################################ # Created by: Luciano Patrão # # Date: 10-05-2017 # # Import VMs from TXT VMs file and PowerON # ################################################ ###### Credentials and vCenter connection ###### $vCenter = "Enter vCenter IP or VMware host IP" $user = "Enter user" $pwd = "Enter password" Connect-VIServer $vCenter -User $user -Password $pwd cls $Report=@() $NrVMsOff = 0 $NrVMsOn = 0 #Import vm name from file created $VMlist = Get-Content "AddYourPathHere\PoweronVMs.txt foreach ($vm in $VMlist) { $VMname = Get-VM $vm | Select Name, @{N="Powerstate";E={($_).powerstate}} #Check VM powerstate if ($VMname.Powerstate -like "PoweredOff") { Write-Host "VM --> ", $VMname.Name, " in the list is PowerOff, sript will start the VM " Start-VM -VM $VMname.Name -Verbose:$false Sleep 2 $Report += "VM --> " + $VMname.Name + " in the list is PowerOff, sript will start the VM " $NrVMsOff = $NrVMsOff + 1 } Elseif ($VMname.Powerstate -like "PoweredOn") { Write-Host "VM --> ", $VMname.Name, " in the list is already PowerON, no action taken" #Creating VMS report $Report += "VM --> " + $VMname.Name + " in the list is already PowerON, no action taken" $NrVMsOn = $NrVMsOn + 1 } } $Report += " --- Total of " + $NrVMsOn + " VMs PowerOn no changes" $Report += " --- Total of " + $NrVMsOff + " VMs were PowerOff script did PowerON" write-host "Creating report ..." Sleep 3 $Path= "add your path here" $PowerOff = "$Path\PowerOffVMs.txt" $Report | Out-File $PowerOff #Disconnect vCenter Server Disconnect-VIServer $vCenter -Confirm:$false |
This is an example of the file output:
1 2 3 4 5 6 7 8 9 10 |
VM --> ESXi 5.5 - 003 in the list is already PowerON, no action taken VM --> ESXi 5.5 - 002 in the list is already PowerON, no action taken VM --> ESXi 5.5 - 001 - v6.0 in the list is already PowerON, no action taken VM --> SL 002 x64 in the list is PowerOff, sript will start the VM VM --> SL 001 x32 in the list is PowerOff, sript will start the VM VM --> SL 004 x32 in the list is PowerOff, sript will start the VM --- Total of 3 VMs PowerOn no changes --- Total of 3 VMs were PowerOff script did PowerON |
The script will run through all VMs list and will PowerON all the VMs that are inside that file.
Will also provide the Total number of VMs that were PowerOff and did not touch, and the number of VMs that did PowerON and will also create a file called PowerOffVMs.txt so that you have the record of all VMs that were PowerON and the ones that the script did not touch.
Hope these scripts help you.
Note: Share this article, if you think it is worth sharing.
Can you please add the section of the script that shuts down the VMs as well, like a clean data center shutdown?
Thanks in advance
Hi Kevin,
This section needs to be in two different ways. First, we need to check if the VM have VMware Tools installed, if yes we will have a Guest Shutdown, if not then we need to send hard shutdown (Power off VM).
At this moment I am a little bit busy, just give me a few days, and I will send you the script with this included.
Thank You for your visit and reply.
Luciano Patrao
Hi Kevin,
First sorry that I completely forgot about this. When i receive a new commend here I did notice that I did not reply you with the update script that you ask me and I promise to add.
Here is the script with the option to check VM VMware Tools and will power off VMs depending VMware Tools is running or not.
################################################
# Created by: Luciano Patrão #
# Date: 10-05-2017 #
# Power Off Virtual Infraestructure (VMs) #
# Create List of all VMs powered off #
################################################
###### Credentials and vCenter connection ######
$vCenter = "Enter vCenter IP or VMware host IP"
$user = "Enter user"
$pwd = "Enter password"
Connect-VIServer $vCenter -User $user -Password $pwd
cls
$Report=@()
$Record=@()
$NrVMsOff = 0
$NrVMsOn = 0
$NrVMsToolson = 0
$NrVMsToolsoff = 0
#Create report per Cluster
#We can check PoweredON and PoweredOff VMs, just comment this part in the next line | where { $_.PowerState -eq “PoweredOn”}, if not the script will only check PoweredON VMs.
#$vms = Get-Cluster "Cluster Test" | Get-vm | where { $_.PowerState -eq “PoweredOn”}
#Create report for full vCenter, remove comment if you want to use for all vCenter.
$vms = Get-vm | where { $_.PowerState -eq “PoweredOn”}
foreach ($vm in $vms)
{
$VMname = Get-VM $vm | Select Name, @{N="Powerstate";E={($_).powerstate}}
#Check VM powerstate
if ($VMname.Powerstate -like "PoweredOff")
{
Write-Host "VM --> ", $VMname.Name, " Already Power off no action needed"
$NrVMsOff = $NrVMsOff + 1
}
Elseif ($VMname.Powerstate -like "PoweredOn")
{
Write-Host "VM --> ", $VMname.Name, " is Powered ON, adding to the list"
$Report += $VMname.Name
$NrVMsOn = $NrVMsOn + 1
#Creating VMs report
Write-Host "Processing Power off for VM -> " -f Blue -nonewline; Write-Host "$vm" -f red
Write-Host “Checking for VM VMware Tools State” -ForegroundColor Blue;Write-Host
#Check VM VMware Tools State
$ToolsState = get-view -Id $vm.Id
If ($ToolsState.config.Tools.ToolsVersion -eq 0)
{
$Record += “$vm ###### VMware tools not detected. I will shutdown VM"
$NrVMsToolsoff = $NrVMsToolsoff + 1
#Stop-VM $VMname.Name -Confirm:$false
Sleep 3
}
Else
{
$Record += “$vm ###### VMware tools detected. I will attempt to gracefully shutdown”
$NrVMsToolson = $NrVMsToolson + 1
#$vm | Shutdown-VMGuest -Confirm:$false
Sleep 5
}
}
}
$Record += ""
$Record += "#### Number of VMs that were Powered off ####"
$Record += " Total of " + $NrVMsToolsoff + " VMs with no VMware Tools"
$Record += " Total of " + $NrVMsToolson + " VMs with VMware Tools"
$Record += " Total of " + $NrVMsOn + " VMs Powered off"
#Will write in the screen the VMs Totals
Write-Host "Total of " $NrVMsToolsoff " VMs with no VMware Tools"
Write-Host "Total of " $NrVMsToolson " VMs with VMware Tools"
Write-Host "Total of " $NrVMsOn " VMs Powered off"
Write-Host "Total of " $NrVMsOff " were already VMs Powered Off"
Write-Host "Total of " $NrVMsOn " VMs Powered On and added to the Power ON list script"
write-host "Creating reports ..."
Sleep 3
$Path= "add your path here"
$PowerON = "$Path\PowerOnVMs.txt"
$PoweredOFF = "$Path\Record-Powered-Off-VMs.txt"
$Report | Out-File $PowerON
$Record | Out-File $PoweredOFF
#Disconnect vCenter Server
Disconnect-VIServer $vCenter -Confirm:$false
The option to power off VMs is commented. So test it, and then if it works(check reports to see if you have all your VMs inside) run it in a test environment. If you think is ok for you, then you can run in your environment to power off all your VMs. Always be aware of Domain Controller and Database VMs. Double check if they will be power off gracefully and not Hard power off.
Hope this can help you
Luciano Patrao
Hi,
I’d be interested as well in the Power Off script, once you create it. And – not sure if that is possible – I would need to trigger it from inside a VM. And ideally in the end after shutting down all VM’s the ESXi should be shut down as well.
Thx,
Thomas
Hi Thomas,
I did reply to previous user and provided a script with all that information except for host shutdown. That needs a better script and needs to double check VMs, hosts, maintenance mode etc. Sorry for now I dont have time to do something like that.
Thank you for your comment.
Luciano Patrao