Public/Get-IP.ps1
|
function Get-IP { <# .SYNOPSIS Displays a colorful, formatted table of network adapters (name, MAC, IP, DHCP status, gateway, DNS, etc.). .DESCRIPTION Shows all network adapters in a nicely aligned console table with colors. Works in PowerShell 5.1 legacy console (powershell.exe) and modern hosts. Uses native console color API — no ANSI escapes. .PARAMETER UpOnly Show only adapters where Status is 'Up' .PARAMETER SortBy Column to sort by. Default: Description (descending) .PARAMETER Descending Sort in descending order. Default: $true when SortBy = Description .EXAMPLE Get-IP .EXAMPLE Get-IP -UpOnly .EXAMPLE Get-IP -SortBy Name -Descending:$false #> [CmdletBinding()] [Alias('IP')] param( [switch] $UpOnly, [ValidateSet('Name', 'MAC', 'Description', 'Speed', 'Lnk', 'IPv4_Subnet', 'AddrType')] [string] $SortBy = 'Description', [switch] $Descending = $true ) # ============================================================================ # Helper Functions # ============================================================================ function Write-ColorLine { <# .SYNOPSIS Writes one adapter row, correctly handling multi-line values in any column. Uses $columnWidths for alignment. #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject] $Adapter ) # ================================================ # Step 1: Split every field into lines (even single-line becomes 1-element array) # ================================================ $lines = @{ Name = @([string]$Adapter.Name -split "`r`n|`n") MAC = @([string]$Adapter.MAC -split "`r`n|`n") Description = @([string]$Adapter.Description -split "`r`n|`n") Speed = @([string]$Adapter.Speed -split "`r`n|`n") Lnk = @([string]$Adapter.Lnk -split "`r`n|`n") IPv4_Subnet = @([string]$Adapter.IPv4_Subnet -split "`r`n|`n") AddrType = @([string]$Adapter.AddrType -split "`r`n|`n") Gateway = @([string]$Adapter.Gateway -split "`r`n|`n") DNS_Servers = @([string]$Adapter.DNS_Servers -split "`r`n|`n") } # ================================================ # Step 2: Find the maximum number of lines in this row # ================================================ $maxLines = 1 foreach ($key in $lines.Keys) { $count = $lines[$key].Count if ($count -gt $maxLines) { $maxLines = $count } } # ================================================ # Step 3: Write one visual row per line index # ================================================ for ($i = 0; $i -lt $maxLines; $i++) { # Name (Cyan) $text = if ($i -lt $lines.Name.Count) { $lines.Name[$i] } else { '' } Write-Host $text.PadRight($columnWidths.Name) -ForegroundColor Cyan -NoNewline # MAC (Magenta) $text = if ($i -lt $lines.MAC.Count) { $lines.MAC[$i] } else { '' } Write-Host $text.PadRight($columnWidths.MAC) -ForegroundColor Magenta -NoNewline # Description (Gray) $text = if ($i -lt $lines.Description.Count) { $lines.Description[$i] } else { '' } Write-Host $text.PadRight($columnWidths.Description) -ForegroundColor Gray -NoNewline # Speed (Yellow) $text = if ($i -lt $lines.Speed.Count) { $lines.Speed[$i] } else { '' } Write-Host $text.PadRight($columnWidths.Speed) -ForegroundColor Yellow -NoNewline # Lnk / Status (Green) $text = if ($i -lt $lines.Lnk.Count) { $lines.Lnk[$i] } else { '' } $color = if ($text -eq "Up") { [ConsoleColor]::Green } else { [ConsoleColor]::Red } Write-Host $text.PadRight($columnWidths.Lnk) -ForegroundColor $color -NoNewline # IPv4_Subnet (Cyan) $text = if ($i -lt $lines.IPv4_Subnet.Count) { $lines.IPv4_Subnet[$i] } else { '' } Write-Host $text.PadRight($columnWidths.IPv4_Subnet) -ForegroundColor Cyan -NoNewline # AddrType (already colored string) $text = if ($i -lt $lines.AddrType.Count) { $lines.AddrType[$i] } else { '' } $color = if ($text -eq "DHCP") { [ConsoleColor]::Green } else { [ConsoleColor]::Gray } Write-Host $text.PadRight($columnWidths.AddrType) -ForegroundColor $color -NoNewline # Gateway (Yellow) $text = if ($i -lt $lines.Gateway.Count) { $lines.Gateway[$i] } else { '' } Write-Host $text.PadRight($columnWidths.Gateway) -ForegroundColor Yellow -NoNewline # DNS_Servers (Magenta) $text = if ($i -lt $lines.DNS_Servers.Count) { $lines.DNS_Servers[$i] } else { '' } Write-Host $text.PadRight($columnWidths.DNS_Servers) -ForegroundColor Magenta -NoNewline # End of visual row Write-Host "" # new line after each visual row } } # ============================================================================ # Main Logic - Collect adapters # ============================================================================ $adapters = Get-NetAdapter | # Where-Object { $_.Status -eq 'Up' } | # uncomment to filter only Up ForEach-Object { $adapter = $_ # MAC formatting $MACraw = $adapter.MacAddress $MAC = if ($MACraw) { $MACraw = $MACraw -replace '-', ':' $MACraw -replace ':', '' } else { '<virtual>' } $ipConfig = Get-NetIPConfiguration -InterfaceAlias $adapter.Name -Detailed -ErrorAction SilentlyContinue 2>$null # All IPv4 addresses (array) $ipv4Addresses = $ipConfig.IPv4Address | Where-Object { $_.AddressFamily -eq 'IPv4' } | ForEach-Object { "$($_.IPAddress)/$($_.PrefixLength)" } # Status shorthand $Lnk = if ($adapter.Status -eq "Disconnected") { "Dwn" } else { $adapter.Status } # DHCP / Static $addrTypeRaw = if ($ipConfig.NetIPv4Interface.Dhcp -eq 'Enabled') { 'DHCP' } else { 'Static' } [PSCustomObject]@{ Name = $adapter.Name MAC = $MAC Description = $adapter.InterfaceDescription Speed = $adapter.LinkSpeed -replace ' ', '' Lnk = $Lnk IPv4_Subnet = if ($ipv4Addresses) { $ipv4Addresses -join "`n" } else { '<none>' } AddrType = $addrTypeRaw Gateway = ($ipConfig.IPv4DefaultGateway | Select-Object -First 1).NextHop DNS_Servers = ($ipConfig.DNSServer | Where-Object AddressFamily -eq 2 | Select-Object -ExpandProperty ServerAddresses) -join "`n" } } # ============================================================================ # Calculate automatic column widths (scan all rows) # ============================================================================ $columnWidths = @{ Name = 4 # minimum MAC = 3 Description = 11 Speed = 5 Lnk = 3 IPv4_Subnet = 9 # '<none>' AddrType = 6 Gateway = 7 DNS_Servers = 10 } foreach ($a in $adapters) { # Name if ($a.Name.Length -gt $columnWidths.Name) { $columnWidths.Name = $a.Name.Length } # MAC if ($a.MAC.Length -gt $columnWidths.MAC) { $columnWidths.MAC = $a.MAC.Length } # Description if ($a.Description.Length -gt $columnWidths.Description) { $columnWidths.Description = $a.Description.Length } # Speed if ($a.Speed.Length -gt $columnWidths.Speed) { $columnWidths.Speed = $a.Speed.Length } # Lnk if ($a.Lnk.Length -gt $columnWidths.Lnk) { $columnWidths.Lnk = $a.Lnk.Length } # AddrType if ($a.AddrType.Length -gt $columnWidths.AddrType) { $columnWidths.AddrType = $a.AddrType.Length } # Gateway if ($a.Gateway.Length -gt $columnWidths.Gateway) { $columnWidths.Gateway = $a.Gateway.Length } # DNS_Servers - longest line $dnsLines = $a.DNS_Servers -split "`n" foreach ($line in $dnsLines) { if ($line.Length -gt $columnWidths.DNS_Servers) { $columnWidths.DNS_Servers = $line.Length } } # IPv4_Subnet - longest line (after we pad internally) $ipLines = $a.IPv4_Subnet -split "`n" foreach ($line in $ipLines) { # Strip ANSI if any (though we don't use ANSI anymore) $cleanLine = $line -replace '\x1B\[[0-9;]*m', '' if ($cleanLine.Length -gt $columnWidths.IPv4_Subnet) { $columnWidths.IPv4_Subnet = $cleanLine.Length } } } # ============================================================================ # Pad IPv4_Subnet so slashes align (multi-line aware) # ============================================================================ $maxIpPartLength = 0 foreach ($a in $adapters) { $lines = $a.IPv4_Subnet -split "`n" foreach ($line in $lines) { if ($line -match '^([^/]+)') { $len = $Matches[1].Length if ($len -gt $maxIpPartLength) { $maxIpPartLength = $len } } elseif ($line.Length -gt $maxIpPartLength) { $maxIpPartLength = $line.Length } } } $adapters = $adapters | ForEach-Object { $lines = $_.IPv4_Subnet -split "`n" $padded = @() foreach ($line in $lines) { if ($line -match '^([^/]+)(/.*)?$') { $ip = $Matches[1] $rest = if ($Matches[2]) { $Matches[2] } else { '' } $pad = ' ' * ($maxIpPartLength - $ip.Length) $padded += $ip + $pad + $rest } else { $pad = ' ' * ($maxIpPartLength - $line.Length) $padded += $pad + $line } } $_.IPv4_Subnet = $padded -join "`n" $_ } # ============================================================================ # Output - Header + Data Rows # ============================================================================ # Clear-Host Write-Host "" # Header Write-Host ("{0,-$($columnWidths.Name-1)} {1,-$($columnWidths.MAC-1)} {2,-$($columnWidths.Description-1)} {3,-$($columnWidths.Speed-1)} {4,-$($columnWidths.Lnk-1)} {5,-$($columnWidths.IPv4_Subnet-2)} {6,-$($columnWidths.AddrType-1)} {7,-$($columnWidths.Gateway-1)} {8}" -f "Name", "MAC", "Description", "Speed", "Lnk", "IPv4_Subnet", "DHCP?", "Gateway", "DNS_Servers") ` -ForegroundColor White Write-Host ("-" * ($columnWidths.Values | Measure-Object -Sum).Sum) -ForegroundColor DarkGray # Data foreach ($a in ($adapters | Sort-Object Description -Descending)) { Write-ColorLine -Adapter $a Write-Host "" } } Export-ModuleMember -Function Get-IP -Alias IP |