PowerShell dig (nslookup) Cmdlet!

So, today someone came to #PowerShell on irc.freenode.net and asked how to do nslookup functionality natively in PowerShell, and nobody knew how … and then as the question evolved, it turned out that what they needed was to do a lookup for both MX and TXT records for a series of domains …

To cut a long story short, I took some code from CodeProject and whipped up Get-DNS and a PoshNet snapin module which you can download here (source here under GPL).

It has an -EmulateDig switch to produce output similar to what you would see from the dig command, and otherwise produces an object with all the information in it. I’ll be cleaning this up in the future, but for now the main use is quite simple:

Get-Dns [-Name] <String> [[-Type] <QueryType[]>] [[-Class] <QueryClass>] [-DnsServers <String[]>] [-EmulateDigOutput]

The mandatory parameter is the domain Name of the computer to look up, of course … which you can pass on the pipeline. Pretty much every DNS record type ever created is allowed, including dozens I’ve never heard of — you can get a list by calling Get-DNS -Type "" :) And you can specify the class as IN, CS, CH, HS, or ANY (the default).

[new] Update: Now with -DnsServers

[new] In this new release (Nov 20, 2008) you have the -DnsServers parameter which accepts one or more dns server ip addresses. NOTE: they must be IP Addresses, not domain names (sorry, I was lazy, Maybe if someone I’ll make sure that gets tweaked eventually). You may include the port (eg: 71.6.202.220:53) but you don’t have to unless it’s non-standard (ie: not port 53). You may specify multiple servers if you need a fallback … and as always, if you leave it off, the cmdlet will use your default DNS servers.

Installation

On PowerShell 2 you can install this by just calling Add-Module .\PoshNet.dll (or by putting it in a folder in your PSModulePath, like … Documents\WindowsPowerShell\Modules\PoshNet and then you can just Add-Module PoshNet). On the PowerShell 1.0 release, you need to use InstallUtil.exe to install it, so I’ve included a “Install.ps1” script which should let you call: .\Install.ps1 PoshNet.dll from an elevated console:


Extract-Archive PoshNet.zip      # Unzip the archive somewhere...
.\Install.ps1 PoshNet.dll        # Run InstallUtil.exe on the dll
Get-PsSnapin -registered PoshNet # Verify that PoshNet is installed
Add-PsSnapin PoshNet             # Load it. (Add this to your profile?)
Get-Command -PsSnapin PoshNet    # Verify that it is loaded...

Example uses


[1]: Get-Dns HuddledMasses.org -EmulateDig
; <<>> Dig.Net 1.0.0.0 <<>> @24.92.226.40 A HuddledMasses.org
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: Query, status: NoError, id: 20722
;; flags:  qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 0

;; QUESTION SECTION:
;HuddledMasses.org.                     IN      A

;; ANSWER SECTION:
HuddledMasses.org.               85847  IN      A       72.232.199.162

;; AUTHORITY SECTION:
HuddledMasses.org.               85252  IN      NS      ns2.us.editdns.net.
HuddledMasses.org.               85252  IN      NS      ns3.us.editdns.net.
HuddledMasses.org.               85252  IN      NS      ns1.us.editdns.net.

;; Query time: 23 msec
;; SERVER: 24.92.226.40#53(24.92.226.40)
;; WHEN: Thu Sep 18 21:18:22 2008
;; MSG SIZE rcvd: 119

You can also ask for multiple record types at once, to solve the original question that was asked on IRC:


[2]: Get-DNS HuddledMasses.org MX,TXT | fl RecordsMX,RecordsTxt,MessageSize,TimeStamp

RecordsMX   : {1 aspmx.l.google.com., 5 alt1.aspmx.l.google.com., 5 alt2.aspmx.l.google.com.,
              10 aspmx2.googlemail.com., 10 aspmx3.googlemail.com., 10 aspmx4.googlemail.com.,
              10 aspmx5.googlemail.com.}
RecordsTXT  : {"v=spf1 include:_spf.google.com -all"}
MessageSize : 458
TimeStamp   : 9/18/2008 9:22:40 PM

Of course, the other part of the request is that you need to be able to query a whole list of servers, so you can do that, for instance, by having a file with a domain per line, or whatever. Also, for the sake of this last example, recall that unlike the linux “dig” command, we can output everything as an object (like we did above) and all of the Records* types are collections of objects, so you can expand them, and enumerate or format them. Play with the “Answers” collection:


[3]: cat Servers.txt | get-dns -type MX,TXT | select -expand Answers | ft -auto

  TTL NAME               Type Class RDLENGTH RECORD                                TimeLived
  --- ----               ---- ----- -------- ------                                ---------
 3600 geoshell.org.        MX    IN       25 10 ASPMX4.GOOGLEMAIL.COM.                     0
 3600 geoshell.org.        MX    IN       11 10 ASPMX5.GOOGLEMAIL.COM.                     0
 3600 geoshell.org.        MX    IN       24 5 ALT1.ASPMX.L.GOOGLE.COM.                    0
 3600 geoshell.org.        MX    IN        9 5 ALT2.ASPMX.L.GOOGLE.COM.                    0
 3600 geoshell.org.        MX    IN        4 1 ASPMX.L.GOOGLE.COM.                         0
 3600 geoshell.org.        MX    IN       11 10 ASPMX2.GOOGLEMAIL.COM.                     0
 3600 geoshell.org.        MX    IN       11 10 ASPMX3.GOOGLEMAIL.COM.                     0
84628 huddledmasses.org.   MX    IN       25 10 aspmx3.googlemail.com.                     0
84628 huddledmasses.org.   MX    IN       11 10 aspmx4.googlemail.com.                     0
84628 huddledmasses.org.   MX    IN       11 10 aspmx5.googlemail.com.                     0
84628 huddledmasses.org.   MX    IN       19 1 aspmx.l.google.com.                         0
84628 huddledmasses.org.   MX    IN        9 5 alt1.aspmx.l.google.com.                    0
84628 huddledmasses.org.   MX    IN        9 5 alt2.aspmx.l.google.com.                    0
84628 huddledmasses.org.   MX    IN       11 10 aspmx2.googlemail.com.                     0
86156 huddledmasses.org.  TXT    IN       36 "v=spf1 include:_spf.google.com -all"         0
 3600 helpfulmom.com.      MX    IN       22 10 ASPMX2.GOOGLEMAIL.com.                     0
 3600 helpfulmom.com.      MX    IN       11 10 ASPMX3.GOOGLEMAIL.com.                     0
 3600 helpfulmom.com.      MX    IN       11 10 ASPMX4.GOOGLEMAIL.com.                     0
 3600 helpfulmom.com.      MX    IN       11 10 ASPMX5.GOOGLEMAIL.com.                     0
 3600 helpfulmom.com.      MX    IN       24 5 ALT1.ASPMX.L.GOOGLE.com.                    0
 3600 helpfulmom.com.      MX    IN        9 5 ALT2.ASPMX.L.GOOGLE.com.                    0
 3600 helpfulmom.com.      MX    IN        4 1 ASPMX.L.GOOGLE.com.                         0

Similar Posts:

7 thoughts on “PowerShell dig (nslookup) Cmdlet!”

  1. You can also do this with the get-dns cmdlet that is included in NetCmdlets.

    NetCmdlets has a free hobbyist license listed on its sales page too.

  2. thanks joel!

    i’m sure ‘somebody’ is very happy that you did this!

    - somebody

  3. @seaJhawk You’re welcome ;-)

    @Lance Robinson Yeah, “hobbyist” licenses remind me a bit of the whole “first hit’s free” marketing plan ;) ... but I didn’t even think theirs might support looking up different types at once, good job.

    I should check theirs out to see how they format their output. This class from CodePlex is dying for a decent ps1xml format file with some scripting to unwrap things. ;)

  4. I’m having some issues on PS1 with the install. After running the install script I don’t see any new snapins or the get-dns cmdlet.

    I’ve pasted the results of the install here and the contents of the _installed.InstallLog file follows.

    PS C:\toolbox\Scripts\dlls> .\install-poshnet.ps1 .\poshnet.dll
    Microsoft® .NET Framework Installation utility Version 2.0.50727.1434
    Copyright© Microsoft Corporation. All rights reserved.

    The uninstall is beginning.
    See the contents of the log file for the C:\toolbox\Scripts\dlls\_installed.dll assembly’s progress.
    The file is located at C:\toolbox\Scripts\dlls\_installed.InstallLog.
    Uninstalling assembly ‘C:\toolbox\Scripts\dlls\_installed.dll’.
    Affected parameters are:
    logtoconsole =
    assemblypath = C:\toolbox\Scripts\dlls\_installed.dll
    showcallstack =
    logfile = C:\toolbox\Scripts\dlls\_installed.InstallLog

    The uninstall has completed.
    Microsoft® .NET Framework Installation utility Version 2.0.50727.1434
    Copyright© Microsoft Corporation. All rights reserved.

    Running a transacted installation.

    Beginning the Install phase of the installation.
    See the contents of the log file for the C:\toolbox\Scripts\dlls\_installed.dll assembly’s progress.
    The file is located at C:\toolbox\Scripts\dlls\_installed.InstallLog.
    Installing assembly ‘C:\toolbox\Scripts\dlls\_installed.dll’.
    Affected parameters are:
    logtoconsole =
    assemblypath = C:\toolbox\Scripts\dlls\_installed.dll
    showcallstack =
    logfile = C:\toolbox\Scripts\dlls\_installed.InstallLog

    The Install phase completed successfully, and the Commit phase is beginning.
    See the contents of the log file for the C:\toolbox\Scripts\dlls\_installed.dll assembly’s progress.
    The file is located at C:\toolbox\Scripts\dlls\_installed.InstallLog.
    Committing assembly ‘C:\toolbox\Scripts\dlls\_installed.dll’.
    Affected parameters are:
    logtoconsole =
    assemblypath = C:\toolbox\Scripts\dlls\_installed.dll
    showcallstack =
    logfile = C:\toolbox\Scripts\dlls\_installed.InstallLog

    The Commit phase completed successfully.

    The transacted install has completed.
    PS C:\toolbox\Scripts\dlls> Get-PSSnapin

    Name : Microsoft.PowerShell.Core
    PSVersion : 1.0
    Description : This Windows PowerShell snap-in contains Windows PowerShell management cmdlets used to manage components of Windows
    PowerShell.

    Name : Microsoft.PowerShell.Host
    PSVersion : 1.0
    Description : This Windows PowerShell snap-in contains cmdlets used by the Windows PowerShell host.

    Name : Microsoft.PowerShell.Management
    PSVersion : 1.0
    Description : This Windows PowerShell snap-in contains management cmdlets used to manage Windows components.

    Name : Microsoft.PowerShell.Security
    PSVersion : 1.0
    Description : This Windows PowerShell snap-in contains cmdlets to manage Windows PowerShell security.

    Name : Microsoft.PowerShell.Utility
    PSVersion : 1.0
    Description : This Windows PowerShell snap-in contains utility Cmdlets used to manipulate data.

    PS C:\toolbox\Scripts\dlls> gcm dns -commandType cmdlet

    Nothing Returned

    trimmed by Jaykul ;)
  5. Ok, the install.ps1 script just registers the snapin (although it should have made a copy named “PoshNet_installed.dll” not just “_installed.dll”, so that’s weird).

    Basically, it just runs InstallUtil.exe and it’s really for my purposes in development, because it copies the dll before registering it, so I can recompile even if the dll is loaded in a host.

    Assuming the install worked correctly, neither of the commands you ran is the right one to find it. You need to check for registered snapins, because the Install.ps1 script doesn’t Add-PSSnapin unless you pass it the -Add parameter.

    The full process is like this, and if you’re on Vista, you have to run install.ps1 in an elevated console. I’ve added this to the main post, but basically, you need to do something like this:

    Extract-Archive PoshNet.zip      # Unzip the archive somewhere...
    .\Install.ps1 PoshNet.dll        # Run InstallUtil on the assembly
    Get-PsSnapin -registered PoshNet # Verify that PoshNet is installed
    Add-PsSnapin PoshNet             # Load it. (Add this to your profile?)
    Get-Command -PsSnapin PoshNet    # Verify that it is loaded...
  6. That worked great!

    And amazingly, you managed to do something that the big boys (err… other big boys) can’t seem to do – you provided one snapin that works in both 32-bit and 64-bit PowerShell. I’m not sure if you intended to do that or not, but explaining it would sure make a great blog post because there are a lot of folks out there who need some help.

    You Rock!
    -Chris

  7. Hm? Was I not supposed to be able to do that? 8O

    Well, I’m honestly not sure what I did differently than anyone else. It’s a pretty straight-forward 32bit assembly project, with my cut-and paste version of a PSSnapin module. Anyone who wants to, is, of course, free to work from my GPL project template :D

Comments are closed.