Currently I have two objects, one is $allVMs and has 1500 records
vmip : 10.x.x.x
hypervisorhost : xxxxx.yyyyyyyyyy.lan
cluster : zzzzzzzzzz
manager : aaaaaaa
bladenaam : empty
domainnaam : empty
natip : empty
and another object $allBlades which has 500 records.
domain : dom01
name : name01
pndn : pndn01
I for each $vm in $allVMs, I have to search the corresponding blade in $allBlades and when found add name and domain from that blade to the $vm.domain and $vm.name.
Currently I just created a loop on $allVMs and per VM I do a "select-object | where" in $allBlades. It takes quite some time to go through the loop, about an hour. Is there a faster way?
foreach( $VM in $AllVMs)
{
if( $null -ne $vm.vmnaam)
{
$Hostname = $($vm.hypervisorhost).split(".")[0]
$FoundBlade = $AlleBlades | Where-Object {$_.name -match $hostname }
if ($null -eq $FoundBlade)
{
write-host "Blade $($vm.hypervisorhost) not found"
}
else
{
$vm.bladenaam = $FoundBlade.name
$vm.domainnaam = $FoundBlade.domain
}
}
}
Use a hash-based search (any IDictionary
implementing type, most commonly used in PowerShell for this kind of task is hash table @{}
) instead of linear search (Where-Object
):
$bladesMap = @{}
foreach ($item in $AlleBlades) {
$bladesMap[$item.name] = $item
}
foreach ($VM in $AllVMs) {
if ($null -ne $vm.vmnaam) {
$Hostname = $vm.hypervisorhost.Split('.')[0]
if (-not $bladesMap.ContainsKey($Hostname)) {
Write-Host "Blade $($vm.hypervisorhost) not found"
}
else {
$item = $bladesMap[$Hostname]
$vm.bladenaam = $item.name
$vm.domainnaam = $item.domain
}
}
}