Powershell Windows

There was a question on microsoft.public.windows.powershell today about ways of using Powershell to process telnet commands. That made me think of how I would do the sort of thing this guy was looking for B.P. (Before Powershell). Instead of telnet, I find netcat to be a much more flexible tool. One of the features I really use in Netcat is the ability to quickly connect to an arbitrary TCP port and send and receive data. (I know it does much more.)

So here we are A.P. (After Powershell); what’s a scripter to do? I want to see how to do netcat the Powershell way. That of course means something that can work in the pipeline. I’m more of a hacker than a programmer, I need some code to start with. Searching for “powershell telnet” produced exactly what I was looking for; a blog post from almost a year ago titled, “Replacing Telnet.exe (now removed from Vista)“. The code I found does simple TCP port probing and I/O–that was perfect.

My code isn’t so perfect, but here is what I have so far. This is in the form of a .PS1 script that you would typically dot-source in your profile so that the filter function is ready for use at any time. I don’t know if this is the best way to handle it–feedback welcome. I’ve decided I like Write-TcpPort better as a name than the original Connect-Computer. The changes made to the original code so far are very minimal. I just replaced the read-host with $_ $Input and encapsulated everything in filter{}. See below the code listing for more discussion, such as why doesn’t this work 100%?

Ye code:

   1: filter Write-TcpPort {
   2:     param(
   3:         [string] $remoteHost = "localhost",
   4:         [int] $port = 80
   5:     )
   6:  
   7:     ## Open the socket, and connect to the computer on the specified port
   8:     $socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
   9:     if($socket -eq $null) { return; }
  10:  
  11:     $stream = $socket.GetStream()
  12:     $writer = new-object System.IO.StreamWriter($stream)
  13:  
  14:     $buffer = new-object System.Byte[] 1024
  15:     $encoding = new-object System.Text.AsciiEncoding
  16:  
  17:     while($TRUE)
  18:     {
  19:         ## Allow data to buffer for a bit
  20:         start-sleep -m 500
  21:  
  22:         ## Read all the data available from the stream, writing it to the
  23:         ## screen when done.
  24:         while($stream.DataAvailable) 
  25:         { 
  26:             $read = $stream.Read($buffer, 0, 1024)   
  27:             write-host -n ($encoding.GetString($buffer, 0, $read)) 
  28:         }
  29:  
  30:         ## Write command from pipeline to the remote host
  31:         $cmd = $Input | out-string
  32:         $writer.WriteLine($cmd)
  33:         $writer.Flush()
  34:     }
  35:  
  36:     ## Close the streams
  37:     # $writer.Close()
  38:     # $stream.Close()
  39: }

 


You can try it yourself after saving the code to a file (user & password here have been censored):

Ye Interactive Shell:

10# . .tcp.ps1

11# $cmd2 = @"
>> <userid>
>> <password>
>> 1
>> 1
>> "@
>>
12# $cmd2 | Write-TcpPort myrouter.local 23
Login: <userid>
<password>
1
1

Password:

                Welcome to
               Cisco Systems
       VPN 3000 Concentrator Series
          Command Line Interface
Copyright (C) 1998-2001 Cisco Systems, Inc.

1) Configuration
2) Administration
3) Monitoring
4) Save changes to Config file
5) Help Information
6) Exit

Main ->
1) Interface Configuration
2) System Management
3) User Management
4) Policy Management
5) Back

Config ->
This table shows current IP addresses.

  Intf         Status       IP Address/Subnet Mask          MAC Address
-------------------------------------------------------------------------------
Ether1-Pri|      UP      |   172.16.16.45/255.255.255.0  | 00.03.A0.88.3E.64
Ether2-Pub|      UP      |  172.16.17.209/255.255.255.0  | 00.03.A0.88.3E.65
-------------------------------------------------------------------------------
DNS Server: 10.2.1.11
Default Gateway: 172.16.16.1

So what’s wrong with it? Well for one thing, it keeps going. It’s not exiting the pipeline loop. I’m sure I did something wrong there. The second thing is that you start to get errors I think related to the port not being closed, or perhaps the remote end closed and Powershell is still trying to send data. If you know how to fix this, please let me know. I’ll figure it out eventually. :)

Technorati Tags:

: http://halr9000.com/article/397

( Show All | Hide All ) Post a comment now » Sorry, the comments are closed.
Lee
2007-07-16 23:33:46

Good changes :) There was actually a follow-up to that post, as I agree — an arbitrary netcat is much more flexible:

http://www.leeholmes.com/blog/ScriptingNetworkTCPConnectionsInPowerShell.aspx

I’ve since renamed it to Send-TcpRequest to more accurately reflect its purpose.

Lee

Sorry, the comment form is closed at this time.

  • Microblog

  • Recent Posts

  • Recent Comments

  • meta