VMware Cloud Community
vmk2014
Expert
Expert
Jump to solution

Scheduling the Bulk VM's Hardware version upgrade in ESXi host 6.5 through power cli

Hello Everyone,

I'm looking to schedule the Bulk lists of VM's to upgrade HW version at a particular time through power cli. Kindly help.

thanks

vmk2014

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

This version of the script should only shut down powered on VMs that have the VMware Tools installed.
Then for all powered off VMs the HW version is upgraded.

$vmNames = Get-Content -Path C:\TEMP\vmliste.txt | where{$_ -ne ''}

# Select powered off VM and powered on VMs that have VMware Tools running

$vms = Get-VM -Name $vmNames | where{$_.PowerState -eq 'PoweredOff' -or

    ($_.PowerState -eq 'PoweredOn' -and $_.Guest.State -eq 'running')}

# Shutdown all powered on VMs from list

$vms | where{$_.PowerState -eq 'PoweredOn'} | Shutdown-VMGuest -Confirm:$false

# Wait till all VMs are shutdown

while((Get-VM -Name $vms.Name | Select -ExpandProperty PowerState) -contains 'PoweredOn'){

    sleep 5

}

# Set new HW version and start VM

Get-VM -Name $vms.Name | Set-VM -Version v13 -Confirm:$false | Start-VM -Confirm:$false


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

View solution in original post

0 Kudos
48 Replies
LucD
Leadership
Leadership
Jump to solution

Do you mean at the next power off/power on of the VM with "...at a particular time..."?


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

Thanks for your response. Actually, we can schedule the vmware virtual HW version upgrade either from Host or VUM but we cant re-boot all VM's becuase it depends on customer downtime available, hence want to schedule and upgrade the lists of VM's and re-boot as per customer down time. Example 100 VM's @ 2:00 AM CST.

Thanks

vmk2014

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Something like this

http://www.running-system.com/powercli-script-schedule-vms-to-upgrade-the-virtual-hardware-at-the-ne...

    • prepare a list (.txt file) with the VMs like this:
    • use the following PowerCLI code to schedule the upgrade for the VMs listed in the .txt file:
      foreach($vmlist in (Get-Content -Path C:\TEMP\vmliste.txt)){$vm = Get-VM -Name $vmlist                $do = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec                $do.ScheduledHardwareUpgradeInfo = New-Object -TypeName VMware.Vim.ScheduledHardwareUpgradeInfo                $do.ScheduledHardwareUpgradeInfo.UpgradePolicy = “always”                $do.ScheduledHardwareUpgradeInfo.VersionKey = “vmx-11”                $vm.ExtensionData.ReconfigVM_Task($do)}

Do not forget to adapt the path to your .txt file. If necessary you can change the vHW version (in the script: vmx-11)

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Not too sure what the question is in this case?


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

If you go through the script links, it shows some error it throws. Also, does it works for ESXi 6.5 ?

Thanks

vmk2014

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you mean the error listed in the comments on that post, I suspect the person reporting that error, might not have the PowerCLI modules loaded.

In any case, that script should work.

For 6.5 you most probably have to update the selected HW version, like this

foreach($vmlist in (Get-Content -Path C:\TEMP\vmliste.txt)){

    $vm = Get-VM -Name $vmlist

    $do = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec

    $do.ScheduledHardwareUpgradeInfo = New-Object -TypeName VMware.Vim.ScheduledHardwareUpgradeInfo

    $do.ScheduledHardwareUpgradeInfo.UpgradePolicy = “always”

    $do.ScheduledHardwareUpgradeInfo.VersionKey = “vmx-13”

    $vm.ExtensionData.ReconfigVM_Task($do)

}


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Thank you LucD. Let me test it in test environment and will get back to you.

thanks

vmk2014

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

My bad, i wanted to use the below script because that will fetch

The scripts will help you to perform the following actions:

  • shutdown all VMs from the list
  • upgrade the virtual Hardware to the desired version (eg. 11)
  • power-on all VMs from the list

http://www.running-system.com/powercli-scripts-to-upgrade-virtual-hardware-of-vms-from-a-list/

Let me know if the above script will work for ESXi6.5/vSphere 6.5

thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That should work in 6.5, provided you change the HW version.

And perhaps add an automated wait till all VMs are shutdown.

Something like this (I prefer to use the pipeline and select multiple VMs in one call).

$vmNames = Get-Content -Path C:\TEMP\vmliste.txt

# Shutdown all VMs from list

Get-VM -Name $vmNames | Shutdown-VMGuest -Confirm:$false

# Wait till all VMs are shutdown

while((Get-VM -Name $vmNames | Select -ExpandProperty PowerState) -contains 'PoweredOn'){

    sleep 5

}

# Set new HW version and start VM

Get-VM -Name $vmNames | Set-VM -Version v13 -Confirm:$false | Start-VM -Confirm:$false


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD, Thank you once again for extending your help here. Let me check in test env and will update shortly.

I will check both the script shared by you.

thanks

vmk

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

I did executed the script but unfortunately it throws an error. Kindly need your help

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:8 char:14

+ Get-VM -Name $vmNames | Shutdown-VMGuest -Confirm:$false

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:13 char:21

+ while((Get-VM -Name $vmNames | Select -ExpandProperty PowerState) -co ...

+                     ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:22 char:14

+ Get-VM -Name $vmNames | Set-VM -Version v13 -Confirm:$false | Start-V ...

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The last script expects 1 VMname per line, no headers.
Something like this

vm1

vm2

vm3


Are there perhaps any blank lines in the .txt file?


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

I did like below

cxv-dsm1

cxvw-iim02

cxvwt-iim17

cxvwt-iim18

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:8 char:14

+ Get-VM -Name $vmNames | Shutdown-VMGuest -Confirm:$false

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:13 char:21

+ while((Get-VM -Name $vmNames | Select -ExpandProperty PowerState) -co ...

+                     ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:22 char:14

+ Get-VM -Name $vmNames | Set-VM -Version v13 -Confirm:$false | Start-V ...

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, let's try to debug this.

What does the following produce as output?

$vmNames = Get-Content -Path C:\TEMP\vmliste.txt

$vmNames.Count

Get-VM -Name $vmNames


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

Here you go :-

PS C:\temp> .\VM-HW.ps1

5

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:7 char:14

+ Get-VM -Name $vmNames

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I did several tests, and the only way I can reproduce the error you are getting, is by placing a blank line at the start of the .txt file.

Can run the following and check if the 1st number is a 0 (zero)?

Get-Content -Path C:\TEMP\vmliste.txt |

ForEach-Object -Process {

    $_.Length

}


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

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

Please find the output after giving the bove command.

PS C:\temp> .\VM-HW.ps1

9

13

14

14

0

This project is important for me because we cant get down time for all VM's in shot, hence trying script.

thanks

vmk

0 Kudos
vmk2014
Expert
Expert
Jump to solution

LucD,

I tried as suggested leaving first line blank

PS C:\temp> .\VM-HW.ps1

0

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:17 char:14

+ Get-VM -Name $vmNames | Shutdown-VMGuest -Confirm:$false

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:23 char:21

+ while((Get-VM -Name $vmNames | Select -ExpandProperty PowerState) -co ...

+                     ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW.ps1:33 char:14

+ Get-VM -Name $vmNames | Set-VM -Version v13 -Confirm:$false | Start-V ...

+              ~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Infact, i  did tried 2nd script given by you initially, but no results except below error

PS C:\temp> .\VM-HW2.ps1

Type Value

---- -----

Task task-9593806

Task task-9593807

Task task-9593808

Task task-9593809

Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not

null or empty, and then try the command again.

At C:\temp\VM-HW2.ps1:3 char:24

+     $vm = Get-VM -Name $vmlist

+                        ~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

Task task-9593810

Thanks

vmk

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I think I know what is happening.

Your .txt file obviously contains 5 lines, and the 4 first lines have a valid VM name on them.

In the original script I used the _Task form of the method, which is why you see the Task lines as output.

These tasks are run in the background, hence the Task reference.

The error happens after 4 background tasks, that is obviously the 5 entry, which is a blank line.
This is also confirmed by the 0 length I saw in the output of the snippet I asked you to run.

To avoid the blank lines causing the errors you are seeing, I added a test after the Get-Content cmdlet.

Give this one a try

$vmNames = Get-Content -Path C:\TEMP\vmliste.txt | where{$_ -ne ''}

# Shutdown all VMs from list

Get-VM -Name $vmNames | Shutdown-VMGuest -Confirm:$false

# Wait till all VMs are shutdown

while((Get-VM -Name $vmNames | Select -ExpandProperty PowerState) -contains 'PoweredOn'){

    sleep 5

}

# Set new HW version and start VM

Get-VM -Name $vmNames | Set-VM -Version v13 -Confirm:$false | Start-VM -Confirm:$false


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

0 Kudos