VMware Cloud Community
JasonNB
Contributor
Contributor
Jump to solution

Help with scripting shut-down/power-on

Scripting is not my strong suite yet, but I'm learning. I am dabbling with PowerCLI to write a script that will take a list of VM's from a file, Shut them down one/time per order of the list, wait for Power-Off, then power on the VM, wait for VMTools to start, and perform the same sequence on the next server in the list.  Currently, my simple script cobbled together from examples give by others shuts them all down in parallel and powers them back on as they show "Powered-Off", so I'm close. What snippet am I missing to get them in order instead of parallel? I've looked through some examples, but haven't hit the right one yet and feel this is likely a simple thing I'm overlooking.

#Get the Credentials

$creds = Get-VICredentialStoreItem -file  C:\powercli\qa.creds

#Connect to the server using the credentials file

Connect-VIServer -Server $creds.host -User $creds.User -Password $creds.Password

$file = "c:\powercli\scripts\vmlist.txt"

$vms = Get-Content $file

#Reboot servers in proper order and wait for tools to be running until the next vm reboots

foreach ($vms in $file){

       Get-VM $vms | where-object {$_.PowerState -eq "PoweredOn"} | Shutdown-VMGuest -Confirm:$false | Out-Null

  

       do {} until ((Get-VM $vms | select PowerState).powerstate -eq "PoweredOff")

       Start-VM -VM $vms    

  start-sleep -s 3

  wait-tools -vm $vms

   

}

#Clean Up

Disconnect-VIServer -Force -Confirm:$false

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I think your ForEach is getting the data from the incorrect variable ($file).
The Shutdown-VMGuest cmdlet starts the shutdown inside the guest OS, and then comes back.
With the While-loop the script waits till the VM is actually powered off.

Try like this

#Get the Credentials

$creds = Get-VICredentialStoreItem -file C:\powercli\qa.creds


#Connect to the server using the credentials file

Connect-VIServer -Server $creds.host -User $creds.User -Password $creds.Password


$file = "c:\powercli\scripts\vmlist.txt"

$vms = Get-Content -Path $file


#Reboot servers in proper order and wait for tools to be running until the next vm reboots

foreach ($vmName in $vms)

{

   $vm = Get-VM -Name $vmName

   if ($vm.PowerState -eq 'PoweredOn')

   {

   $vm = Shutdown-VMGuest -VM $vm -Confirm:$false

   while ($vm.PowerState -ne 'PoweredOff')

   {

  sleep 5

   $vm = Get-VM -Name $vmName

   }

   }


   Start-VM -VM $vm -Confirm:$false

   Wait-Tools -vm $vms

}


#Clean Up

Disconnect-VIServer -Force -Confirm:$false

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
7 Replies
LucD
Leadership
Leadership
Jump to solution

I think your ForEach is getting the data from the incorrect variable ($file).
The Shutdown-VMGuest cmdlet starts the shutdown inside the guest OS, and then comes back.
With the While-loop the script waits till the VM is actually powered off.

Try like this

#Get the Credentials

$creds = Get-VICredentialStoreItem -file C:\powercli\qa.creds


#Connect to the server using the credentials file

Connect-VIServer -Server $creds.host -User $creds.User -Password $creds.Password


$file = "c:\powercli\scripts\vmlist.txt"

$vms = Get-Content -Path $file


#Reboot servers in proper order and wait for tools to be running until the next vm reboots

foreach ($vmName in $vms)

{

   $vm = Get-VM -Name $vmName

   if ($vm.PowerState -eq 'PoweredOn')

   {

   $vm = Shutdown-VMGuest -VM $vm -Confirm:$false

   while ($vm.PowerState -ne 'PoweredOff')

   {

  sleep 5

   $vm = Get-VM -Name $vmName

   }

   }


   Start-VM -VM $vm -Confirm:$false

   Wait-Tools -vm $vms

}


#Clean Up

Disconnect-VIServer -Force -Confirm:$false

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
JasonNB
Contributor
Contributor
Jump to solution

Thank you! That works great except for the Wait-Tools gives me an "Object reference not set to an instance of an object" and it ignores that portion, so i'll see if I can sort that out.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

My bad, that should have said

Wait-Tools -vm $vm


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
JasonNB
Contributor
Contributor
Jump to solution

I spotted that and tried it but it still errors and immediately starts shutting down the next VM.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Strange, but then again, I seldom use Wait-Tools.

I use the following in my scripts, if I want to make sure that the VMware Tools are running and responding.

Start-VM -VM $vm > $null

 

while ($vm.ExtensionData.Guest.ToolsRunningStatus -ne [VMware.Vim.VirtualMachineToolsRunningStatus]::guestToolsRunning -or

   $vm.ExtensionData.Runtime.PowerState -ne [VMware.Vim.VirtualMachinePowerState]::poweredOn)

{

  sleep 2

   $vm.ExtensionData.UpdateViewData()

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
JasonNB
Contributor
Contributor
Jump to solution

l'll need to study this to understand it, but that works perfectly. Thank you for the help and educating me on this a bit.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

With the ExtensionData property you have access to all properties as used internally by vSphere.

You can explore in the API Reference, under the VirtualMachine object.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos