When querying DNS records in PowerShell, many administrators encounter an unexpected output format. The common approach using [System.Net.Dns]::GetHostAddresses()
returns property bags rather than raw values, making pipeline processing cumbersome.
Here's what typically happens:
$computer = 'Server1'
$result = [System.Net.Dns]::GetHostAddresses($computer) | select IPAddressToString
$result.GetType().FullName # Returns System.Management.Automation.PSCustomObject
The output displays as @{IPAddressToString=x.x.x.x}
because PowerShell's Select-Object
creates custom objects with named properties.
Method 1: Direct Property Access
The simplest approach for single IP retrieval:
([System.Net.Dns]::GetHostAddresses('Server1')).IPAddressToString
Method 2: Expansion Operator
When you need the raw string value for further processing:
([System.Net.Dns]::GetHostAddresses('Server1') |
Select-Object -ExpandProperty IPAddressToString)
Method 3: Array Handling for Multiple IPs
For computers with multiple addresses:
[System.Net.Dns]::GetHostAddresses('Server1') |
ForEach-Object { $_.IPAddressToString }
Raw string output enables:
- Direct string manipulation
- Clean integration with logging systems
- Simpler conditional checks
- Better pipeline compatibility
Batch processing example for server lists:
$servers = 'Server1','Server2','Server3'
$servers | ForEach-Object {
[PSCustomObject]@{
Computer = $_
IP = ([System.Net.Dns]::GetHostAddresses($_)).IPAddressToString
}
}
Many PowerShell users encounter the same issue when trying to retrieve raw IP addresses from hostnames. The default output from [System.Net.Dns]::GetHostAddresses()
returns objects rather than simple string values, which creates formatting challenges.
When you execute:
$computer = 'Server1'
$result = [System.Net.Dns]::GetHostAddresses($computer) | select IPAddressToString
You get objects with properties rather than direct values. This is PowerShell's object-oriented nature at work.
Here are three reliable methods to extract just the IP address string:
1. Accessing the Property Directly
$ip = $result.IPAddressToString
# For multiple IPs:
$ips = $result | ForEach-Object { $_.IPAddressToString }
2. Using -ExpandProperty
$ip = [System.Net.Dns]::GetHostAddresses($computer) |
Select-Object -ExpandProperty IPAddressToString
3. Dot Notation Alternative
$ip = ([System.Net.Dns]::GetHostAddresses($computer)).IPAddressToString
For systems with multiple network interfaces:
$allIPs = [System.Net.Dns]::GetHostAddresses($computer) |
ForEach-Object { $_.IPAddressToString }
# Get first IP:
$primaryIP = $allIPs[0]
Here's how you might use this in a real script:
$servers = 'Server1','Server2','Server3'
$ipReport = foreach ($server in $servers) {
try {
$ip = ([System.Net.Dns]::GetHostAddresses($server)).IPAddressToString
[PSCustomObject]@{
ServerName = $server
IPAddress = $ip
}
}
catch {
Write-Warning "Failed to resolve $server"
}
}
$ipReport | Format-Table -AutoSize
The most efficient method for large-scale operations is direct property access:
# Fastest method for bulk operations
Measure-Command {
1..100 | ForEach-Object {
$ip = ([System.Net.Dns]::GetHostAddresses('localhost')).IPAddressToString
}
} | Select-Object TotalMilliseconds
Always include basic error handling:
try {
$ip = ([System.Net.Dns]::GetHostAddresses($computer)).IPAddressToString
if (-not $ip) { throw "No IP found" }
}
catch [System.Net.Sockets.SocketException] {
Write-Warning "Hostname resolution failed for $computer"
}
catch {
Write-Warning "General error occurred: $_"
}