PowerShell Null Routing Function
This week, while troubleshooting a networking problem for a customer, I wanted to limit or block network connectivity to some remote endpoints from a test workstation. To accomplish this, I created a quick PowerShell function to null route the traffic (send it to an invalid/null next hop).
You can copy/paste this and save it as a PS1 for usage later. To invoke, dot source it and then you can use the Add-NullRoute and Remove-NullRoute functions. You can send it one or more dotted-four addresses or CIDR ranges.
function Add-NullRoute([ValidatePattern('^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)($|/([0-9]|1[0-9]|2[0-9]|3[0-2]))?$')][array]$IPAddress,[switch]$UseLegacy,[switch]$Force)
{
# Check if Elevated
$wid = [system.security.principal.windowsidentity]::GetCurrent()
$prp = New-Object System.Security.Principal.WindowsPrincipal($wid)
$adm = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if ($prp.IsInRole($adm))
{
Write-Host "Elevated PowerShell session detected. Continuing."
}
else
{
Write-Host -Fore Red "This application/script must be run in an elevated PowerShell window. Please launch an elevated session and try again."
Break
}
$result = [bool](Get-Command New-NetRoute -ea silentlycontinue)
If (!$UseLegacy)
{
switch ($result)
{
true
{
$adapters = (Get-NetAdapter | ? { $_.MediaConnectionState -eq "Connected" -and $_.InterfaceDescription -notlike "*Xbox*" }).InterfaceIndex
foreach ($adapter in $adapters)
{
foreach ($address in $IPAddress)
{
Write-Host "Specified Address is $($address)"
if ($address -notlike "*/*") { $address = $address + "/32" }
Write-Host "Null routing address $($address)"
$IfAddressExists = [bool](Get-NetRoute -DestinationPrefix $address -ea SilentlyContinue)
switch ($IfAddressExists)
{
true {
if (!$Force) { Write-Host "Route already exists. Use -Force parameter to update existing route." }
If ($Force)
{
Write-Host "Updating destination $($address)."
Set-NetRoute -InterfaceIndex $adapter -DestinationPrefix $address -NextHop 0.0.0.0
}
}
false {
Write-Host "Processing $($address) for adapter $($adapter)."
New-NetRoute -InterfaceIndex $adapter -DestinationPrefix $address -NextHop 0.0.0.0
}
}
}
}
}
false
{
# Use the legacy Route Add syntax
foreach ($address in $range)
{
Write-Host "Adding route for $($address)"
route add $address mask 255.255.255.255 0.0.0.0
}
}
}
}
else
{
# Use the legacy Route Add syntax
foreach ($address in $range)
{
Write-Host "Adding route for $($address)."
Route add $address mask 255.255.255.255 0.0.0.0
}
}
}
function Remove-NullRoute([ValidatePattern('^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)($|/([0-9]|1[0-9]|2[0-9]|3[0-2]))?$')][array]$IPAddress, [switch]$UseLegacy, [switch]$Force)
{
# Check if Elevated
$wid = [system.security.principal.windowsidentity]::GetCurrent()
$prp = New-Object System.Security.Principal.WindowsPrincipal($wid)
$adm = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if ($prp.IsInRole($adm))
{
Write-Host "Elevated PowerShell session detected. Continuing."
}
else
{
Write-Host -Fore Red "This application/script must be run in an elevated PowerShell window. Please launch an elevated session and try again."
Break
}
$result = [bool](Get-Command Remove-NetRoute -ea silentlycontinue)
If (!$UseLegacy)
{
switch ($result)
{
true
{
foreach ($address in $IPAddress)
{
Write-Host "Specified Address is $($address)"
if ($address -notlike "*/*") { $address = $address + "/32" }
Write-Host "Null routing address $($address)"
$IfAddressExists = [bool](Get-NetRoute -DestinationPrefix $address -ea SilentlyContinue -NextHop 0.0.0.0)
switch ($IfAddressExists)
{
true {
Write-Host "Removing null route for $($address)."
Remove-NetRoute -DestinationPrefix $address -Confirm:$false
}
false {
Write-Host "Null route does not currently exist for $($address)."
}
}
}
}
false
{
# Use the legacy Route Add syntax
foreach ($address in $range)
{
Write-Host "Removing null route for $($address)"
route delete $address
}
}
}
}
else
{
# Use the legacy Route Add syntax
foreach ($address in $range)
{
Write-Host "Removing null route for $($address)."
Route delete $address
}
}
}
I've also posted it on the TN gallery at https://gallery.technet.microsoft.com/Add-and-Remove-Null-Routes-cfc77032.