Remote session inside other remote session and getting remote session computer information like computer name

Hi,

I am building a script in order to validate thousands of network rules. The script would be run from my desktop, open a session to the source computer and then run test-netconnection to the remote one on the specific port. And if the port is not opened, connect to the destination computer and do a check from the localhost.

Except, I am not sure I can launch a pssession from a pssession and to validate the script works, I'd like to retrieve for instance the computer name of the computer in which the session is running. eng:computername returns my desktop

Here is what I have for the moment:

# transforms the dotted IP to an int so that it can be bitwise compared
function toInt ($dottedDecimal){ 
    $dottedDecimal.split(".") | %{ $int=([convert]::toInt64($_) + ($int -shl 8)) ;  }
    return $int
} 
# transforms the int to an ip format
function toDottedDecimalFromInt ($int){ 
    $i = 24;
    do {
        $dottedDecimal += "." + [string]$( $int -shr $i ); 
        $int = $int - (($int -shr $i) -shl $i); 
        $i-= 8; 
    } while ($i -ge 0) 
    return $dottedDecimal.substring(1) 
}
#Gets the wildcard mask from the int mask
function NetMasktoWildcard ($int) { 
    $i = 0;
    $mask = 32;
    while ( ($int -band ([math]::pow(2,$i))) -eq 0 )
    {
        $mask--;
        $i++;
    }
        
    return $mask 
} 

function GetNetwork ($ipinfo)
{
    $subnet = toDottedDecimalFromInt ( (toInt $ipinfo.IPSubnet[0]) -band (toInt $ipinfo.IPAddress[0]) );
    $mask = NetMasktoWildcard (toInt $ipinfo.IPSubnet[0]);
    return ( $subnet + '/' + $mask );
}


#$sourcecomputers = 'for the future'
$sourceComputer = 'sourcecompdns'
$destinationComputers = 'remotecompdns1' #, 'remotecompdns2'
$portList = 53, 88, 135, 389, 445, 5722;
$sourceIP = (Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $sourceComputer -EA Stop | ? {$_.IPEnabled} )
$sourcenet = GetNetwork $sourceIP


$sc = new-pssession -Name 'r' -ComputerName $sourceComputer
enter-pssession $sc
    foreach ($destinationComputer in $destinationComputers) {
        #Get IP info of the destination computer
        $destinationIP = (Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $destinationComputer -EA Stop | ? {$_.IPEnabled} )
        $destnet = GetNetwork $destinationIP
        #Test if the ports can be opened - Beware, service might be actually OFF so answer could be false even though the firewall port is opened - There is a check in place for this scenario
        foreach ($p in $portList) {
            $result = test-netconnection -computername $destinationIP.IPAddress[0] -port $p -informationlevel quiet
            $rval = $false;
            #Checking if the port from the local machine is actually accessible
            if ($result -eq $false) {
                $dc = new-pssession -Name 'r' -ComputerName $destinationComputer
                enter-pssession $dc
                    $rval = test-netconnection -computername $destinationIP.IPAddress[0] -port $p -informationlevel quiet
                remove-pssession $dc
            }
            if ( ($rval -eq $false) -or ($result -eq $true)) {$check = $true;}
            Write-Output ('From Network: '+$sourcenet+' - From IP: '+$sourceIP.IPAddress[0]+' - To Network: '+ $destnet+' - To IP: '+$destinationIP.IPAddress[0]+' - Port: '+$p+' - Check: '+$check+' - Remote Result: '+$result+' - Local Result: '+ ($rval))
        }
    }
remove-pssession $sc


Regards,

September 3rd, 2015 11:40am

Hi O.Ragain,

first of all, if you are trying this as an automated script, do not use Enter-PSSession. This cmdlet is for interactive use only.

Instead create a session and store it in a variable, then use Invoke-Command while specifying the session.

Then, instead of the nested session, I recommend simply running this command remotely using Invoke-Command with the -ComputerName parameter. No need for a full session.

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
September 3rd, 2015 11:46am

# transforms the dotted IP to an int so that it can be bitwise compared function toInt ($dottedDecimal){ $dottedDecimal.split(".") | %{ $int=([convert]::toInt64($_) + ($int -shl 8)) ; } return $int } # transforms the int to an ip format function toDottedDecimalFromInt ($int){ $i = 24; do { $dottedDecimal += "." + [string]$( $int -shr $i ); $int = $int - (($int -shr $i) -shl $i); $i-= 8; } while ($i -ge 0) return $dottedDecimal.substring(1) } #Gets the wildcard mask from the int mask function NetMasktoWildcard ($int) { $i = 0; $mask = 32; while ( ($int -band ([math]::pow(2,$i))) -eq 0 ) { $mask--; $i++; } return $mask } function GetNetwork ($ipinfo) { $subnet = toDottedDecimalFromInt ( (toInt $ipinfo.IPSubnet[0]) -band (toInt $ipinfo.IPAddress[0]) ); $mask = NetMasktoWildcard (toInt $ipinfo.IPSubnet[0]); return ( $subnet + '/' + $mask ); } # Command to be passed to the invokes $command = { param($1,$2); test-netconnection -computername $1 -port $2 -informationlevel quiet; } $sourcecomputers = ###################' $sourceComputer = ###############' $destinationComputers = ############### #$destinationComputer =############### $portList = 53, 88, 135, 389, 445, 5722; $sourceNetwork = '172.16.9.0' $sourceIP = (Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $sourceComputer -EA Stop | ? {$_.IPEnabled} ) $sourcenet = GetNetwork $sourceIP $sc = new-pssession -Name 'r' -ComputerName $sourceComputer #enter-pssession $sc foreach ($destinationComputer in $destinationComputers) { #Get IP info of the destination computer $destinationIP = (Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $destinationComputer -EA Stop | ? {$_.IPEnabled} ) $destnet = GetNetwork $destinationIP #Test if the ports can be opened - Beware, service might be actually OFF so answer could be false even though the firewall port is opened - There is a check in place for this scenario foreach ($p in $portList) { $result = invoke-command -Session $sc -ScriptBlock $command -ArgumentList $destinationIP.IPAddress[0], $p $rval = $false; #Checking if the port from the local machine is actually accessible if ($result -eq $false) { $dc = new-pssession -Name 'r' -ComputerName $destinationComputer $rval = invoke-command -Session $dc -ScriptBlock $command -ArgumentList $destinationIP.IPAddress[0], $p remove-pssession $dc } if ( ($rval -eq $false) -or ($result -eq $true)) {$check = $true;} Write-Output ('From Network: '+$sourcenet+' - From IP: '+$sourceIP.IPAddress[0]+' - To Network: '+ $destnet+' - To IP: '+$destinationIP.IPAddress[0]+' - Port: '+$p+' - Check: '+$check+' - Remote Result: '+$result+' - Local Result: '+ ($rval)) } } remove-pssession $sc


Thanks, that works too, took me a little while to figure out the argumentlist of the invokecommand!
September 3rd, 2015 12:48pm

Hi,

glad to hear it works. One refinement though:

# Old Lines
$dc = new-pssession -Name 'r' -ComputerName $destinationComputer
$rval = invoke-command -Session $dc -ScriptBlock $command -ArgumentList $destinationIP.IPAddress[0], $p
remove-pssession $dc

# New Line
$rval = invoke-command -ComputerName $destinationComputer -ScriptBlock $command -ArgumentList $destinationIP.IPAddress[0], $p

This creates less overhead on the destination computer and less network chatter.

As for IP Math ...

# Example to calculate Subnet
[IPAddress]($ip.Address -band $mask.Address)

# Example to calculate Subnet
[Math]::Log(($mask.Address + 1), 2)

No need to create 3 dedicated functions for that :)

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
September 4th, 2015 7:11am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics