Skip to content

Commit 6e0b24e

Browse files
authored
Create Test-RpcConnection.ps1
1 parent 08da4fc commit 6e0b24e

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

Test-RpcConnection.ps1

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
Function Test-RPCConnection {
2+
<#
3+
.SYNOPSIS
4+
This cmdlet is used to test RPC connections to a remote device
5+
6+
7+
.DESCRIPTION
8+
Test open RPC connections between the local machine executing this cmdlet and a remotely specified device
9+
10+
11+
.PARAMETER ComputerName
12+
Specify the FQDN, IP address, or hostname of a remote device to check your RPC connectivity with
13+
14+
15+
.EXAMPLE
16+
Test-RpcConnection -ComputerName dhcp.domain.com
17+
# This example checks to see if any RPC communications can be opened betwnee localhost and dhcp.domain.com
18+
19+
20+
.LINK
21+
https://devblogs.microsoft.com/scripting/testing-rpc-ports-with-powershell-and-yes-its-as-much-fun-as-it-sounds/
22+
http://bit.ly/scriptingguystwitter
23+
http://bit.ly/scriptingguysfacebook
24+
https://social.msdn.microsoft.com/profile/Joel%20Vickery,%20PFE
25+
26+
27+
.NOTES
28+
I stole this from the below author and made a few inconsequential changes
29+
Author: Ryan Ries [MSFT]
30+
Origianl date: 15 Feb. 2014
31+
Requires: -Version 3
32+
33+
Modifications Made by Robert Osborne
34+
35+
36+
37+
INPUTS
38+
System.String
39+
40+
41+
OUTPUTS
42+
PSCustomObject
43+
#>
44+
[CmdletBinding(SupportsShouldProcess=$True)]
45+
param(
46+
[Parameter(
47+
Position=0,
48+
Mandatory=$True,
49+
ValueFromPipeline=$True,
50+
ValueFromPipelineByPropertyName=$False,
51+
HelpMessage="Define the hostname, FQDN, or IP address of the remote host to test RPC connectivity on")] # End Parameter
52+
[String[]]$ComputerName = 'localhost')
53+
54+
BEGIN {
55+
56+
$Output = @()
57+
$Source = @'
58+
using System;
59+
using System.Collections.Generic;
60+
using System.Runtime.InteropServices;
61+
62+
63+
64+
public class Rpc
65+
{
66+
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
67+
public static extern int RpcBindingFromStringBinding(string StringBinding, out IntPtr Binding);
68+
69+
[DllImport("Rpcrt4.dll")]
70+
public static extern int RpcBindingFree(ref IntPtr Binding);
71+
72+
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
73+
public static extern int RpcMgmtEpEltInqBegin(IntPtr EpBinding,
74+
int InquiryType, // 0x00000000 = RPC_C_EP_ALL_ELTS
75+
int IfId,
76+
int VersOption,
77+
string ObjectUuid,
78+
out IntPtr InquiryContext);
79+
80+
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
81+
public static extern int RpcMgmtEpEltInqNext(IntPtr InquiryContext,
82+
out RPC_IF_ID IfId,
83+
out IntPtr Binding,
84+
out Guid ObjectUuid,
85+
out IntPtr Annotation);
86+
87+
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
88+
public static extern int RpcBindingToStringBinding(IntPtr Binding, out IntPtr StringBinding);
89+
90+
public struct RPC_IF_ID
91+
{
92+
public Guid Uuid;
93+
public ushort VersMajor;
94+
public ushort VersMinor;
95+
}
96+
97+
98+
// Returns a dictionary of <Uuid, port>
99+
public static Dictionary<int, string> QueryEPM(string host)
100+
{
101+
Dictionary<int, string> ports_and_uuids = new Dictionary<int, string>();
102+
int retCode = 0; // RPC_S_OK
103+
104+
IntPtr bindingHandle = IntPtr.Zero;
105+
IntPtr inquiryContext = IntPtr.Zero;
106+
IntPtr elementBindingHandle = IntPtr.Zero;
107+
RPC_IF_ID elementIfId;
108+
Guid elementUuid;
109+
IntPtr elementAnnotation;
110+
111+
try
112+
{
113+
retCode = RpcBindingFromStringBinding("ncacn_ip_tcp:" + host, out bindingHandle);
114+
if (retCode != 0)
115+
throw new Exception("RpcBindingFromStringBinding: " + retCode);
116+
117+
retCode = RpcMgmtEpEltInqBegin(bindingHandle, 0, 0, 0, string.Empty, out inquiryContext);
118+
if (retCode != 0)
119+
throw new Exception("RpcMgmtEpEltInqBegin: " + retCode);
120+
121+
do
122+
{
123+
IntPtr bindString = IntPtr.Zero;
124+
retCode = RpcMgmtEpEltInqNext (inquiryContext, out elementIfId, out elementBindingHandle, out elementUuid, out elementAnnotation);
125+
if (retCode != 0)
126+
if (retCode == 1772)
127+
break;
128+
129+
retCode = RpcBindingToStringBinding(elementBindingHandle, out bindString);
130+
if (retCode != 0)
131+
throw new Exception("RpcBindingToStringBinding: " + retCode);
132+
133+
string s = Marshal.PtrToStringAuto(bindString).Trim().ToLower();
134+
if(s.StartsWith("ncacn_ip_tcp:"))
135+
if (ports_and_uuids.ContainsKey(int.Parse(s.Split('[')[1].Split(']')[0])) == false) ports_and_uuids.Add(int.Parse(s.Split('[')[1].Split(']')[0]), elementIfId.Uuid.ToString());
136+
137+
RpcBindingFree(ref elementBindingHandle);
138+
139+
}
140+
while (retCode != 1772); // RPC_X_NO_MORE_ENTRIES
141+
}
142+
catch(Exception ex)
143+
{
144+
Console.WriteLine(ex);
145+
return ports_and_uuids;
146+
}
147+
finally
148+
{
149+
RpcBindingFree(ref bindingHandle);
150+
}
151+
return ports_and_uuids;
152+
}
153+
}
154+
'@
155+
156+
} PROCESS {
157+
158+
ForEach ($C in $ComputerName) {
159+
$EPMOpen = $False
160+
$Socket = New-Object -TypeName System.Net.Sockets.TcpClient
161+
162+
Try {
163+
164+
$Socket.Connect($C, 135)
165+
If ($Socket.Connected) {
166+
167+
$EPMOpen = $True
168+
169+
} # End If
170+
171+
$Socket.Close()
172+
173+
} Catch {
174+
175+
$Output += New-Object -TypeName PSCustomObject -Property @{
176+
ComputerName=$C;
177+
Port=135;
178+
Status="Unreachable"
179+
} # End New-Object -Property
180+
181+
$Socket.Dispose()
182+
183+
} # End Try Catch
184+
185+
If ($EPMOpen) {
186+
187+
Add-Type -TypeDefinition $Source
188+
189+
$RpcPortsUuids = [Rpc]::QueryEPM($C)
190+
$PortDeDup = ($RpcPortsUuids.Keys) | Sort-Object -Unique
191+
192+
Foreach ($Port In $PortDeDup) {
193+
194+
$Socket = New-Object -TypeName System.Net.Sockets.TcpClient
195+
Try {
196+
197+
$Socket.Connect($C, $Port)
198+
If ($Socket.Connected) {
199+
200+
$Output += New-Object -TypeName PSCustomObject -Property @{
201+
ComputerName=$C;
202+
Port=135;
203+
Status="Open"
204+
} # End New-Object -Property
205+
206+
} # End If
207+
208+
$Socket.Close()
209+
210+
} Catch {
211+
212+
$Output += New-Object -TypeName PSCustomObject -Property @{
213+
ComputerName=$C;
214+
Port=135;
215+
Status="Unreachable"
216+
} # End New-Object -Property
217+
218+
$Socket.Dispose()
219+
220+
} # End Try Catch
221+
222+
} # End ForEach
223+
224+
} # End If
225+
226+
} # End ForEach
227+
228+
} END {
229+
230+
Write-Verbose -Message "Completed RPC connection testing"
231+
Return $Output
232+
233+
} # End BPE
234+
235+
} # End Function Test-RPCConnection

0 commit comments

Comments
 (0)