<# .SYNOPSIS PowerShell script that knocks on a given sets of ports. It can optionally take an execute parameter to run a secondary script after the knocking is complete. .DESCRIPTION PowerShell script that knocks on a given sets of ports. It can optionally take an execute parameter to run a secondary script after the knocking is complete. .PARAMETER Knock_Ports Object Array for of the sequence of ports that should be knocked. The array must follow the following pattern. Destination, Port, Protocol .PARAMETER Delay The time to pause between knocks in milliseconds. Defaults to 200 milliseconds. .PARAMETER Execute Optional command that will be run after the knocking sequence is complete. This is passed directly to a Invoke-Expression command. .EXAMPLE $Knock_Ports = @( ("10.1.1.1", 36041, "TCP"), ("10.1.1.1", 38097, "UDP"), ("10.1.1.1", 27079, "TCP") ) PortKnock.ps1 -Knock_Ports $Knock_Ports .NOTES Version: 1.0 Author: Tyler Hale Creation Date: 2021.09.13 #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Object[]] $Knock_Ports, [Parameter(Mandatory = $false)] [int] $Delay = 200, [Parameter(Mandatory = $false)] [string] $Execute ) $ErrorDetected = $False foreach ($Knock in $Knock_Ports) { if (!([ipaddress]::TryParse("$($Knock[0])",[ref][ipaddress]::Loopback))) { $DNS_Resolve = (Resolve-DnsName $Knock[0]) $Knock_Destination = $DNS_Resolve.IP4Address } else { $Knock_Destination = $Knock[0] } $Knock_Port = $Knock[1] $Knock_Protocol = $Knock[2] try { switch ($Knock_Protocol) { "TCP" { $tcpClient = New-Object System.Net.Sockets.TcpClient $tcpClient.BeginConnect($Knock_Destination, $Knock_Port, $null, $null) | Out-Null $tcpClient.Close() | Out-Null } "UDP" { $udpClient = New-Object System.Net.Sockets.UdpClient $udpClient.Connect($Knock_Destination, $Knock_Port) | Out-Null $udpClient.Send([byte[]](0), 1) | Out-Null $udpClient.Close() | Out-Null } default { throw "Protocol not found $Knock_Protocol" } } Write-Verbose "Sent $Knock_Protocol packet to $($Knock_Destination):$Knock_Port" } catch { Write-Error $_ $ErrorDetected = $True } Start-Sleep -Milliseconds $Delay } if ($ErrorDetected) { Write-Warning "Knock may not have completed successfully" } else { Write-Host "Knock Complete" if ($null,"" -ne $Execute) { Write-Verbose "Invoking command: $Execute" Invoke-Expression -Command $Execute } }