12 Replies Latest reply on Sep 24, 2020 9:09 AM by LucD

    Combine 3 x scripts with a foreach?

    frased Novice

      Hello all,

      These all work individually.  I'd like to have 1 script that does all of this.   

       

      My ultimate goal would be to combine these 3 in this order: 

      1. VMtools first with no reboot.
      2. Time settings advance parameters add no reboot. 
      3. Upgrade HW flag w/reboot. 

       

      The reboot at the end would finalize everything.  Instead of multiple reboots with separate scripts. 

       

      Again all 3 of these work separately.  But I have to manually reboot.  And there's no for each loop on the time sync script.

        • 1. Re: Combine 3 x scripts with a foreach?
          LucD Guru
          Community WarriorsUser ModeratorsvExpert

          Try something like this.
          The Guest OS is rebooted at the end.

           

          $ExtraValues = @{

              "tools.syncTime"=0;

              "time.synchronize.continue"=0;

              "time.synchronize.restore"=0;

              "time.synchronize.resume.disk"=0;

              "time.synchronize.shrink"=0;

              "time.synchronize.tools.startup"=0;

              "time.synchronize.tools.enable"=0;

              "time.synchronize.resume.host"=0

          }


          $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec


          $ExtraValues.GetEnumerator() | %{ 

              $extra = New-Object VMware.Vim.optionvalue

              $extra.Key=$_.Key

              $extra.Value=$_.Value

              $vmConfigSpec.extraconfig += $extra

          }


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

          $vmConfigSpec.ScheduledHardwareUpgradeInfo.UpgradePolicy = “always”

          $vmConfigSpec.ScheduledHardwareUpgradeInfo.VersionKey = “vmx-13

           

          Get-Datacenter -name Testing | Get-Folder -name "Testing" |

          Get-Vm -PipelineVariable vm |

          ForEach-Object -Process {

              # Script 2

              if($vm.ExtensionData.Guest.ToolsVersionStatus2 -eq [VMware.Vim.VirtualMachineToolsVersionStatus]::guestToolsNeedUpgrade){

                  Update-Tools -NoReboot -VM $vm

              }      


              # Script 1 + 3

              $vm.ExtensionData.ReconfigVM($vmConfigSpec)


              Restart-VMGuest -VM $vm -Confirm:$false

          }

           

          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          1 person found this helpful
          • 2. Re: Combine 3 x scripts with a foreach?
            frased Novice

            I finally got around to testing this!  Phew what a week.  Anyway it appears the VMtools upgrade part is not kicking off.  I threw a pause in between and it still isn't kicking off tools upgrade.  Hmmmm. 

            • 3. Re: Combine 3 x scripts with a foreach?
              LucD Guru
              Community WarriorsUser ModeratorsvExpert

              Did you check that the ToolsVersionStatus2 actually says that an upgrade is needed?

              Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
              1 person found this helpful
              • 4. Re: Combine 3 x scripts with a foreach?
                frased Novice

                Hi LucD thanks again for your help on this. Just wondering...  how would I query a Datacenter in vCenter to tell me if any VMs are missing the following parameters?

                 

                $ExtraValues = @{

                "tools.syncTime"=0;

                "time.synchronize.continue"=0;

                "time.synchronize.restore"=0;

                "time.synchronize.resume.disk"=0;

                "time.synchronize.shrink"=0;

                "time.synchronize.tools.startup"=0;

                "time.synchronize.tools.enable"=0;

                "time.synchronize.resume.host"=0 }

                • 5. Re: Combine 3 x scripts with a foreach?
                  LucD Guru
                  User ModeratorsCommunity WarriorsvExpert

                  Did the VMware Tools upgrade part work after all?

                  Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                  • 6. Re: Combine 3 x scripts with a foreach?
                    frased Novice

                    Yes thank you again sir!  It worked excellent.  Although for some reason I wasn't successful at combining the Tools script with the 2 x part HW update one.  They work great separately. 

                     

                    Still working through the 1k VM upgrades though.  About half done.  Change controls etc. 

                     

                    During the cleanup phase I'm looking to run a query to see if any VMs are "missing" the time sync parameters.  That way I can update any stragglers. 

                    • 7. Re: Combine 3 x scripts with a foreach?
                      LucD Guru
                      vExpertUser ModeratorsCommunity Warriors

                      You could do something like this

                       

                      $dcName = 'MyDC'

                      $ExtraValues = @{

                          "tools.syncTime"=0

                          "time.synchronize.continue"=0

                          "time.synchronize.restore"=0

                          "time.synchronize.resume.disk"=0

                          "time.synchronize.shrink"=0

                          "time.synchronize.tools.startup"=0

                          "time.synchronize.tools.enable"=0

                          "time.synchronize.resume.host"=0

                      }


                      Get-Datacenter -Name $dcName | Get-VM -PipelineVariable vm |

                      ForEach-Object -Process {

                          $obj = [ordered]@{

                              VM = $vm.Name

                          }

                          $ExtraValues.Keys | ForEach-Object -Process {

                              $obj.Add($_,'missing')

                          }


                          Get-AdvancedSetting -Entity $vm -Name @($ExtraValues.Keys) -PipelineVariable setting |

                          ForEach-Object -Process {

                              if($setting.Value -eq $ExtraValues[$setting.Name]){

                                  $obj[$setting.Name] = 'ok'

                              }

                              else{

                                  $obj[$setting.Name] = $setting.Value

                              }

                          }

                          New-Object -TypeName PSObject -Property $obj

                      }

                      Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                      1 person found this helpful
                      • 8. Re: Combine 3 x scripts with a foreach?
                        frased Novice

                        Thanks LucD.  Does this modify/add the values if missing?  Looking to just create a list of ones that have it missing.  This way I can plan a change control event with my master list of stragglers. 

                        • 9. Re: Combine 3 x scripts with a foreach?
                          LucD Guru
                          Community WarriorsUser ModeratorsvExpert

                          No, this snippet answered your "... run a query to see if any VMs are "missing" the time sync parameters" questoin.

                          You could run this after the 1st script that does the actual changes

                          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                          1 person found this helpful
                          • 10. Re: Combine 3 x scripts with a foreach?
                            frased Novice

                            Awesome thanks again!

                            • 11. Re: Combine 3 x scripts with a foreach?
                              frased Novice

                              How would I add only "powered on" VMs to this?

                               

                              Works excellent. 

                              • 12. Re: Combine 3 x scripts with a foreach?
                                LucD Guru
                                vExpertUser ModeratorsCommunity Warriors

                                You can use a Where-clause for that

                                 

                                Get-Datacenter -Name $dcName | Get-VM -PipelineVariable vm |

                                where{$_.PowerState -eq 'PoweredOn'} |

                                ForEach-Object -Process {

                                Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                                1 person found this helpful