Freigeben über


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.