Is there any way I can utilize this piece of code with Test-NetConnection -ComputerName $_ -Port 5985
instead of Test-Connection -ComputerName $_ -Count 1 -AsJob
? I can't utilize -AsJob
with the Test-NetConnection
cmdlet. Are there any workarounds?
Here is my code:
$online = @()
$pc = Get-Content C:\servers.txt
$pc | ForEach-Object {
Test-Connection -ComputerName $_ -Count 1 -AsJob
} | Get-Job | Receive-Job -Wait |
Select-Object @{Name='ComputerName';Expression={$_.Address}},@{Name='Reachable';Expression={
if ($_.StatusCode -eq 0) {
$true
} else {
$false
}
}} | ForEach-Object {
if ($_.Reachable -eq $true) {
$online += $_.ComputerName
}
}
$online | ft -AutoSize
servers.txt just basically has hostnames of all the machines on the network.
With vanilla Windows PowerShell 5.1 the best you can get is using a RunspacePool, the code is not easy to follow and for a good reason there are many modules available to handle multithreading in PowerShell. The most recommended one would be ThreadJob
.
This answer offers a "copy-pastable" version of a function that can handle multithreading from pipeline similar to ForEach-Object -Parallel
but compatible with Windows PowerShell 5.1.
$ProgressPreference = 'Ignore'
$maxThreads = 32 # How many jobs can run at the same time?
$pool = [runspacefactory]::CreateRunspacePool(1, $maxThreads,
[initialsessionstate]::CreateDefault2(), $Host)
$pool.Open()
$jobs = [System.Collections.Generic.List[hashtable]]::new()
Get-Content C:\servers.txt | ForEach-Object {
$instance = [powershell]::Create().AddScript({
param($computer)
[pscustomobject]@{
Computer = $computer
Port = 5985
PortOpen = Test-NetConnection $computer -Port 5985 -InformationLevel Quiet
}
}).AddParameters(@{ computer = $_ })
$instance.RunspacePool = $pool
$jobs.Add(@{
Instance = $instance
Async = $instance.BeginInvoke()
})
}
$result = while($jobs) {
$job = $jobs[[System.Threading.WaitHandle]::WaitAny($jobs.Async.AsyncWaitHandle)]
$job.Instance.EndInvoke($job.Async)
$job.Instance.Dispose()
$null = $jobs.Remove($job)
}
$pool.Dispose()
$result | Where-Object PortOpen # filter only for computers with this port open