I have 3 nested loops and they do the following:

  1. Get scopes from DHCP
  2. Get hostnames from csv file
  3. 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
    \$\begingroup\$ Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate. \$\endgroup\$ Apr 15, 2021 at 20:41
  • \$\begingroup\$ Why do you Import-Csv inside the foreach ($server in $DHServers) loop? Do it once and save to a variable Before the loop. File manipulation is always time consuming… Moreover, the foreach ($_ in … seems to be a nonstandard construct, see difference between foreach and Foreach-Object. Read entire about_foreach topic. \$\endgroup\$
    – JosefZ
    Apr 16, 2021 at 18:04
  • \$\begingroup\$ Doing it inside vs outside only took a few milliseconds off. Its calling DHCP info each time I loop that is the real problem. \$\endgroup\$ Apr 16, 2021 at 18:13

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.