Automation

 View Only
Expand all | Collapse all

Combine 3 x scripts with a foreach?

  • 1.  Combine 3 x scripts with a foreach?

    Posted Jun 16, 2020 05:53 PM

    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.



  • 2.  RE: Combine 3 x scripts with a foreach?

    Posted Jun 16, 2020 06:48 PM

    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

    }



  • 3.  RE: Combine 3 x scripts with a foreach?

    Posted Jun 27, 2020 02:10 AM

    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. 



  • 4.  RE: Combine 3 x scripts with a foreach?

    Posted Jun 27, 2020 05:10 AM

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



  • 5.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 21, 2020 10:16 PM

    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 }



  • 6.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 22, 2020 06:13 AM

    Did the VMware Tools upgrade part work after all?



  • 7.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 22, 2020 11:27 AM

    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. 



  • 8.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 22, 2020 12:06 PM

    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

    }



  • 9.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 24, 2020 03:29 PM

    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. 



  • 10.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 24, 2020 03:32 PM

    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



  • 11.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 24, 2020 03:37 PM

    Awesome thanks again!



  • 12.  RE: Combine 3 x scripts with a foreach?

    Posted Sep 24, 2020 03:42 PM

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

    Works excellent. 



  • 13.  RE: Combine 3 x scripts with a foreach?
    Best Answer

    Posted Sep 24, 2020 04:10 PM

    You can use a Where-clause for that

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

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

    ForEach-Object -Process {