Improving the Speed of a script using Get-View

Working in an enterprise environment with a large number of virtual centers presents a number of problems. Where is the VM hosted?

This challenge led to some thinking and as we had previously delivered a utility scripting server, it seemed like a good idea to enable IIS, and host some freely available searchable web pages.

I then built a central location to host the output (a simple IIS server will suffice), then we created a list of virtual centers that needed to be contacted and put this in a text file, then it was simply a question cycling through each VC and appending the information to the end of the HTML file.

  • Each virtual center was then queried with the following script (with help from the VMware communities).
## for environments older that v4.0 (older API)
Get-View -ViewType ClusterComputeResource -Property Name | %{
    ## store this cluster in a variable for later use
    $viewThisCluster = $_
    Get-View -ViewType HostSystem -SearchRoot $viewThisCluster.MoRef -Property Name | %{
        ## store this host in a variable for later use
        $viewThisHost = $_
        ## get the .Net View object for all VMs (not templates) and return a bit of info for each; add info to the Report array
        Get-View -ViewType VirtualMachine -SearchRoot $viewThisHost.MoRef -Property Name, Guest.HostName, Config.Hardware.NumCPU, Config.Hardware.MemoryMB, Config.Hardware.Device, Guest.IPAddress, Runtime.PowerState, Config.DatastoreUrl -Filter @{"Config.Template" = "False"} | %{
            $Report += Select -InputObject $_ Name,
                @{N="DNS";E={$_.Guest.Hostname}},
                @{N="NumCPU"; E={$_.Config.Hardware.NumCPU}},
                @{N="MemoryMB"; E={$_.Config.Hardware.MemoryMB}},
                @{N="DiskGB";E={[Math]::Round((($_.Config.Hardware.Device | ?{$_ -is [VMware.Vim.VirtualDisk]} | Measure-Object -Property CapacityInKB -Sum).Sum / 1mb),2)}},
                @{N="IP Address";E={@($_.Guest.IPAddress)[0]}},
                @{N="State";E={$_.Runtime.PowerState}},
                @{N="VM VC";E={$VISRV}},
                @{N="Cluster";E={$viewThisCluster.Name}},
                @{N="ESX Host";E={$viewThisHost.Name}},
                @{N="Datastore";E={@($_.Config.DatastoreUrl | %{$_.Name})}},
                @{N="VM URL";E={"<a href=https://$VISRV/ui/vmDirect.do?view=" + ($URLVM = ($SdkUrlB64 = [System.Convert]::ToBase64String(([System.Text.Encoding]::ASCII.GetBytes("wsUrl=http://localhost/sdk&vmId=VirtualMachine|" + $_.MoRef.Value + "&ui=33")))) + "_") + ">$($_.Name)</a>"}}
        } ## end foreach-object
    } ## end Get-View for hosts
} ## end Get-View for Clusters
  • For newer environments (vSphere 4+) we used:

$Report = @()

Foreach ($VISRV in $VISRVs) {
if ($VISRV.contains($ProdDom))
{Connect-VIServer -Server $VISRV -user $UserProd -pass $PassProd}
else
{Connect-VIServer -Server $VISRV -user $UserLabs -pass $PassLabs}

Get-View -ViewType ClusterComputeResource -Property Name | %{
## store this cluster in a variable for later use
$viewThisCluster = $_
Get-View -ViewType HostSystem -SearchRoot $viewThisCluster.MoRef -Property Name | %{
## store this host in a variable for later use
$viewThisHost = $_
## get the .Net View object for all VMs (not templates) and return a bit of info for each; add info to the Report array
Get-View -ViewType VirtualMachine -SearchRoot $viewThisHost.MoRef -Property Name, Guest.HostName, Config.Hardware.NumCPU, Config.Hardware.MemoryMB, Summary.Storage.Committed, Guest.IPAddress, Runtime.PowerState, Config.DatastoreUrl -Filter @{“Config.Template” = “False”} | %{
$Report += Select -InputObject $_ Name,
@{N=”DNS”;E={$_.Guest.Hostname}},
@{N=”NumCPU”; E={$_.Config.Hardware.NumCPU}},
@{N=”MemoryMB”; E={$_.Config.Hardware.MemoryMB}},
@{N=”DiskGB”;E={[Math]::Round(($_.Summary.Storage.Committed / 1GB),2)}},
@{N=”IP Address”;E={$_.Guest.IPAddress[0]}},
@{N=”State”;E={$_.Runtime.PowerState}},
@{N=”VM VC”;E={$VISRV}},
@{N=”Cluster”;E={$viewThisCluster.Name}},
@{N=”ESX Host”;E={$viewThisHost.Name}},
@{N=”Datastore”;E={@($_.Config.DatastoreUrl | %{$_.Name})}},
@{N=”VM URL”;E={“<a href=https://$VISRV/ui/vmDirect.do?view=” + ($URLVM = ($SdkUrlB64 = [System.Convert]::ToBase64String(([System.Text.Encoding]::ASCII.GetBytes(“wsUrl=http://localhost/sdk&vmId=VirtualMachine|” + $_.MoRef.Value + “&ui=33”)))) + “_”) + “>$($_.Name)</a>”}}
} ## end foreach-object
} ## end Get-View for hosts
} ## end Get-View for Clusters

Disconnect-VIServer -Server $VISRV -Confirm:$false
}

($Report  | Convertto-Html -head $head -body $body -title $title -PostContent $postcont) -replace ‘&lt;’, “<” -replace ‘&gt;’, “>” -replace ‘<table>’, $tableout  | Out-File “$fileloc\$file”)

Now the code will return a list of VMs, there associated VC, a console link to the VM, and other quick reference data in a simple HTML format.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s