i'm sruggeling with some script that checks NW connectivity between hosts basicaly i have CSV with source IP and port which looks like this
the problem is when i run this script it checks me every ip with every port and i need it to check onlu port that is next to it i .e for 8.8.8.8 only port 53 and for 1.1.1.1 only 443
below is my code
$dest = Import-Csv "C:\temp\dest.csv"
#$dest | ft
$source = (Get-WmiObject Win32_Computersystem).name
Foreach ($d in $dest.SourceIP){
Foreach ($P in $dest.Port){
try{
$temp = new-object Net.Sockets.TcpClient
$temp.Connect("$d", $P)
if ($temp.Connected -eq $true){
Write-Host $P -ForegroundColor Green " => port is open from" $source "to" $d
}
}
catch {$theError =$_
if($theError.Exception -like "*A connection attempt failed*"){
Write-Host $P -ForegroundColor Red "=> NO TRAFFIC between" $source "and" $d
}
elseif($theError.Exception -like "*No connection could be made*"){
Write-Host $P -ForegroundColor Red "=> port is closed from" $source "to" $d
}
}
}
}
I know that nested loop is the problem here but i ran oout of ideas how to change it to make it work properly
Get-WmiObject
is obsolete. Use Get-CimInstance
works pretty much the same.
And why the nested loop in first place? You can access the properties!
$source = (Get-CimInstance -ClassName Win32_Computersystem).Name
Foreach ($Address in $dest) {
$PortString = '{0,-5} => ' -f $Address.Port
try {
if ([System.Net.Sockets.TcpClient]::new($Address.SourceIP, $Address.Port).Connected) {
Write-Host -ForegroundColor Green $PortString 'port is open from' $source 'to' $Address.SourceIp
}
}
catch [System.Net.Sockets.SocketException] {
switch ($_.Exception.ErrorCode) {
10060 { Write-Host -ForegroundColor Red $PortString 'NO TRAFFIC between' $source 'and' $Address.SourceIp }
10061 { Write-Host -ForegroundColor Red $PortString 'port is closed from' $source 'to' $Address.SourceIp }
}
}
catch {
# generic error management
}
}
and if you are using Powershell Core/7.x and you have many elements to check, you can use Foreach-Object -Parallel
. See:
$source = (Get-CimInstance -ClassName Win32_Computersystem).Name
Import-Csv -Path $CsvPath | ForEach-Object -Parallel {
# technically superfluous, but helps readibility.
$Address = $_
# necessary to access the out-of-scope $source varible.
# the local name could by anything, but I kept the same name for clarity.
$source = $using:source
$PortString = '{0,-5} => ' -f $Address.Port
try {
if ([System.Net.Sockets.TcpClient]::new($Address.SourceIP, $Address.Port).Connected) {
Write-Host -ForegroundColor Green $PortString 'port is open from' $source 'to' $Address.SourceIp
}
}
catch [System.Net.Sockets.SocketException] {
switch ($_.Exception.ErrorCode) {
10060 { Write-Host -ForegroundColor Red $PortString 'NO TRAFFIC between' $source 'and' $Address.SourceIp }
10061 { Write-Host -ForegroundColor Red $PortString 'port is closed from' $source 'to' $Address.SourceIp }
}
}
catch {
# generic error management
}
}