HOWTO: Power On a VMware Virtual Machine with PowerCLI (PowerCLI 101)

Being able to Power on a Virtual Machine is a PowerCLI 101 subject (right after the Connect-VIServer).

Start-VM -VM "<VM Name>" -Server "<vCenter/ESX Server Name>"

However, how about being able to choose what to do with a Virtual Machine based on its current Power Status?  That is where (amongst other ways) the PowerShell Switch command comes in.

Firstly we get the Virtual Machine Object using Get-VM into an object called (funnily enough) $VM.

$VM = Get-VM -Name "<Name>" -Location "<vCenter/Host Name>"

Then we use the PowerState property of the Virtual Machine Object to query the power state of that VM and act accordingly.

  • PoweredOn
  • PoweredOff
  • Suspended

There are three defined states according the Virtual Machine Object that we can use in the Switch.

Switch (item)
{
Value A {Expression}
Value B {Expression}
Value X {Expression}

Default {Expression}
}

Whoa there… What is the Default condition for? Well the clue is in the name, the Default condition is only run if no other condition is matched.

For Virtual Machine(s) that are in a PowerState of “Powered On” or “Suspended” we’ll just display a message to that effect.  Albeit, you could easily Start the Suspended Machine or Power Off the already Powered On Virtual Machine but that’s not what this post is about!  For the Virtual Machine(s) that are Powered Off, we’ll Power them On!

Switch ($VM.PowerState)
{
PoweredOn { Write-Host "$VM already Powered On.";break}
PoweredOff { Write-Host "Powering on $VMName on <esx-host-Name>"; Start-VM -VM $VM -Server "<esx-host-Name>";break}
Suspended { Write-Host "$VM suspended.";break}
Default {break}
}

Now (again) we can put all of this logic into a Function called PowerOnVM

Function PowerOnVM ([string] $Name, [string] $Hostname)
{

$VM = Get-VM -Name $Name -Location $Hostname
Switch ($VM.PowerState)
{
PoweredOn { Write-Host "$VM already Powered On.";break}
PoweredOff { Write-Host "Powering on $VMName on $Hostname"; Start-VM -VM $VM -Server $Hostname;break}
Suspended { Write-Host "$VM suspended.";break}
Default {break}
}
}

Which can then be called by a script using:

PowerOnVM "<vm name>" "<host/vcenter name>"

I’m sure there are PowerCLI wizards out there who can be more efficient in their code and this PowerOnVM function could easily be changed to a ChangeVMPowerState function by Powering Off VMs that were on and vice versa.

2 Comments

  1. Hello, I am trying to apply this workaround with all VMs powered off on the host.
    How should I modify it to create a for-each to check all VMs and create a scheduled task to check periodically if any of them are powered off and power on the ones which are powered off?

    I would really appreciate if you could help me.

    Regards.

    1. Hi Jimmy, Sorry only just seen this – try something like this:

      $vCenterServer = “
      $User = “
      $Password = “

      $EncryptedPassword = ConvertTo-SecureString -String “$Password” -AsPlainText -Force
      $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $EncryptedPassword

      $Con = Connect-VIServer $vCenterServer -Credential $Credential -SaveCredentials -Force -ErrorAction SilentlyContinue

      $VMList = Get-VM

      if ($Con) {
      ForEach ($Name in $VMList)
      {
      $VM = Get-VM -Name $Name -ErrorAction SilentlyContinue | Select Name,VMHost,PowerState

      If ($VM){
      [string]$VHost = $VM.VMHost

      Switch ($VM.PowerState)
      {
      PoweredOn { Write-Host $VM.Name “already Powered On.” -ForegroundColor Yellow; break}
      PoweredOff { Write-Host “Powering on” $VM.Name “on” $VM.VMHost -ForegroundColor Yellow; Start-VM -VM $Name -Server $VHost; break}
      Suspended { Write-Host $VM.Name ” suspended.” -ForegroundColor Yellow; break}
      Default {break}
      }
      } else {
      Write-Host “$Name not found.” -ForeGroundColor Magenta
      }
      }
      }

      Not sure how you would put that as a scheduled task though.

      Chris

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.