Sunday, June 24, 2018

Powershell: Test RPC Connection and the RPC higher ports

Troubleshooting RPC connections are a bit challenging as RPC as it uses port 135 then continues the communication on a dynamic random port (More here).
So when getting an RPC not available error message or any similar error, usually the question, is the RPC connection was successful on the dynamic ports, is the client able to communicate establish RPC connection with the remote host successfully ?!

Part of the puzzle answer is a nice small tool from Microsoft called PortQry. This tool will query the host port and get a list of ports and the status of the ports.
This tool can also get a list of RPC Dynamic ports via the RPC mapper, check the below sample output:

.\PortQry.exe -e 135 -n MyServer

UUID: 2e6035b2-e8f1-41a7-a044-656b439c4c34 Proxy Manager provider server endpoint
ncacn_ip_tcp:MyServer[49674]

UUID: 2e6035b2-e8f1-41a7-a044-656b439c4c34 Proxy Manager provider server endpoint
ncacn_ip_tcp:MyServer[49673]

UUID: c49a5a70-8a7f-4e70-ba16-1e8f1f193ef1 Adh APIs
ncacn_np:MyServer[\\pipe\\SessEnvPublicRpc]

UUID: 12345778-1234-abcd-ef00-0123456789ac
ncacn_ip_tcp:MyServer[49668]

UUID: 12345778-1234-abcd-ef00-0123456789ac
ncacn_ip_tcp:MyServer49709]

in the example above the focus will be on the ip_tcp, and as we can see that there are some RPC are assigned with service and others are not such as 49668 and 49709, these are listening. and our target is to check the reachability for these ports.

To answer this, I created a #Powershell use the PortQuery tool to get a list of all the dynamic ports and then use a PowerShell script to test the reachability of this port via Test-NetConnection command.

If the script is used without any parameter, the Localhost will be scanned, or you can simply use the -Servername parameter and set the computer name you want to scan.
I tried to make the script simple without defining a lot of variables and parameter, and all can be adjusted, just leave a comment and will update it for you if you want to scan a list of servers.

NOTE: Please make sure that the Portqry.exe is in the following path "C:\PortQryV2\"

# ----------------------------------- Script Start from here ------------
param(
[string]$Servername="localhost"
)
#Please Make sure that the tool is in the path below or simply update the path 
if (Test-Path "C:\PortQryV2\"){
    Try{
   #Execute the tool and filter the output to get only the IP unique result 
        $RPCPorts=  C:\PortQryV2\PortQry.exe -e 135 -n $Servername  | findstr "ncacn_ip" | Select-Object -Unique
            if ($RPCPorts.length -eq 0){
                Write-Host "No output, maybe incorrect server name" -ForegroundColor Red
                return
            }
        #Parsing the output
        ForEach ($SinglePort in $RPCPorts){
        $porttocheck=$SinglePort.Substring($SinglePort.IndexOfAny("[")+1)
        $porttocheck=$porttocheck.Remove($porttocheck.Length -1)
        #Checking the port reachability 
        $Result=Test-NetConnection -ComputerName $Servername -Port $porttocheck
        Write-Host "Port health for $Servername on port $porttocheck is " -NoNewline
        Write-Host $Result.TcpTestSucceeded -ForegroundColor Green
        }
    }
    Catch{
        #Something went wrong, maybe the firewall block, the exception will be written
        Write-Host $_.Exception.Message -ForegroundColor Red

    }

}
ELSE{
    Write-Host "PortQry is not found"
}
# --------------------------------- Script Finishes here ------------


The output should look similar to this


In this way we can confirm that the ports are reachable and the communication is OK.

No comments: