powershell

Trouble capturing output from Get-NetRoute in a script


I'm having trouble trying to capture, then display the results of Get-NetRoute from within a module:

$option = New-CimSessionOption -Protocol $Protocol
$session = New-CimSession -ComputerName $name -Credential $Credentials -SessionOption $option -ErrorAction $ErrorAct;
$res = Get-NetRoute -CimSession $session

Write-Host $res

What I end up with is garbage:

MSFT_NetRoute (InstanceID = "???8???8???8???9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8???8???8???9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8:8:8:9?55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = "???8:8:8:9?55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8???9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8?:?9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";C?8;@B8;8:9??55?55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8???8???8???9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8:8:8;9??55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ";?A8:8:8:9B55;55:8:8:8:55;") MSFT_NetRoute (InstanceID = ":8:8:8:9:55?55;C?8;@B8;8;55;") MSFT_NetRoute (InstanceID = "pp::DD9B55?55DD55;") MSFT_NetRoute (InstanceID = "pp::DD9B55;55DD55;") MSFT_NetRoute (InstanceID = "poB:DD?B;CD??plD??oBDA@?:9;?B55?55DD55;...) MSFT_NetRoute (InstanceID = "poB:DD9@?55?55DD55;") MSFT_NetRoute (InstanceID = "DD;9;?B55;55DD55;")

When what I expect is a properly formatted table (or at least properties on the $res object that I can get valid values from.) Ultimately, I want to do a little parsing and add columns from other cmdlets later in the script to give me a full report of network configuration on a remote machine. How can I properly capture the result and have it actually show the data as when I do it directly at the command line? Is it because I have to iterate over $res as in a Foreach-Object to access each row in it's result set?

[Edit: Moved from wrong board]

[Edit2: Here's my code listing]

    Function Get-RemoteRouteData{
    [CmdletBinding()]
    [OutputType([System.Management.Automation.PSCustomObject])]
    param (
        [Parameter(Mandatory = $true)]
        [string]$Subnet,
        [Parameter(Mandatory = $true)]
        [object]$Credentials,
        [Parameter(Mandatory = $false)]
        [string]$Protocol = 'WSMan',
        [Parameter(Mandatory = $false)]
        [bool]$TableOnly,
        [Parameter(Mandatory = $false)]
        [string]$ErrorAct = 'SilentlyContinue'
    )
    if (!$TableOnly)
    {
        Write-Host "Scanning $subnet for hosts..."
    }
    
    #Use PSSubnetScan module for hosts
    $computers = Get-PSSubnetScan -IPList $subnet -RevDNS -ICMPTest
    
    $out = @() # Holds list of output objects
    
    $time = Measure-Command {
        foreach ($computer in $computers)
        {
            $name = $computer.RevDNS.Hostname
            $ip = $computer.IPAddress.IPAddressToString
            $ping = $computer.ICMP.IsActive
            
            #Check to see if we have a host name or can ping.  If neither, skip it.
            if ((!$null -eq $name) -and (!$true -eq $ping))
            {
                Continue
            }
            
            if (!$TableOnly)
            {
                Write-Host "Asking $name - $ip for it's Routing Table"
            }
            
            $session = $null
            
            try
            {
                #Use WMI Class directly
                #([WMIClass]"\\$name\ROOT\CImv2:Win32_Process").Create("cmd.exe /c ipconfig /registerdns") | Out-Null
                #([WMIClass]"\\192.168.1.205\ROOT\CImv2:Win32_Process").Create("cmd.exe /c winrm quickconfig"
                #Use Cim Session
                #$option = New-CimSessionOption -Protocol $Protocol
                $session = New-CimSession -ComputerName $name -Credential $Credentials #-SessionOption $option -ErrorVariable $err;
                $res = Get-NetRoute -CimSession $session
                $res | Format-List -Property *
                Write-Host "Sanity Check..."
            }
            catch
            {
                if (!$TableOnly)
                {
                    Write-Host "$ip - $name - FAILED TO GET ROUTING TABLE" -ForegroundColor Red
                }
            
            }
            finally
            {
                Remove-CimSession $session
            }
        }
    }
    if (!$TableOnly)
    {
        "`nCompleted in [{0}] milliseconds" -f $time.TotalMilliseconds
    }
    Write-Host "`n"
}

Get-RemoteRouteData -Subnet 192.168.1.205 -Credentials (Get-Credential)

I added the last line to run the function with a know IP Address (my domain controller). The result is this:

    ❯ import-module .\RoutingInfo.psm1 -force

PowerShell credential request
Enter your credentials.
User: scott.reeves@bluejacketsoftware.com
Password for user scott.reeves@bluejacketsoftware.com: ************

Scanning 192.168.1.205 for hosts...
Asking bjsdc01.bluejacketsoftware.com - 192.168.1.205 for it's Routing Table
Sanity Check...


scott.reeves@DELL17  C:\dev\WPA\PowerShell\RoutingInfo   master ≣ +0 ~1 -1 !                               [21:52]
❯

Solution

  • SOLVED:

    The problem was because the $res variable was nested inside several layers of brackets, not the least of which was a for-eachobject. Since processing had not yet finished iterating over the entire list, the for-eachobject function wasn't capable of returning reasonable values, but rather internal representations. Adding the $res object to the $out collection, and finally printing the $out collection at the very end of the function returned useable results. For reference, here's the working code:

        Function Get-RemoteRouteData{
        [CmdletBinding()]
        [OutputType([System.Management.Automation.PSCustomObject])]
        param (
            [Parameter(Mandatory = $true)]
            [string]$Subnet,
            [Parameter(Mandatory = $true)]
            [object]$Credentials,
            [Parameter(Mandatory = $false)]
            [string]$Protocol = 'WSMan',
            [Parameter(Mandatory = $false)]
            [bool]$TableOnly,
            [Parameter(Mandatory = $false)]
            [string]$ErrorAct = 'SilentlyContinue'
        )
        if (!$TableOnly)
        {
            Write-Host "Scanning $subnet for hosts..."
        
        }
        
        #Use PSSubnetScan module for hosts
        $computers = Get-PSSubnetScan -IPList $subnet -RevDNS -ICMPTest
        
        $out = @() # Holds list of output objects
        
        $time = Measure-Command {
            foreach ($computer in $computers)
            {
                $name = $computer.RevDNS.Hostname
                $ip = $computer.IPAddress.IPAddressToString
                $ping = $computer.ICMP.IsActive
                
                #Check to see if we have a host name or can ping.  If neither, skip it.
                if ((!$null -eq $name) -and (!$true -eq $ping))
                {
                   Continue
                }
                
                if (!$TableOnly)
                {
                    Write-Host "Asking $name - $ip for it's Routing Table"
                }
                
                $session = $null
                
                try
                {
                    #Use WMI Class directly
                    #([WMIClass]"\\$name\ROOT\CImv2:Win32_Process").Create("cmd.exe /c ipconfig /registerdns") | Out-Null
                    #([WMIClass]"\\192.168.1.205\ROOT\CImv2:Win32_Process").Create("cmd.exe /c winrm quickconfig"
                    #Use Cim Session
                    $option = New-CimSessionOption -Protocol $Protocol
                    
                    $session = New-CimSession -ComputerName $name -Credential $Credentials -SessionOption $option -ErrorVariable $err;
                    
                    $res = Get-NetRoute -CimSession $session
                    $out += $res
                    
                }
                catch
                {
                    if (!$TableOnly)
                    {
                        Write-Host "$ip - $name - FAILED TO GET ROUTING TABLE" -ForegroundColor Red
                    }
                
                }
                finally
                {
                    if(!$null -eq $session){
                        Remove-CimSession $session
                    }
                }
            }
        }
        if (!$TableOnly)
        {
            "`nCompleted in [{0}] milliseconds" -f $time.TotalMilliseconds
        }
        Write-Host "`n"
        $out
    }
    Get-RemoteRouteData -Subnet 192.168.1.0/24 -Credentials (Get-Credential)