PowerShell: Resolve partial computer names, CNAME’s & IP Addresses to concrete Host name / IP

One can refer to a host by several means.

Where I am at, we generously use CNAME’s to point to host to insulate the applications from having to change when then hostname changes.

For example, if the hostname for Dev SQL Server is ddxumapDEV, then we might have a cname entry that says “Dev-SQL”. All the developers will use “Dev-SQL” in their code and configuration. Everything from ping to other forms references will work as if we referred to the hostname directly although the DNS CNAME entry does all the magic behind the scenes.

We have simplified access and downtime if things were to change. However, there are multiple ways the same host can be referenced

  • ddxumapDEV
  • ddxumapDEV.mycompany.something
  • ddxumapDev.somethingelse
  • Dev-SQL
  • 20.33.221.211

Programmatically, I would like to resolve them to the actual hostname and IP address no matter how they are referenced. This is so that I have a single name by which I can reference each host for whatever my need might be.

In my case, I am trying catalog all the hosts and the aliases they are referenced by.

Below is my function

#Key Source: http://windowsitpro.com/powershell/powershell-one-liner-quickly-finding-ip-address-hostname-and-vice-versa

#######################
<#
.SYNOPSIS
    Given a name or IP address, resolves the details to the actual hostname + IP

.DESCRIPTION 

    The parameter specified could be one of the following
    1) ComputerName without domain name suffix
    2) ComputerName with domain suffix
    3) CNAME (DNS entry)
    4) IP Address

    Given any of the above, this function resolves it to an actual host and IP address. 

    If there is an error, populates columns IsError and Error appropriately

    Also, see https://support.dnsimple.com/articles/differences-between-a-cname-alias-url/

.INPUTS
    Computer/IP list as pipeline input

.OUTPUTS
    HostName + IP + Error information

.EXAMPLE 

    #Check the members available in the result
    Resolve-HostNameOrAddress | Get-Member

.EXAMPLE 

    #Basic example
    Resolve-HostNameOrAddress | ft

.EXAMPLE 

    #Get OS information from multiple computers

    'mydevhost','myqacname','actualhostname','10.22.212.211' | Resolve-HostNameOrAddress | ft -GroupBy Name -auto

.EXAMPLE 

    #Get OS information from multiple computers - some are bad computer names.

    'mydevhost','myqacname','actualhostname','10.22.212.211' | Resolve-HostNameOrAddress | ft

.EXAMPLE 

    #Get OS information from multiple computers - some are bad computer names. Warnings are supressed

    'mydevhost','myqacname','actualhostname','10.22.212.211'  | Resolve-HostNameOrAddress -WarningAction silentlyContinue | ft

.EXAMPLE 

    #Get OS information from multiple computers (some are bad computer names). Check IsError and Error properties + supresses warning messages

    'mydevhost','myqacname','actualhostname','10.22.212.211' | Resolve-HostNameOrAddress -WarningAction silentlyContinue | Where-Object {$_.IsError -eq 'Y'} | Select-Object ComputerName, IPAddressString, IsError, Error

.EXAMPLE 

    #Depends on: http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0#content
    #Get OS info from multiple computers **** asynchronously *****

    #$servers = Get-Content c:\_dblog\servers.txt
    $servers = @('mydummyhost','mydevhost','myqahost','myanotherhost','10.22.212.211')
    [ScriptBlock] $sb =
            {
                param
                    (
                        [string] $ComputerName,
                        [string] $BasePath
                    )

                #------------------------------------------------------------------------------------------------------------
                #Remember that this script block will run in a separate PowerShell session and anything it needs needs to be imported/dot-sourced!
                #------------------------------------------------------------------------------------------------------------
                . "$BasePath\PoShLib\Computer\Resolve-HostNameOrAddress.ps1"
                #. $BasePath\Import-Essentials.ps1
                #Import-Essentials -BasePath $BasePath

                Resolve-HostNameOrAddress -ComputerName $ComputerName
            }

     #Build the variable need to splat the parameters (for the other parameters outside the list to iterate thru)
    $params = @{
                    Basepath = Get-PoShBasePath
                }   

    $rtn = Invoke-Async -Set $servers -SetParam ComputerName -Params $params -ScriptBlock $sb -Verbose -Measure:$true -ThreadCount 3

    $rtn | select-object -expand output

.NOTES
    Excellent and crisp example of how to get pipleline input + addl. inputs     

Version History
    Base idea from URL referenced at the very top

.LINK
    http://windowsitpro.com/powershell/powershell-one-liner-quickly-finding-ip-address-hostname-and-vice-versa

#>
function Resolve-HostNameOrAddress
{
    [CmdletBinding()]
    param
    (
        [Parameter(Position=0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [Alias('HostName')]
        [Alias('cn')]
        [Alias('ComputerName')]
        [Alias('IPAddress')]
        [string[]]$NameOrIPAddress = $env:COMPUTERNAME
    )

    BEGIN
    {
    }

    PROCESS
    {
        foreach ($computer in $NameOrIPAddress)
        {
            try
            {
                #Ref: http://stackoverflow.com/questions/5901082/using-regular-exprestion-to-validate-ip-address-in-powershell
                [bool]$isIPAddress = [bool]($computer -as [ipaddress])                

                if ($isIPAddress -eq $true)
                {
                    $ip1 = $computer
                    $host1 = [System.Net.Dns]::GetHostbyAddress($computer)
                }
                else
                {
                    $ip1 = [System.Net.Dns]::GetHostAddresses($computer)
                    $host1 = [System.Net.Dns]::GetHostbyAddress($ip1.IPAddressToString)
                }

                #If the host has an IPAddressList, it will be in $host1.AddressList
                New-Object psobject -Property @{
                                    Input        = $computer
                                    IPAddressString = $ip1.IPAddressToString
                                    ComputerName = $host1.HostName
                                    IPAddress    = $ip1
                                    Host         = $host1
                                    IsError      = 'N'
                                    Error        = $null
                                }

            }
            catch
            {
                $err = $_.Exception

                New-Object psobject -Property @{
                                    Input        = $computer
                                    IPAddressString = $null
                                    ComputerName = $null
                                    IPAddress    = $null
                                    Host         = $null
                                    IsError      = 'Y'
                                    Error        = $err
                                }

                Write-Warning "$computer - $err"
            }
        }
    }

    END {}
}

The output columns are shown below

PS C:\> Resolve-HostNameOrAddress | Get-Member

Name            MemberType  Definition
----            ----------   ----------
Equals          Method       bool Equals(System.Object obj)
GetHashCode     Method       int GetHashCode()
GetType         Method       type GetType()
ToString        Method       string ToString()
ComputerName    NoteProperty  ComputerName=null
Error           NoteProperty System.Management.Automation.MethodInvocationException Error=System.Management.Automation.MethodInvocationExc...
Host            NoteProperty  Host=null
Input           NoteProperty System.String Input=DKKDKKDKKKA
IPAddress       NoteProperty  IPAddress=null
IPAddressString NoteProperty  IPAddressString=null
IsError         NoteProperty System.String IsError=Y
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s