Public/network/Get-NetworkRoute.ps1
|
#Requires -Version 5.1 function Get-NetworkRoute { <# .SYNOPSIS Retrieves IP routing table entries on one or more Windows computers. .DESCRIPTION Queries the routing table using the Get-NetRoute cmdlet from the NetTCPIP module. Supports filtering by destination prefix, next hop gateway, interface alias, and address family (IPv4/IPv6). For remote computers, the query is executed via Invoke-Command, which requires WinRM / WS-Man enabled on the target. .PARAMETER ComputerName One or more computer names to query. Accepts pipeline input by value and by property name. Defaults to the local machine ($env:COMPUTERNAME). .PARAMETER Credential Optional PSCredential for authenticating to remote machines. Ignored for local machine queries. .PARAMETER DestinationPrefix Filter routes by destination prefix. Supports wildcards (e.g. '10.0.*', '0.0.0.0/0'). .PARAMETER NextHop Filter routes by next hop gateway address. Supports wildcards. .PARAMETER InterfaceAlias Filter routes by network interface alias (e.g. 'Ethernet', 'Wi-Fi'). Supports wildcards. .PARAMETER AddressFamily Filter routes by address family. Valid values: IPv4, IPv6. By default both are returned. .EXAMPLE Get-NetworkRoute Returns all routing table entries on the local machine. .EXAMPLE Get-NetworkRoute -AddressFamily IPv4 -DestinationPrefix '0.0.0.0/0' Returns the default IPv4 gateway route on the local machine. .EXAMPLE Get-NetworkRoute -ComputerName 'SRV01' -Credential (Get-Credential) Returns all routes on remote server SRV01. .EXAMPLE 'SRV01', 'SRV02' | Get-NetworkRoute -AddressFamily IPv4 Returns IPv4 routes for two servers via pipeline. .OUTPUTS PSWinOps.NetworkRoute Route details including destination, next hop, interface, metric and address family. .NOTES Author: Franck SALLET Version: 1.0.0 Last Modified: 2026-03-20 Requires: PowerShell 5.1+ / Windows only Permissions: No admin required for reading routes Remote: Requires WinRM / WS-Man enabled on target machines .LINK https://docs.microsoft.com/en-us/powershell/module/nettcpip/get-netroute #> [CmdletBinding()] [OutputType('PSWinOps.NetworkRoute')] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias('CN', 'Name', 'DNSHostName')] [string[]]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [PSCredential]$Credential, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$DestinationPrefix, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$NextHop, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$InterfaceAlias, [Parameter(Mandatory = $false)] [ValidateSet('IPv4', 'IPv6')] [string]$AddressFamily ) begin { Write-Verbose "[$($MyInvocation.MyCommand)] Starting network route query" $localNames = @($env:COMPUTERNAME, 'localhost', '.') $hasCredential = $PSBoundParameters.ContainsKey('Credential') $queryScriptBlock = { param( [string]$QueryAddressFamily, [string]$QueryDestinationPrefix, [string]$QueryNextHop, [string]$QueryInterfaceAlias ) $getParams = @{ ErrorAction = 'Stop' } if ($QueryAddressFamily) { $getParams['AddressFamily'] = $QueryAddressFamily } $routes = Get-NetRoute @getParams if ($QueryDestinationPrefix) { $routes = @($routes | Where-Object { $_.DestinationPrefix -like $QueryDestinationPrefix }) } if ($QueryNextHop) { $routes = @($routes | Where-Object { $_.NextHop -like $QueryNextHop }) } if ($QueryInterfaceAlias) { $routes = @($routes | Where-Object { $_.InterfaceAlias -like $QueryInterfaceAlias }) } foreach ($route in $routes) { [PSCustomObject]@{ DestinationPrefix = $route.DestinationPrefix NextHop = $route.NextHop InterfaceAlias = $route.InterfaceAlias InterfaceIndex = $route.InterfaceIndex RouteMetric = $route.RouteMetric AddressFamily = if ($route.AddressFamily -eq 2) { 'IPv4' } elseif ($route.AddressFamily -eq 23) { 'IPv6' } else { [string]$route.AddressFamily } Protocol = [string]$route.Protocol Store = [string]$route.Store } } } } process { foreach ($targetComputer in $ComputerName) { try { $isLocal = $localNames -contains $targetComputer $timestamp = Get-Date -Format 'o' Write-Verbose "[$($MyInvocation.MyCommand)] Querying '$targetComputer' (local: $isLocal)" $queryArgs = @( $(if ($AddressFamily) { $AddressFamily } else { $null }) $(if ($PSBoundParameters.ContainsKey('DestinationPrefix')) { $DestinationPrefix } else { $null }) $(if ($PSBoundParameters.ContainsKey('NextHop')) { $NextHop } else { $null }) $(if ($PSBoundParameters.ContainsKey('InterfaceAlias')) { $InterfaceAlias } else { $null }) ) if ($isLocal) { $rawResults = & $queryScriptBlock @queryArgs } else { $invokeParams = @{ ComputerName = $targetComputer ScriptBlock = $queryScriptBlock ArgumentList = $queryArgs ErrorAction = 'Stop' } if ($hasCredential) { $invokeParams['Credential'] = $Credential } $rawResults = Invoke-Command @invokeParams } foreach ($entry in $rawResults) { [PSCustomObject]@{ PSTypeName = 'PSWinOps.NetworkRoute' ComputerName = $targetComputer DestinationPrefix = $entry.DestinationPrefix NextHop = $entry.NextHop InterfaceAlias = $entry.InterfaceAlias InterfaceIndex = $entry.InterfaceIndex RouteMetric = $entry.RouteMetric AddressFamily = $entry.AddressFamily Protocol = $entry.Protocol Store = $entry.Store Timestamp = $timestamp } } } catch { Write-Error "[$($MyInvocation.MyCommand)] Failed on '$targetComputer': $_" } } } end { Write-Verbose "[$($MyInvocation.MyCommand)] Completed network route query" } } |