Home > OS >  Powershell: Loop over variable
Powershell: Loop over variable

Time:11-20

I am trying to query ports from one server to multiple remote servers but i can't figure it out.

Querying to one server wordks good but i want to add multiple remote servers in $destination variable and let the script loop over them to give me all the results in one shot.

the script i found:

$Servers = "127.0.0.1"
$Ports   =  "80",
            "445",
            "443"

$Destination = "Computer_1"
$Results = @()
$Results = Invoke-Command $Servers {param($Destination,$Ports)
            $Object = New-Object PSCustomObject
            $Object | Add-Member -MemberType NoteProperty -Name "ServerName" -Value 
$env:COMPUTERNAME
            $Object | Add-Member -MemberType NoteProperty -Name "Destination" -Value $Destination
                Foreach ($P in $Ports){
                    $PortCheck = (Test-NetConnection -Port $p -ComputerName $Destination ).TcpTestSucceeded
                    If($PortCheck -notmatch "True|False"){$PortCheck = "ERROR"}
                    $Object | Add-Member Noteproperty "$("Port "   "$p")" -Value "$($PortCheck)"
                }
            $Object
       } -ArgumentList $Destination,$Ports | select * -ExcludeProperty runspaceid, pscomputername

$Results | Out-GridView -Title "Testing Ports"

$Results | Format-Table -AutoSize

I get the results:

ServerName Destination   Port 80 Port 445 Port 443 
---------- -----------   -------- -------- -------- 
<local host> Computer_1    True     True     True    

I need to add multiple remote in the $destination block. I have tried the following:

$Destination = "Computer_1","Computer_2"

But it is not the right way because i get this:

ServerName Destination                     Port 80 Port 445 Port 443
---------- -----------                     -------- -------- -------- 
<local host> "Computer_1","Computer_2"     False    False    False      

i need to get this results:

ServerName Destination   Port 80 Port 445 Port 443 
---------- -----------   -------- -------- -------- 
<local host> Computer_1    True     True     True  
<local host> Computer_2    True     True     True  

Any help would be appreciated.

CodePudding user response:

The problem is that you're running a ForEach() for the $ports but not $destination. You want to do something more like this:

$Servers = "127.0.0.1"
$Ports   =  "80",
            "445",
            "443"

$Destinations = "Computer_1","Computer_2"
$Results = @()
$Results = Invoke-Command $Servers {param($Destinations,$Ports)
    ForEach($Destination in Destinations){
        $Object = New-Object PSCustomObject
        $Object | Add-Member -MemberType NoteProperty -Name "ServerName" -Value $env:COMPUTERNAME
        $Object | Add-Member -MemberType NoteProperty -Name "Destination" -Value $Destination
        Foreach ($P in $Ports){
            $PortCheck = (Test-NetConnection -Port $p -ComputerName $Destination ).TcpTestSucceeded
            If($PortCheck -notmatch "True|False"){$PortCheck = "ERROR"}
            $Object | Add-Member Noteproperty "$("Port "   "$p")" -Value "$($PortCheck)"
        }
        $Object
    }
} -ArgumentList $Destinations,$Ports | select * -ExcludeProperty runspaceid, pscomputername

$Results | Out-GridView -Title "Testing Ports"
$Results | Format-Table -AutoSize

Though if you were more familiar with Powershell, there would be slightly tidier ways of formatting this using the Pipeline to pass your results directly to Out-GridView, rather than collecting them all together into an array first.

CodePudding user response:

You pass multiple servers in $Destination , so you need to loop though them. Instead you just add the whole $Destination in to the $Object

in pseudo code you need something like

$Results  = foreach ($destServer in $ destination) {
   Invoke-Command {
   {same code you use currently}
   }
}
  • Related