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