Search code examples
powershellworkflowpowercli

Duplicates in Workflow VM audit


I'm implementing a VM audit of several vcenters (around 5 of them) where the report is simply a csv of each VM along with a few properties. Although this script would run overnight, I found that it took around 5-6 hours to complete and wanted to increase its efficiency. I learned about workflows and figured it would be faster to audit each vcenter at the same time instead of one by one. It was slower than I expected finishing after about 4 hours. I noticed that there were many duplicates in the data and I can't figure out why that would be; maybe my ideas about how workflow works is flawed. I'm also looking for any tips on raising efficiency in my code. Thanks in advance.

The workflow:

workflow test {

param([string[]]$vcenters, [string]$session, [string]$username, [string]$password)

foreach -parallel($vcenter in $vcenters){
$main = InlineScript{
    Add-PSSnapin VMware.VimAutomation.Core
    Connect-VIServer -Server $Using:vcenter -User $Using:username -Password $Using:password 
    $vms = Get-View -ViewType VirtualMachine -Property Name, Summary.Config.GuestFullName, Runtime.Powerstate, Config.Hardware.MemoryMB, Config.Hardware.NumCPU
    ForEach($machine in $vms){
        $vm = Get-VM -Server $Using:vcenter -Name $machine.Name -ErrorAction SilentlyContinue
        $object = New-Object -Type PSObject -Property ([ordered]@{
            Name = $machine.Name
            GuestOS = $machine.Summary.Config.GuestFullName
            PowerState = $machine.Runtime.PowerState
            MemoryGB = ($machine.Config.Hardware.MemoryMB / 1024)
            CPU = $machine.Config.Hardware.NumCPU
            VLAN=(Get-NetworkAdapter -VM $vm |Sort-Object NetworkName |Select -Unique -Expand NetworkName) -join '; '
        })
        $object| Export-Csv -Append “C:\TestReports\$($vcenter)_TestReport.csv” -NoTypeInformation
    }
    Disconnect-VIServer - $Using:vcenter  -Confirm:$false
    }
}
}

Solution

  • With the below changes, maybe it runs quickly enough that you no longer need parallelism or workflow. Not sure if those elements are a cause of the duplication problem. If not, you might need to share more details from your environment for help with that piece.

    Get-VM is slow. You're calling it once for each VM, and I don't think you need it at all. Try adding this line after connecting to vCenter

    $networks = Get-View -ViewType Network
    

    Replacing your VLAN= line with

    VLAN= $networks | ? {$_.VM.Value -contains $machine.MoRef.value} | select -exp Name
    

    And dropping your $vm = Get-VM... line entirely.