13 Replies Latest reply on Oct 10, 2019 8:11 AM by BBB36

    Update Video Ram. Wait for task to complete before proceeding to next action.

    BBB36 Novice

      Hi all. My objective is the following:

      1) Stop VM

      2) Take snapshot

      3) Update video ram to new value

      4) Start VM

      I want each task to be confirmed as complete before proceeding to the next task.

      The VMs are in a CSV file.

      The stop VM and take snapshot completes successfully. Although there's an error in the second part (screen output).

      It doesn't actually update the video ram but just prints out the part stating the script will complete before powering on the VM and it gets stuck there because the VMs are actually not powered on.

       

       

      The screen output is below:

      *****************************************************************************************

      PS C:\PowerCLI\scripts\set_video_ram> C:\PowerCLI\Scripts\set_video_ram\update_vram_poweroff_snapshot.ps1

      vm1 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

      vm2 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

       

       

      Name                 PowerState Num CPUs MemoryGB      

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

      vm1          PoweredOff 1        4.000         

      Snapshot of vm1 is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task...

      Exception calling "ContainsKey" with "1" argument(s): "Key cannot be null.

      Parameter name: key"

      At H:\PowerCLI\Scripts\set_video_ram\update_vram_poweroff_snapshot.ps1:68 char:2

      +     elseif($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error"){

      +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

          + FullyQualifiedErrorId : ArgumentNullException

       

      vm2          PoweredOff 1        2.000         

      Snapshot of vm2 is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task...

      Exception calling "ContainsKey" with "1" argument(s): "Key cannot be null.

      Parameter name: key"

      At H:\PowerCLI\Scripts\set_video_ram\update_vram_poweroff_snapshot.ps1:68 char:2

      +     elseif($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error"){

      +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

          + FullyQualifiedErrorId : ArgumentNullException

       

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

      The scrript will wait for the configuration task to be complete before the VMs are powered on

       

       

      The script snippet is below:

      ***********************************************************************************

      $newVideoRamSize = 9000

      $vmlist = Import-Csv .\vmlist.csv -UseCulture

      $vmlist1 = $vmlist | select -ExpandProperty VM

      $taskTab = @{}

       

       

      #Shutdown VMs

          foreach ($vm in $vmlist1) {

          #if($vm.Powerstate -eq "PoweredOn") { //FYI If this part is not commented out, the script will run without doing anything.

          Write-Host $vm is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task... -foregroundcolor green

          $taskTab[(Stop-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

      }

      #}

       

       

      #Take snapshot of VMs

          $runningTasks = $taskTab.Count

      while($runningTasks -gt 0){

      Get-Task | % {

      if($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success"){

          Get-VM $taskTab[$_.Id]

          Write-Host Snapshot of $taskTab[$_.Id] is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task... -foregroundcolor green

          $tasktab[(New-Snapshot -VM $taskTab[$_.Id] -Name BeforeVideoRamChange -RunAsync).Id] = $vm

          $taskTab.Remove($_.Id)

      $runningTasks--

      }

      }

      elseif($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error"){

      $taskTab.Remove($_.Id)

      $runningTasks--

      }

      }

      Start-Sleep -Seconds 15

       

       

      #Update Video Ram

          $runningTasks = $taskTab.Count

      while($runningTasks -gt 0){

      Get-Task | % {

      if($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success"){

          Get-VM $taskTab[$_.Id]

          if($taskTab[$_.Id].Powerstate -eq "PoweredOn")

          {return "One or more VMs is still powered on. Manually power off VMs before re-attempting."}

       

       

      $vid = $taskTab[$_.Id].ExtensionData.Config.Hardware.Device | ?{$_.GetType().Name -eq "VirtualMachineVideoCard"}

          $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

          $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

          $devChange.Operation = 'edit'

          $vid.videoRamSizeInKB = $newVideoRamSize

             

          if ((!$devChange.Operation) -or (!$vid.videoRamSizeInKB))

          {return "ERROR: Unable to set video memory on $taskTab[$_.Id]}. Ensure it is powered off."}

       

      Write-Host Video Memory on VM: $taskTab[$_.Id] has been successfully set to $vid.videoRamSizeInKB -foregroundcolor green

             

      $devChange.Device += $vid

      $spec.DeviceChange += $devChange

      $taskTab[$_.Id].ExtensionData.ReconfigVM($spec)

          $taskTab.Remove($_.Id)

      $runningTasks--

      }

      elseif($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error"){

      $taskTab.Remove($_.Id)

      $runningTasks--

      }

      Start-Sleep -Seconds 15

         

      Write-Host The script will wait for the configuration task to be complete before the VMs are powered on -foregroundcolor green

          }

      }

       

       

      #Power on VMs

          $runningTasks = $taskTab.Count

      while($runningTasks -gt 0){

      Get-Task | % {

      if($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success"){

          Get-VM $taskTab[$_.Id]

          if($taskTab[$_.Id].Powerstate -eq "PoweredOff") {

          Write-Host $taskTab[$_.Id] is now being powered on. Please wait five to ten minutes before verifying new configuration -foregroundcolor green

          $taskTab[(Start-VM -VM $taskTab[$_.Id] -Confirm:$false -RunAsync).Id] = $vm

          }

      }

      }

      }

      *****************************************************************************************

      Any help to point out the issues and/or fix the script would be greatly appreciated.

        • 1. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
          LucD Guru
          Community WarriorsUser ModeratorsvExpert

          If there are client-side tasks, there will not be an Id property, hence the error.

          Try changing those lines to

           

              Get-Task | where{$_.Id} | % {

           

          • 2. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
            BBB36 Novice

            Hi LucD,

             

            Thanks for your response, and I appreciate your help always. I did make the changes as suggested but got the same errors.

            • 3. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
              LucD Guru
              Community WarriorsvExpertUser Moderators

              There must be one or more tasks that do not have an Id.

              Can you check with

               

              Get-Task | Select Name,StartTime,Id

               

              • 4. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                BBB36 Novice

                Do you mean logging in to the vCSA and running this?

                 

                PS C:\Users\myuserid> Get-Task | Select Name,StartTime,Id

                 

                Result of the above here:

                Name            StartTime           Id

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

                CloneVM_Task    10/08/2019 15:04:16 Task-task-234068

                UpgradeVM_Task  10/08/2019 15:04:46 Task-task-234589

                ReconfigVM_Task 10/08/2019 15:04:57 Task-task-234565

                ReconfigVM_Task 10/08/2019 15:05:13 Task-task-234665

                CloneVM_Task    10/08/2019 15:05:33 Task-task-234555

                UpgradeVM_Task  10/08/2019 15:05:53 Task-task-233445

                 

                Or do you mean I need to update the script with the Get-Task | Select Name,StartTime,Id?

                • 5. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                  LucD Guru
                  vExpertUser ModeratorsCommunity Warriors

                  I had another look at your script, and there is a brace too much after the if-statement.
                  The elseif part was not inside the foreach block.
                  Change the code to

                   

                  #Take snapshot of VMs

                   

                  $runningTasks = $taskTab.Count

                  while ($runningTasks -gt 0) {

                      Get-Task | % {

                          if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                              Get-VM $taskTab[$_.Id]

                              Write-Host Snapshot of $taskTab[$_.Id] is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task... -foregroundcolor green

                              $tasktab[(New-Snapshot -VM $taskTab[$_.Id] -Name BeforeVideoRamChange -RunAsync).Id] = $vm

                              $taskTab.Remove($_.Id)

                              $runningTasks--

                          } # Removed extra brace <===

                          elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                              $taskTab.Remove($_.Id)

                              $runningTasks--

                          }

                      }

                      Start-Sleep -Seconds 15

                  • 6. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                    BBB36 Novice

                    Hmm. Tried that but it says it's missing a closing brace. See attached Capture.PNGimage.

                    • 7. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                      LucD Guru
                      vExpertCommunity WarriorsUser Moderators

                      When you take a brace away there, you have to add one at the end.

                       

                      $newVideoRamSize = 9000

                      $vmlist = Import-Csv .\vmlist.csv -UseCulture

                      $vmlist1 = $vmlist | select -ExpandProperty VM

                      $taskTab = @{ }

                       

                       

                      #Shutdown VMs

                      foreach ($vm in $vmlist1) {

                          #if($vm.Powerstate -eq "PoweredOn") { //FYI If this part is not commented out, the script will run without doing anything.

                          Write-Host $vm is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task... -foregroundcolor green

                          $taskTab[(Stop-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

                      }

                      #}

                       

                       

                      #Take snapshot of VMs

                      $runningTasks = $taskTab.Count

                      while ($runningTasks -gt 0) {

                          Get-Task | % {

                              if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                  Get-VM $taskTab[$_.Id]

                                  Write-Host Snapshot of $taskTab[$_.Id] is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task... -foregroundcolor green

                                  $tasktab[(New-Snapshot -VM $taskTab[$_.Id] -Name BeforeVideoRamChange -RunAsync).Id] = $vm

                                  $taskTab.Remove($_.Id)

                                  $runningTasks--

                              }

                              elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                  $taskTab.Remove($_.Id)

                                  $runningTasks--

                              }

                          }

                          Start-Sleep -Seconds 15

                       

                          #Update Video Ram

                          $runningTasks = $taskTab.Count

                          while ($runningTasks -gt 0) {

                              Get-Task | % {

                                  if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                      Get-VM $taskTab[$_.Id]

                                      if ($taskTab[$_.Id].Powerstate -eq "PoweredOn") {

                                          return "One or more VMs is still powered on. Manually power off VMs before re-attempting."

                                      }

                       

                                      $vid = $taskTab[$_.Id].ExtensionData.Config.Hardware.Device | ? { $_.GetType().Name -eq "VirtualMachineVideoCard" }

                                      $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

                                      $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

                                      $devChange.Operation = 'edit'

                                      $vid.videoRamSizeInKB = $newVideoRamSize

                           

                                      if ((!$devChange.Operation) -or (!$vid.videoRamSizeInKB)){

                                          return "ERROR: Unable to set video memory on $taskTab[$_.Id]}. Ensure it is powered off."

                                      }

                       

                                      Write-Host Video Memory on VM: $taskTab[$_.Id] has been successfully set to $vid.videoRamSizeInKB -foregroundcolor green

                           

                                      $devChange.Device += $vid

                                      $spec.DeviceChange += $devChange

                                      $taskTab[$_.Id].ExtensionData.ReconfigVM($spec)

                                      $taskTab.Remove($_.Id)

                                      $runningTasks--

                                  }

                                  elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                      $taskTab.Remove($_.Id)

                                      $runningTasks--

                                  }

                                  Start-Sleep -Seconds 15

                       

                                  Write-Host The script will wait for the configuration task to be complete before the VMs are powered on -foregroundcolor green

                              }

                          }

                       

                       

                          #Power on VMs

                          $runningTasks = $taskTab.Count

                          while ($runningTasks -gt 0) {

                              Get-Task | % {

                                  if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                      Get-VM $taskTab[$_.Id]

                                      if ($taskTab[$_.Id].Powerstate -eq "PoweredOff") {

                                          Write-Host $taskTab[$_.Id] is now being powered on. Please wait five to ten minutes before verifying new configuration -foregroundcolor green

                                          $taskTab[(Start-VM -VM $taskTab[$_.Id] -Confirm:$false -RunAsync).Id] = $vm

                                      }

                                  }

                              }

                          }

                      }

                      • 8. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                        BBB36 Novice

                        Yep. You're right. I updated the script. Thank you.

                        It took only the snapshot of one of the 2 VMs though. Also, now it's just stuck at "The script will wait for the configuration task to be complete before the VMs are powered on" and doesn't progress to update the video ram and start up the VMs. See results below. Any ideas?

                        *********************************************************************************************

                        PS C:\PowerCLI\> C:\PowerCLI\update_vram_poweroff_snapshot.ps1

                        VM1 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

                        VM2 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

                         

                         

                        Name                 PowerState Num CPUs MemoryGB      

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

                        VM1          PoweredOff 1        4.000         

                        Snapshot of VM1 is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task...

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                        The script will wait for the configuration task to be complete before the VMs are powered on

                         

                         

                        PS C:\PowerCLI\>

                        • 9. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                          BBB36 Novice

                          Do I need to change this:

                          $_.Id) -and $_.State -eq "Success") to this:

                          $_.Status) -and $_.State -eq "Completed") to match the tab name and actual results in vCenter tasks perhaps?

                          • 10. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                            BBB36 Novice

                            I'd also like to add, I have another version of this script, which actually does everything but I don't think the wait-task works. Here it is:

                            ******************************************************************************************************************************************************

                            $newVideoRamSize = 9000

                            $vmlist1 = $vmlist | select -ExpandProperty VM

                             

                            #Shutdown VMs

                                foreach ($vm in $vmlist1) {

                                $guestname = Get-VM $vm

                                if($guestname.Powerstate -eq "PoweredOn") {

                                Write-Host $guestname is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task... -foregroundcolor green

                                $shutvmtask = Stop-VM -VM $guestname -Confirm:$false -RunAsync | Out-Null }

                                Wait-Task $shutvmtask

                                Start-Sleep -Seconds 15

                            }

                             

                            #Take snapshot of VMs

                                foreach ($vm in $vmlist1) {

                                $guestname = Get-VM $vm

                                Write-Host Snapshot of $guestname is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task... -foregroundcolor green

                                $snapshotvmtask = New-Snapshot -VM $guestname -Name BeforeVideoRamChange -RunAsync | Out-Null }

                                Wait-Task $snapshotvmtask

                                Start-Sleep -Seconds 15

                             

                            #Update Video Ram

                                foreach ($vm in $vmlist1) {

                                    $guestname = Get-VM $vm

                                    if($guestname.Powerstate -eq "PoweredOn")

                                    {return "One or more VMs is still powered on. Manually power off VMs before re-attempting."}

                             

                                     $vid = $guestname.ExtensionData.Config.Hardware.Device | ?{$_.GetType().Name -eq "VirtualMachineVideoCard"}

                                    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

                                    $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

                                    $devChange.Operation = 'edit'

                                    $vid.videoRamSizeInKB = $newVideoRamSize

                                   

                                    if ((!$devChange.Operation) -or (!$vid.videoRamSizeInKB))

                                    {return "ERROR: Unable to set video memory on $guestname}. Ensure it is powered off."}

                             

                            Write-Host Video Memory on VM: $guestname has been successfully set to $vid.videoRamSizeInKB -foregroundcolor green

                                   

                            $devChange.Device += $vid

                            $spec.DeviceChange += $devChange

                            $vramconfigtask = $guestname.ExtensionData.ReconfigVM($spec)

                                    Wait-Task $vramconfigtask

                                    Start-Sleep -Seconds 15

                                    Write-Host The script will wait for the configuration task to be complete before the VMs are powered on -foregroundcolor green

                            }

                             

                            #Power on VMs

                                foreach ($vm in $vmlist1) {

                                $guestname = Get-VM $vm

                                if($guestname.Powerstate -eq "PoweredOff") {

                                Write-Host $guestname is now being powered on. Please wait five to ten minutes before verifying new configuration -foregroundcolor green

                                Start-VM -VM $guestname -Confirm:$false -RunAsync | Out-Null }

                            }

                             

                            ******************************************************************************************************************************************************

                            The output is below:

                            ******************************************************************************************************************************************************

                            VM1 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

                            Wait-Task : Cannot validate argument on parameter 'Task'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

                            At C:\PowerCLI\update_vram_poweroff_snapshot-Copy.ps1:53 char:15

                            +     Wait-Task $shutvmtask

                            +               ~~~~~~~~~~~

                                + CategoryInfo          : InvalidData: (:) [Wait-Task], ParameterBindingValidationException

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

                             

                            VM2 is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task...

                            Wait-Task : Cannot validate argument on parameter 'Task'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

                            At C:\PowerCLI\update_vram_poweroff_snapshot-Copy.ps1:53 char:15

                            +     Wait-Task $shutvmtask

                            +               ~~~~~~~~~~~

                                + CategoryInfo          : InvalidData: (:) [Wait-Task], ParameterBindingValidationException

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

                             

                            Snapshot of VM1 is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task...

                            Snapshot of VM2 is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task...

                            Wait-Task : Cannot validate argument on parameter 'Task'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

                            At C:\PowerCLI\update_vram_poweroff_snapshot-Copy.ps1:62 char:15

                            +     Wait-Task $snapshotvmtask

                            +               ~~~~~~~~~~~~~~~

                                + CategoryInfo          : InvalidData: (:) [Wait-Task], ParameterBindingValidationException

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

                             

                            Video Memory on VM: VM1 has been successfully set to 9000

                            Wait-Task : Cannot validate argument on parameter 'Task'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

                            At C:\PowerCLI\update_vram_poweroff_snapshot-Copy.ps1:85 char:19

                            +         Wait-Task $vramconfigtask

                            +                   ~~~~~~~~~~~~~~~

                                + CategoryInfo          : InvalidData: (:) [Wait-Task], ParameterBindingValidationException

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

                             

                            The scrript will wait for the configuration task to be complete before the VMs are powered on

                            Video Memory on VM: VM2 has been successfully set to 9000

                            Wait-Task : Cannot validate argument on parameter 'Task'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

                            At C:\PowerCLI\update_vram_poweroff_snapshot-Copy.ps1:85 char:19

                            +         Wait-Task $vramconfigtask

                            +                   ~~~~~~~~~~~~~~~

                                + CategoryInfo          : InvalidData: (:) [Wait-Task], ParameterBindingValidationException

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

                             

                            The scrript will wait for the configuration task to be complete before the VMs are powered on

                            VM1 is now being powered on. Please wait five to ten minutes before verifying new configuration

                            VM2 is now being powered on. Please wait five to ten minutes before verifying new configuration

                            • 11. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                              LucD Guru
                              User ModeratorsvExpertCommunity Warriors

                              The issue is most likely because you the VirtualMachine in the hash table (with the Key of the TakId).

                              But such a VirtualMachine object is not updated automatically.

                              You will for example not see that the powerstate of the VM has changed.

                              For that you have to 'refresh' the object, by doing a new Get-VM.

                               

                              Something like this

                               

                              $newVideoRamSize = 9000

                              $vmlist = Import-Csv .\vmlist.csv -UseCulture

                              $vmlist1 = $vmlist | select -ExpandProperty VM

                              $taskTab = @{ }

                               

                               

                              #Shutdown VMs

                              foreach ($vm in $vmlist1) {

                                  #if($vm.Powerstate -eq "PoweredOn") { //FYI If this part is not commented out, the script will run without doing anything.

                                  Write-Host $vm is now being powered off. The script will confirm all VMs are powered off before proceeding to the next task... -foregroundcolor green

                                  $taskTab[(Stop-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

                              }

                              #}

                               

                               

                              #Take snapshot of VMs

                              $runningTasks = $taskTab.Count

                              while ($runningTasks -gt 0) {

                                  Get-Task | % {

                                      if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                          $vm = Get-VM $taskTab[$_.Id]

                                          Write-Host "Snapshot of $($vm.Name) is being taken before configuration change. The script will confirm all VM snapshots are complete before proceeding to the next task..." -foregroundcolor green

                                          $tasktab[(New-Snapshot -VM $vm -Name BeforeVideoRamChange -RunAsync).Id] = $vm

                                          $taskTab.Remove($_.Id)

                                          $runningTasks--

                                      }

                                      elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                          $taskTab.Remove($_.Id)

                                          $runningTasks--

                                      }

                                  }

                                  Start-Sleep -Seconds 15

                               

                                  #Update Video Ram

                                  $runningTasks = $taskTab.Count

                                  while ($runningTasks -gt 0) {

                                      Get-Task | % {

                                          if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                              $vm = Get-VM -Name ($taskTab[$_.Id]).Name

                                              if ($vm.Powerstate -eq "PoweredOn") {

                                                  return "One or more VMs is still powered on. Manually power off VMs before re-attempting."

                                              }

                               

                                              $vid = $vm.ExtensionData.Config.Hardware.Device | ? { $_.GetType().Name -eq "VirtualMachineVideoCard" }

                                              $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

                                              $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

                                              $devChange.Operation = 'edit'

                                              $vid.videoRamSizeInKB = $newVideoRamSize

                                   

                                              if ((!$devChange.Operation) -or (!$vid.videoRamSizeInKB)){

                                                  return "ERROR: Unable to set video memory on $taskTab[$_.Id]}. Ensure it is powered off."

                                              }

                               

                                              Write-Host Video Memory on VM: $taskTab[$_.Id] has been successfully set to $vid.videoRamSizeInKB -foregroundcolor green

                                   

                                              $devChange.Device += $vid

                                              $spec.DeviceChange += $devChange

                                              $vm.ExtensionData.ReconfigVM($spec)

                                              $taskTab.Remove($_.Id)

                                              $runningTasks--

                                          }

                                          elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                              $taskTab.Remove($_.Id)

                                              $runningTasks--

                                          }

                                          Start-Sleep -Seconds 15

                               

                                          Write-Host The script will wait for the configuration task to be complete before the VMs are powered on -foregroundcolor green

                                      }

                                  }

                               

                               

                                  #Power on VMs

                                  $runningTasks = $taskTab.Count

                                  while ($runningTasks -gt 0) {

                                      Get-Task | % {

                                          if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                              $vm = Get-VM -Name (Get-VM $taskTab[$_.Id]).Name

                                              if ($vm.Powerstate -eq "PoweredOff") {

                                                  Write-Host "$($vm.Name) is now being powered on. Please wait five to ten minutes before verifying new configuration" -foregroundcolor green

                                                  $taskTab[(Start-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

                                              }

                                          }

                                      }

                                  }

                              }

                              • 12. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                                BBB36 Novice

                                Thanks. I updated the script but unfortunately it's the same result as before,i.e. "The script will wait for the configuration task to be complete before the VMs are powered on" and doesn't progress to update the video ram and start up the VMs.

                                I'll go through the script again more carefully and post results later today or tomorrow. Thank you so much for all your time!

                                • 13. Re: Update Video Ram. Wait for task to complete before proceeding to next action.
                                  BBB36 Novice

                                  Hey LucD, I made some modifications. Now the script works. I had to however remove some of the "tasktab" and error control portions in the #Shutdown VMs and #Power on VMs sections of the script for it to work. I'm sure I'm just missing something small but I needed to get this working ASAP and also don't have the knowledge yet to fix it quickly. Anyway, here's the final script. If you or anyone else can enhance it that would be greatly appreciated! Thanks so much for all your help!

                                  ******************************************************************************************************************************************************************************

                                  $newVideoRamSize = 9000

                                  $vmlist = Import-Csv .\vmlist.csv -UseCulture

                                  $vmlist1 = $vmlist | select -ExpandProperty VM

                                  $taskTab = @{ }

                                   

                                  #Shutdown VMs

                                  foreach ($vm in $vmlist1) {

                                      Write-Host $vm will shutdown in preparation for the Video Ram configuration change. -foregroundcolor green

                                      $taskTab[(Stop-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

                                  }

                                   

                                  Start-Sleep -Seconds 30

                                   

                                  #Take snapshot of VMs

                                  $runningTasks = $taskTab.Count

                                  while ($runningTasks -gt 0) {

                                     Get-Task | % {

                                        if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                           $vm = Get-VM $taskTab[$_.Id]

                                           Write-Host $vm snapshot is being taken before the configuration change should a rollback be necessary. -foregroundcolor green

                                           $tasktab[(New-Snapshot -VM $taskTab[$_.Id] -Name BeforeVideoRamChange -RunAsync).Id] = $vm

                                           $taskTab.Remove($_.Id)

                                           $runningTasks--

                                         }

                                          elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                          $taskTab.Remove($_.Id)

                                          $runningTasks--

                                         }

                                      }

                                    }

                                   

                                  Start-Sleep -Seconds 30

                                   

                                  #Update Video Ram

                                  foreach ($vm in $vmlist1) {

                                  $runningTasks = $taskTab.Count

                                  while ($runningTasks -gt 0) {

                                     Get-Task | % {

                                         if ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success") {

                                            $vm = Get-VM ($taskTab[$_.Id]).Name

                                               if ($vm.Powerstate -eq "PoweredOn") {

                                               return "$vm is still powered on. Manually power off VMs before re-attempting."

                                         }

                                            $vid = $vm.ExtensionData.Config.Hardware.Device | ? { $_.GetType().Name -eq "VirtualMachineVideoCard" }

                                            $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

                                            $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

                                            $devChange.Operation = 'edit'

                                            $vid.videoRamSizeInKB = $newVideoRamSize

                                   

                                            if ((!$devChange.Operation) -or (!$vid.videoRamSizeInKB)){

                                            return "ERROR: Unable to set video memory on $($vm.Name). Ensure it is powered off."

                                         }

                                            Write-Host $($vm.Name) video memory has been successfully set to $newVideoRamSize -foregroundcolor green

                                   

                                            $devChange.Device += $vid

                                            $spec.DeviceChange += $devChange

                                            $vm.ExtensionData.ReconfigVM($spec)

                                            $taskTab.Remove($_.Id)

                                            $runningTasks--

                                         }

                                            elseif ($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error") {

                                            $taskTab.Remove($_.Id)

                                            $runningTasks--

                                         }

                                       }

                                     }

                                  }

                                   

                                  Start-Sleep -Seconds 30

                                   

                                  #Power on VMs

                                  foreach ($vm in $vmlist1) {

                                      Write-Host $vm is being powered back on. -foregroundcolor green

                                      $taskTab[(Start-VM -VM $vm -Confirm:$false -RunAsync).Id] = $vm

                                  }

                                   

                                  Start-Sleep -Seconds 30

                                   

                                  Write-Host Configuration complete. Confirm new change in 5 to 10 minutes. -foregroundcolor green