Is it possible to multithread this Powershell NSLookup script?

81 Views Asked by At

I wrote a powershell script that takes in a text file of IPs and outputs a csv of the IP to hostname mapping.

Currently, the script is single threaded and is taking a long time to run since it has to wait for the DNS server to resolve the address before moving to the next IP in the list.

The recent set of IPs I needed to resolve was around 3000 addresses and took around 3 hours, and as we get to other sites in the project this number is only going to get bigger.

$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch.Start()
$ip_file = Get-Content -Path "C:\filepath\ip_list.txt"
$ip_list = @()

ForEach ($ip in $ip_file) {
    $ip_list += $ip
}

Write-Output "Total Number of IPs in IP File: $($ip_list.Length)"
$ip_list = $ip_list | Select-Object -Unique
Write-Output "Total Number of IPs with duplicates removed: $($ip_list.Length)"

$count = 0
$total_resolved = 0
ForEach ($ip in $ip_list) {
    try {
        $hostname = [System.Net.Dns]::GetHostByAddress($ip).Hostname
        Add-Content -Path "C:\filepath\nslookup_results.txt" -Value "$ip, $hostname"
        Write-Output "$ip, $hostname"
        $total_resolved += 1
    }
    catch {
        Write-Output "Unable to resolve hostname for $ip"
    }
    $count += 1
    if ($count % 10 -eq 0) {
        $remaining = $ip_list.Length - $count
        $percentage = ($count / $ip_list.Length) * 100
        $percentage = [Math]::Round($percentage,1)
        $percent_resolved = ($total_resolved / $count) * 100
        $percent_resolved = [Math]:: Round($percent_resolved,1)
        Write-Output ""
        Write-Output "IPs left: $remaining"
        Write-Output "IPs attempted: $count"
        Write-Output "Total hostnames resolved: $total_resolved"
        Write-Output "Percent resolved: $percent_resolved"
        Write-Output "Percent complete: $percentage%"
        Write-Output "Total elapsed time:  $($watch.Elapsed.Hours):$($watch.Elapsed.Minutes):$($watch.Elapsed.Seconds).$($watch.Elapsed.Milliseconds)"
        Write-Output ""
    }
}

$remaining = $ip_list.Length - $count
$percentage = ($count / $ip_list.Length) * 100
$percentage = [Math]::Round($percentage,1)
$percent_resolved = ($total_resolved / $count) * 100
$percent_resolved = [Math]:: Round($percent_resolved,1)
Write-Output ""
Write-Output "IPs left: $remaining"
Write-Output "IPs attempted: $count"
Write-Output "Total hostnames resolved: $total_resolved"
Write-Output "Percent resolved: $percent_resolved"
Write-Output "Percent complete: $percentage%"
Write-Output "Total elapsed time: $($watch.Elapsed.Hours):$($watch.Elapsed.Minutes):$($watch.Elapsed.Seconds).$($watch.Elapsed.Milliseconds)"
Write-Output "IP resolution complete!"
Write-Output ""
$watch.Stop()

I am curious if there is a way to utilize multi-threading in the script so that multiple DNS queries can me resolved simultaneously.

To be honest I am not sure where to start with multi-threading in powershell, as I am newer to the language, so I haven't tried to implement it myself so far. I can't afford to break the working script right now due to the time constraints I am under.

0

There are 0 best solutions below