I've got a bunch of vCenter servers to manage, and I've been getting a lot of requests to find a particular VM based on its name. I wrote a quick little function to do this, but it's taking longer than I'd like to run - about 30 seconds, or closer to 90 seconds if I use the one where I pull backup info from Veeam (the Veeam plugin is slow, though). It just takes input as a string, so it'll return either a single server or a list of servers, if the inventory name(s) matches the input parameter.
Does anyone have any ideas to maybe help speed this script up some?
function Get-VMInfo {
param ( [string]$vmToFind )
$vmReport = @()
$vmListObj = Get-View -ViewType VirtualMachine | Where {$_.Name -match $vmToFind}
foreach ($vm in $vmListObj)
{
$vcInfo = Get-VM $vm.Name | Select @{N="vCenter";E={$_.Uid.Split('@')[1].Split(':')[0]}}
$hostInfo = Get-View -Id $vm.Runtime.Host -Property "Name","Parent"
$clusterInfo = Get-View -Id $hostInfo.Parent -Property "Name","Parent"
$vmInfo = [PSCustomObject][Ordered] @{
Name = $vm.Name
PowerState = $vm.Runtime.PowerState
IPv4 = $vm.Guest.Net.IPAddress | Where-Object { $_ -NotMatch ":"}
vCenter = $vcInfo.vCenter
Host = $hostInfo.Name
Cluster = $clusterInfo.Name
}
$vmReport += $vmInfo
}
return $vmReport
}
This will return something like:
Name : VM2
PowerState : poweredOn
IPv4 : xxx.xxx.xxx.xxx
vCenter : vc01.homelab.local
Host : ESXi01.homelab.local
Cluster : VSAN Test Cluster
Thanks!
Message was edited by: Christopher Kersten
Try this version.
param ( [string]$vmToFind )
$sView = @{
ViewType = 'VirtualMachine'
Property = 'Name','Runtime.PowerState','Guest.Net','Runtime.Host'
Filter = @{'Name'=$vmToFind}
}
Get-View @sView |
ForEach-Object -Process {
[PSCustomObject][Ordered] @{
Name = $_.Name
PowerState = $_.Runtime.PowerState
IPv4 = $_.Guest.Net.IPAddress.Where{$_ -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"} -join '|'
vCenter = ([uri]$_.Client.ServiceUrl).Host
Host = &{
$script:esx = Get-View -Id $_.Runtime.Host -Property 'Name','Parent'
$script:esx.Name
}
Cluster = (Get-View -Id $script:esx.Parent -Property Name).Name
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try this version.
param ( [string]$vmToFind )
$sView = @{
ViewType = 'VirtualMachine'
Property = 'Name','Runtime.PowerState','Guest.Net','Runtime.Host'
Filter = @{'Name'=$vmToFind}
}
Get-View @sView |
ForEach-Object -Process {
[PSCustomObject][Ordered] @{
Name = $_.Name
PowerState = $_.Runtime.PowerState
IPv4 = $_.Guest.Net.IPAddress.Where{$_ -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"} -join '|'
vCenter = ([uri]$_.Client.ServiceUrl).Host
Host = &{
$script:esx = Get-View -Id $_.Runtime.Host -Property 'Name','Parent'
$script:esx.Name
}
Cluster = (Get-View -Id $script:esx.Parent -Property Name).Name
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Wow. Runtime goes from about 30 seconds to 0.3 seconds. I guess now I need to spend some time figuring out how it works. I'm still new to Get-View and don't really understand how it works yet.
Thanks for the assist, and the new code to chew on.
Have a look at the script and when you are not sure why some code is in there, feel free to ask.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference