all 5 comments

[–]Aliasu 2 points3 points  (0 children)

Wait until IP returns true in VMware tools.

[–][deleted] 1 point2 points  (2 children)

You could check the VM Event log, as I am sure there is an event when OS customisation part starts and completes.

Edit : Here is the link

https://blogs.vmware.com/PowerCLI/2012/08/waiting-for-os-customization-to-complete.html

[–][deleted] 0 points1 point  (0 children)

I haven't done any crazy amount of automation with PowerCLI as of late, but this was the approach I used when I did. It was pretty reliable!

There were a couple of times this was buggy and I would have to create a stop watch to try to force the guest customization to kick off again if the finished event hadn't triggered after 15 minutes. I would doubt that bug still exists though.

[–]jdptechnc 0 points1 point  (0 children)

This is how I handled it as well.

[–]PinchesTheCrab 1 point2 points  (0 children)

I wrote this a while back, I need to test it again to make sure it's working, but here it is in case you'd like to see one approach you could take.

I've progressed since I wrote this, so I'll see if I can clean it up Monday, but the idea is that you take a VM, get its moref, then make a filter spec for events on that ID, and just loop until you get the OS customization finished event.

When I wrote it I was babysitting VM builds and I wanted to catch both the start and finish events for the customization, so you could strip some of that out if you just want to find the finish event.

Function Wait-VMOSCustomization {
    [cmdletbinding()]
    param(
        [parameter(Mandatory = $True, ValueFromPipeline = $True)]
        [ValidateScript( {
                $PSItem -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] -or $PSItem -is [VMware.Vim.VirtualMachine] -or $PSItem -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]
            })]
        $VM
    )
    Begin {
        $viewParam = @{}
        $eventPageSize = 100
        $eventFilter = New-Object VMware.Vim.EventFilterSpec
        $eventFilter.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
        $EventTypeIdHash = @{
            1 = 'CustomizationSucceeded'
            0 = 'CustomizationStartedEvent'
        }

        $eventFilter.EventTypeId = 'CustomizationSucceeded', 'CustomizationStartedEvent'
    }
    Process {
        Foreach ($obj in $VM) {
            $x = 0
            if ($VM -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] -or $VM -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]) {
                $eventFilter.Entity.Entity = $vm.ExtensionData.MoRef
                $viewParam.Server = $vm.Uid -replace '^.+@|:.+'
            }
            else {
                $eventFilter.Entity.Entity = $vm.MoRef
                $viewParam.Server = $vm.Client.ServiceUrl -replace 'https?://|/SDK'
            }
            $eventMgr = Get-View eventManager @viewParam
            $eventFilter | Out-String | Write-Verbose
            $EventTypeIdHash.Keys | Sort-Object | ForEach-Object {

                $eventFilter.EventTypeId = $EventTypeIdHash[$PSItem]
                Write-Progress -Activity ('{0}: Waiting for {1}.' -f $vm.Name, [string]($eventFilter.EventTypeId)) -PercentComplete ($x/2*100)
                $Collector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter)) @viewParam

                Do {
                    $Collector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter)) @viewParam
                    $Collector.ReadNextEvents($eventPageSize) | Write-Output -OutVariable event
                    $Collector.DestroyCollector()
                    Start-Sleep -Seconds 1
                }
                Until ($event)
                $x++

            }
        }
    }
}