I have 3 nested loops and they do the following:
- Get scopes from DHCP
- Get hostnames from csv file
- Compares hostnames and leases, matches are added to a hash table
There are 5 DHCP servers, 100's of scopes and thousands of leases.
What would be a good method to speed this up?
$DHServers = Get-DhcpServerInDC #get DHCP info
$hashtable = @{} #create hash table
foreach ($server in $DHServers){
$scopes = Get-DHCPServerv4Scope -ComputerName $server.dnsname #get all scopes in DHCP
foreach ($_ in (Import-Csv C:\script\Asset_List.csv | Select-Object -ExpandProperty asset)){ #get hostnames from list
foreach ($scope in $scopes){
if($scope | Get-DhcpServerV4Lease -ComputerName $server.dnsname | Where-Object HostName -like "$_*" ){ #compares the hostname to find which lease it is in
$scopename=$scope.name #matches give scope name
$hashtable[$_] = $scopename #when a match is found, add keys and values to table
}
}
}
}
1 Answer 1
Piping the DHCP calls through foreach-object
instead and then comparing at the end, cut the time down from 3min to 1min. Everything I have read made it seem like foreach
was faster. Having DHCP being processed down the pipe with foreach-object
instead of several iterations with foreach
makes foreach-objects
more efficient.
$servers = Get-DHCPServerInDC
$hashtable = @{}
# scopes into the leases to go into the PsCustomObject to be matched later
$leases = $servers | ForEach-Object {
$server = $_.dnsname
Get-DHCPServerv4Scope -computerName $server #get scopes on DHCP serves
} | ForEach-Object {
$scope = $_
$_ | Get-DHCPServerV4Lease -ComputerName $server | #get leases in all the scopes
ForEach-Object {
[pscustomobject]@{ # Make object to match later
ScopeName = $scope.name #want name of scope only
HostName = $_.hostname #want hostname of leases
}
}
}
$assets = (Import-CSV c:\script\Asset_List.csv).asset #pull asset list
$assets | ForEach-Object { $asset = $_ #Go through hostnames finding matching lease
$leases | Where-Object { #check leases
$_.HostName -like "${asset}*" #find hostname
} | ForEach-Object {
$hashtable[$asset] = $_.ScopeName #store matches
}
}
```
Import-Csv
inside theforeach ($server in $DHServers)
loop? Do it once and save to a variable Before the loop. File manipulation is always time consuming... Moreover, theforeach ($_ in ...
seems to be a nonstandard construct, see difference betweenforeach
andForeach-Object
. Read entire about_foreach topic. \$\endgroup\$