Getting SRV Records with PowerShell
PowerShell leverages .NET, and .NET exposes the System.Net.Dns class, so all should be happy, no? Evidently not if it comes to SRV records. Someone asked me how to do it, and I said, “That’s easy. I’ll get back to you in a few.”
A few hours later, I realized it wasn’t so easy.
Get-NslookupSrvRecord mail.microsoft.com
VERBOSE: Get-NslookupSrvRecord -FQDN mail.microsoft.com
FQDN : microsoft.com
primary : ns1.msft.net
responsible : msnhst.microsoft.com
serial : 2014070205
refresh = 300 (5 mins) : 300 (5 mins)
retry : 600 (10 mins)
expire : 2419200 (28 days)
default : 3600 (1 hour)
Text : {}
Here’s the magic:
####################
function New-ObjectWithAddPropertyScriptMethod
####################
{
<#
.synopsis
Return a PSObject with AddProperty ScriptMethod
.description
Return a PSObject with AddProperty ScriptMethod that takes two positional arguments, Name and Value.
.example
$object = New-ObjectWithAddPropertyScriptMethod;
$object.AddProperty('username', 'johndoe');
#>
$record = New-Object -TypeName PSObject;
Add-Member -Name AddProperty -InputObject $record -MemberType ScriptMethod -Value {
if ($args.Count -eq 2)
{
($name, $value) = $args;
if (Get-Member -InputObject $this -Name $name)
{
$this.$name = $value;
} # if (Get-Member -InputObject $this -Name $name)
else
{
Add-Member -InputObject $this -MemberType NoteProperty -Name $name -Value $value;
} # if (Get-Member -InputObject $this -Name $name) ... else
} # if ($args.Count -eq 2)
} # Add-Member -Name AddProperty ...
$record;
} # function New-ObjectWithAddPropertyScriptMethod
####################
function Get-NslookupSrvRecord
####################
{
<#
.synopsis
Get SRV record for specified FQDN(s)
.description
PowerShell lacks a way to return SRV records because .NET lacks a way to return SRV records.
Does not return any data, warning, or errror if no SRV record found.
.oputputs
PSObject with properties
- FQDN: FQDN specified, which is the first line returned that does not begin with whitespace.
- Text: Array of any lines returned that do not begin with whitespace after the first one. Can be empty array.
- Other properties vary with the SRV record. Any line beginning with whitepsace is split into name/value pairs over the ' = ' delimiter.
.parameter FQDN
Specified FQDN(s) for which to attempt to return SRV records
.example
Get-NslookupSrvRecord mail.microsoft.com
#>
param(
[parameter(ValueFromPipeline=$true)][string[]]$FQDN
);
begin
{
$ErrorActionPreference = 'SilentlyContinue';
} # begin
process
{
foreach ($_fqdn in $FQDN)
{
$cmd = "set type=srv`n$fqdn";
Write-Verbose "$($MyInvocation.MyCommand.Name) -FQDN $_fqdn";
$record = $null;
$data = @()
$cmd | nslookup.exe 2>&1 |
? {
$_ -and
$_ -notmatch '^Address:' -and
$_ -notmatch '^Server:' -and
$_ -notmatch '^Default Server:' -and
$_ -notmatch '^>'
} |
% {
Write-Debug $_;
switch -Regex ($_)
{
"^[^\s]"
{
if ($record)
{
$data += $_;
} # if ($record)
else
{
$record = New-ObjectWithAddPropertyScriptMethod;
$record.AddProperty('FQDN', ($_ -replace '\s.*'));
} # if ($record) ... else
} # "[^\s]"
"^\s"
{
if ($_ -match ' = ')
{
$name = $_ -replace '^\s*' -replace '\s.* = .*';
$value = $_ -replace '.* = ' -replace '\s*$';
$record.AddProperty($name, $value);
} # if ($_ -match '\s')
else
{
$data += $_;
} # if ($_ -match '\s')
} # " = "
} # switch -Regex ($_)
} # $cmd | nslookup.exe
$record.AddProperty('Text', $data);
$record;
} # foreach ($_fqdn in $FQDN)
} # process
} # function Get-NslookupSrvRecord
Comments
- Anonymous
December 08, 2014
Thanks for this