VMware Cloud Community
Munster99
Enthusiast
Enthusiast

Help with an Advanced Function -

Dear one and all

Having messed around with Powercli for some time now I've started to slowly move into the realms of script writing using 'Advanced Functions'. One of the main reasons was I like the way functions act more like cmdlets and hence I thought I'd give it a shot and write one to help me update the 'virtual hardware' versions of my VMs to its latest (v10). Now I would like to point out that my script DOES WORK. However, once you look at it you will realise its REALLY SLOW. Thats the failure on my part as I've created a foreach loop which simply goes through each VM 'asynchronously'. (i.e. one after the other) and obviously doing this on hundreds of VMs can be quite time consuming! Smiley Sad. This is where I need some help. Could you supply me with some 'pointers' as to a way where I might be able to batch say '20' VMs at a time ??? . This would save loads of time on my part. and allow my function to run a lot more efficiently.

As always many thanks in advance

Munster

Function Update-VirtualHardware {

<#

    .SYNOPSIS

    This will update the Virtual Hardware to v10 for Virtual machines

    .DESCRIPTION

    This function shuts down the VM, Updates its virtual hardware and finally Powers the

    VM back on

    .PARAMETER VMName

    A VM object is required

    .INPUTS

    Input Object Type = [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl]

    .EXAMPLE

    Update-VirtualHardware -VMname (get-VM -VM VM1)

#>

[CmdletBinding()]

    PARAM

    (

    [Parameter(Mandatory=$true,

               ValueFromPipeline=$true,

               ValueFromPipelineByPropertyName=$true,

               HelpMessage = "Please enter a VM Object",

               Position=0)]

    [ValidateNotNullOrEmpty()]

    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VMName,

    [Parameter()]                           

    [string]$ErrorLogFilePath = "C:\Errors.txt",   

    [Parameter()]

    [switch]$LogErrors           

    )   

    BEGIN {

    Write-Verbose "Error log will be $ErrorLogFilePath"   

    Del $ErrorLogFilePath -ErrorAction SilentlyContinue  

    }

    PROCESS {

        Foreach ($VM in $VMName){

                        

            if (($VM.PowerState -eq "PoweredOn") -and ($VM._VMToolsRunningStatus -eq "guestToolsRunning") -and ($VM.Version -ne "v10")) { 

                Write-Verbose "Shutting Down $VM"

                $vm | Shutdown-VMGuest -Confirm:$false | Out-Null

                #Wait for Shutdown to complete

                do {

                   #Wait 5 seconds

                   Start-Sleep -s 5

                   #Check the power status

                   $vm = Get-VM -Name $vm

                   $status = $vm.PowerState

                }until($status -eq "PoweredOff")

               

                    Try{

                    # UPGRADING THE VM

                    Write-Verbose "UPGRADING $VM"

                    Set-VM -VM $VM -Version v10 -confirm:$false -ErrorAction Stop | Out-Null

                    # POWERING ON THE VM             

                    Write-Verbose "POWERING ON $VM"

                    $vm | Start-VM -Confirm:$false | Out-Null

                    }

                    Catch{

                    Write-Warning "$VM Failed to upgrade - logging ComputerName to $ErrorLogFilePath"                

                    $VM.name | Out-File $ErrorLogFilePath -Append        # append to the Errors logfile

                    }

             }

             elseif (($VM._VMToolsRunningStatus -ne "guestToolsRunning") -or ($VM.Version -eq "v10")) {

                Write-Verbose "$vm VM Tools are NOT running or it is already at v10"

                $VM.name | Out-File $ErrorLogFilePath -Append        # append to the Errors logfile 

             }

         

        }

    }

    END { }

   

}

Reply
0 Kudos
1 Reply
LucD
Leadership
Leadership

One option would be to fire off the actions with a Start-Job, that way they will run in the background.

An other option is to use a Workflow which also allows parallelism.


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

Reply
0 Kudos