Search code examples
powershellcsv

Powershell - iterate through CSV file


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

enter image description here

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


Solution

  • 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 
        }
    }