1

I'm trying to implement a UDP broadcast/response network discovery protocol in PowerShell. I have found a few examples of doing this in C#, but I'm having trouble translating into PowerShell.

The protocol is pretty simple:

  1. Send broadcast from port x to port x.
  2. Nodes reply to port x with payload.
  3. Parse sender IP addresses to build list.

So far, I have part of the broadcast working. I can send to the appropriate port, but I haven't had any luck defining the origination port. I know it's working because I see the responses in Wireshark. I've tabled changing the origination port for now. I'm trying to get the chunk of code for receive started, and I'm stuck trying to translate C# code. I'm guessing that Power Shell can do this (because it's very similar to C#), but I haven't seen it said for sure anywhere.

C# examples (example, example, example, example, example), VB.NET example, Java Example.

I started to try to convert this code (with some of this) from C# and I'm getting runtime errors (code here):

$Enc      = [System.Text.Encoding]::ASCII 
$Message = "WPPS" *10 
$responseData   = $Enc.GetBytes( $Message ) 

#$responseData = [System.Text.Encoding]::ASCIIGetBytes("someData");

while (1)
{
    $server = New-Object System.Net.Sockets.UdpClient(1047);
    $clientEp = New-Object System.Net.IPEndPoint(0.0.0.0, 1047);
    $clientRequestData = server.Receive(ref $clientEp);
    $clientRequest = Encoding.ASCII.GetString($clientRequestData);

    Console.WriteLine($"Recived {$clientRequest} from {$clientEp.Address}, sending response: {$responseData}");
    $server.Send($responseData, $responseData.Length, $clientEp);
    $server.Close();
}

When I try to run the above code, I get repeating errors below. I'm sure it's a disparity between C# and PowerShell syntax, but I have almost no idea what it could be. I'm not sure if that first error is after the first iteration loop, or on the first iteration. It looks like after.

New-Object : Exception calling ".ctor" with "1" argument(s): "Only one usage of each socket address (protocol/network 
address/port) is normally permitted"
At line:9 char:15
+     $server = New-Object System.Net.Sockets.UdpClient(1047);
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

New-Object : Exception calling ".ctor" with "2" argument(s): "Value cannot be null.
Parameter name: address"
At line:10 char:17
+     $clientEp = New-Object System.Net.IPEndPoint(0.0.0.0, 1047);
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

ref : The term 'ref' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of 
the name, or if a path was included, verify that the path is correct and try again.
At line:11 char:41
+     $clientRequestData = server.Receive(ref $clientEp);
+                                         ~~~
    + CategoryInfo          : ObjectNotFound: (ref:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Encoding.ASCII.GetString : The term 'Encoding.ASCII.GetString' is not recognized as the name of a cmdlet, function, script file, 
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:12 char:22
+     $clientRequest = Encoding.ASCII.GetString($clientRequestData);
+                      ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Encoding.ASCII.GetString:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

$Recived {$clientRequest} from {$clientEp.Address}, sending response: {$responseData} : The term '$Recived {$clientRequest} from 
{$clientEp.Address}, sending response: {$responseData}' is not recognized as the name of a cmdlet, function, script file, or 
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:14 char:23
+ ... e.WriteLine($"Recived {$clientRequest} from {$clientEp.Address}, send ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: ($Recived {$clie...{$responseData}:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Exception calling "Send" with "3" argument(s): "A request to send or receive data was disallowed because the socket is not 
connected and (when sending on a datagram socket using a sendto call) no address was supplied"
At line:15 char:5
+     $server.Send($responseData, $responseData.Length, $clientEp);
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SocketException

Are there any examples of how to do this in Power Shell? Can Power Shell actually do this?

I know a couple things in Power Shell, but almost nothing about C#.

YetAnotherRandomUser
  • 1,320
  • 3
  • 13
  • 31
  • Why don't you `AddType` around the C# code? I mean, what's the value you're expecting from converting this to native PowerShell? – evilSnobu Oct 20 '17 at 22:01
  • Because I didn't know such a thing existed until you mentioned it. It looks like `Add-Type` lets you import C# resources. I'm not sure how importing resources will assist me in this case. I know a couple things in Power Shell, but almost nothing about C# (just that it's Microsoft's evolution of Java and .NET, or something). – YetAnotherRandomUser Oct 20 '17 at 22:16

0 Answers0