Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple PowerShell implementation of the most basic functionality of Netcat
function Send-NetworkData {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]
$Computer,
[Parameter(Mandatory)]
[ValidateRange(1, 65535)]
[Int16]
$Port,
[Parameter(ValueFromPipeline)]
[string[]]
$Data,
[System.Text.Encoding]
$Encoding = [System.Text.Encoding]::ASCII,
[TimeSpan]
$Timeout = [System.Threading.Timeout]::InfiniteTimeSpan
)
begin {
# establish the connection and a stream writer
$Client = New-Object -TypeName System.Net.Sockets.TcpClient
$Client.Connect($Computer, $Port)
$Stream = $Client.GetStream()
$Writer = New-Object -Type System.IO.StreamWriter -ArgumentList $Stream, $Encoding, $Client.SendBufferSize, $true
}
process {
# send all the input data
foreach ($Line in $Data) {
$Writer.WriteLine($Line)
}
}
end {
# flush and close the connection send
$Writer.Flush()
$Writer.Dispose()
$Client.Client.Shutdown('Send')
# read the response
$Stream.ReadTimeout = [System.Threading.Timeout]::Infinite
if ($Timeout -ne [System.Threading.Timeout]::InfiniteTimeSpan) {
$Stream.ReadTimeout = $Timeout.TotalMilliseconds
}
$Result = ''
$Buffer = New-Object -TypeName System.Byte[] -ArgumentList $Client.ReceiveBufferSize
do {
try {
$ByteCount = $Stream.Read($Buffer, 0, $Buffer.Length)
} catch [System.IO.IOException] {
$ByteCount = 0
}
if ($ByteCount -gt 0) {
$Result += $Encoding.GetString($Buffer, 0, $ByteCount)
}
} while ($Stream.DataAvailable -or $Client.Client.Connected)
Write-Output $Result
# cleanup
$Stream.Dispose()
$Client.Dispose()
}
}
# pipe in a HTTP request:
'GET / HTTP/1.0', '' | Send-NetworkData -Computer www.powershellmagazine.com -Port 80
# Use the Data parameter to do the same:
Send-NetworkData -Data 'GET / HTTP/1.0', '' -Computer www.powershellmagazine.com -Port 80
# As before but only wait 2 seconds for a response:
Send-NetworkData -Data 'GET / HTTP/1.0', '' -Computer www.powershellmagazine.com -Port 80 -Timeout 0:00:02
# Say hello to an SMTP server:
Send-NetworkData -Data "EHLO $Env:ComputerName", "QUIT" -Computer mail.example.com -Port 25
@IISResetMe

This comment has been minimized.

Copy link

@IISResetMe IISResetMe commented Oct 5, 2014

[Int16]::MaxValue is 32767 - [uint16] would probably be more appropriate for $Port

@ilatypov

This comment has been minimized.

Copy link

@ilatypov ilatypov commented Sep 11, 2018

} while ($Stream.DataAvailable -or $Client.Client.Connected)

} while ($Stream.DataAvailable -and $Client.Client.Connected)

@ilatypov

This comment has been minimized.

Copy link

@ilatypov ilatypov commented Sep 11, 2018

A complete Bash Netcat replacement,
echo -ne "ehlo foo@bar.test\r\nmail from:<foo@bar.test>\r\nrcpt to:<baz@bar.test>\r\ndata\r\nSubject: test\r\n\r\nHello, world\r\n.\r\nquit\r\n" | { mapfile -t lines; lines=("${lines[@]//$'\r'/}"); pslines=("${lines[@]/#/\"}"); pslines=("${pslines[@]/%/\"}"); pslines="${pslines[*]/%/,}"; pslines="${pslines:0: -1}"; powershell -noprofile -command '.\netcat.ps1' -Computer SERVER -Port 25 -Data "${pslines}" -Timeout "0:00:02"; }

@ilatypov

This comment has been minimized.

Copy link

@ilatypov ilatypov commented Sep 12, 2018

Using =$True in [Parameter(...=$True)] makes a similar script compatible with PowerShell 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.