Powershell DNS reverse and MX lookup

Hallo zusammen,

Kürzlich musste ich eine grössere Liste von IP Adressen auflösen - dazu habe ich mir kurzerhand ein Powershell Script geschrieben.

Die IP's sind in einer CSV Datei

Das CSV wird eingelesen und für jede IP wird ein DNS Reverse Lookup gemacht. Die Ausgabe erfolgt direkt in die Konsole.

###############################################################################
# Reverse DNS Lookup with Powershell v1.0
# 27.01.2013 A.Bohren - http://blog.icewolf.ch
###############################################################################

$List = Import-CSV C:\Temp\ip.csv
Foreach ($entry in  $list)
{
 Try
 {
  Try
  {
   $x = [System.Net.Dns]::GetHostbyAddress($entry.IP)
   write-host $entry.IP $x.Hostname -ForegroundColor green
  } catch {
   throw $_.exception
  }
 } catch [System.Management.Automation.MethodInvocationException] {
  #Write-Host "MethodInvocationException " -ForegroundColor cyan
  write-host $entry.IP "DNS Entry not found" -ForegroundColor red
 }
}

Leider kann man mit den Dotnet Klassen per Default nur Forward und Reverse Lookups machen. Jedoch keine MX DNS Query. Jemand hat dafür aber eine Powershell Klasse gemacht, welche man dann benutzen kann

 
####################
### Function to get the MX Records for a domain
### Usage: Get-DnsMXQuery -DomainName "gmail.com"
 
function Get-DnsAddressList
{
    param(
        [parameter(Mandatory=$true)][Alias("Host")]
          [string]$HostName)
 
    try {
        return [System.Net.Dns]::GetHostEntry($HostName).AddressList
    }
    catch [System.Net.Sockets.SocketException] {
        if ($_.Exception.ErrorCode -ne 11001) {
            throw $_
        }
        return = @()
    }
}
 
function Get-DnsMXQuery
{
    param(
        [parameter(Mandatory=$true)]
          [string]$DomainName)
 
    if (-not $Script:global_dnsquery) {
        $Private:SourceCS = @'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
 
namespace PM.Dns {
  public class MXQuery {
    [DllImport("dnsapi", EntryPoint="DnsQuery_W", CharSet=CharSet.Unicode, SetLastError=true, ExactSpelling=true)]
    private static extern int DnsQuery(
        [MarshalAs(UnmanagedType.VBByRefStr)]
        ref string pszName,
        ushort     wType,
        uint       options,
        IntPtr     aipServers,
        ref IntPtr ppQueryResults,
        IntPtr pReserved);
 
    [DllImport("dnsapi", CharSet=CharSet.Auto, SetLastError=true)]
    private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType);
 
    public static string[] Resolve(string domain)
    {
        if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            throw new NotSupportedException();
 
       List<string> list = new List<string>();
 
        IntPtr ptr1 = IntPtr.Zero;
        IntPtr ptr2 = IntPtr.Zero;
        int num1 = DnsQuery(ref domain, 15, 0, IntPtr.Zero, ref ptr1, IntPtr.Zero);
        if (num1 != 0)
            throw new Win32Exception(num1);
        try {
            MXRecord recMx;
            for (ptr2 = ptr1; !ptr2.Equals(IntPtr.Zero); ptr2 = recMx.pNext) {
                recMx = (MXRecord)Marshal.PtrToStructure(ptr2, typeof(MXRecord));
                if (recMx.wType == 15)
                   list.Add(Marshal.PtrToStringAuto(recMx.pNameExchange));
            }
        }
        finally {
            DnsRecordListFree(ptr1, 0);
        }
 
        return list.ToArray();
    }
 
    [StructLayout(LayoutKind.Sequential)]
    private struct MXRecord
    {
        public IntPtr pNext;
        public string pName;
        public short  wType;
        public short  wDataLength;
        public int    flags;
        public int    dwTtl;
        public int    dwReserved;
        public IntPtr pNameExchange;
        public short  wPreference;
        public short  Pad;
    }
  }
}
'@
 
        Add-Type -TypeDefinition $Private:SourceCS -ErrorAction Stop
        $Script:global_dnsquery = $true
    }
 
    [PM.Dns.MXQuery]::Resolve($DomainName) | % {
        $rec = New-Object PSObject
        Add-Member -InputObject $rec -MemberType NoteProperty -Name "Host"        -Value $_
        Add-Member -InputObject $rec -MemberType NoteProperty -Name "AddressList" -Value $(Get-DnsAddressList $_)
        $rec
    }
}
 
### END Function ##################################

Mit dem untenstehenden Befehl kann man nun DNS MX Abfragen machen

Get-DnsMXQuery -DomainName bluewin.ch

Speichert man das Resultat in einer Variable (hier $mx) sieht man, dass das ganze ein Array ist.

$mx = Get-DnsMXQuery -DomainName bluewin.ch
$mx.GetType()
$mx.host
$mx.AddressList.IPAddressToString

Grüsse
Andres Bohren