IP Address resolution

Hi -

I’m trying something pretty simple. I’ve got a list of IP addresses, and I’m trying to run it through a powershell script to get the hostname. Here’s the code I’m trying (I’ve left out the for-each loop, for brevity):

$ipaddress = "IP address to resolve"

[System.Net.DNS]::GetHostByAddress($ipaddress).hostname

The issue is, I’m getting the following error:

Exception calling “GetHostByAddress” with “1” argument(s): “The requested name is valid, but no data of the requested type was found”

I can ping and do an nslookup successfully to that IP address, but Powershell doesn’t seem to want any part of it.

Any advice would be greatly appreciated.

Thanks.

You could try

[System.Net.Dns]::gethostentry($ipaddress).hostname

Here you go, this will resolve the issue. Yes, the pun is intended. :smiley:

By chance are you needing to use IPv6 as well? If so why not just Resolve-DNSName?

$IPAddressList = '8.8.8.8', '8.8.4.4'

Foreach ($IPAddress in $IPAddressList){

}

[quote quote=172075]Here you go, this will resolve the issue. Yes, the pun is intended. :grinning:

By chance are you needing to use IPv6 as well? If so why not just Resolve-DNSName?

PowerShell
7 lines
<textarea class="ace_text-input" style="opacity: 0; height: 18px; width: 7px; left: 44px; top: 0px;" spellcheck="false" wrap="off"></textarea>
1
2
3
4
5
6
7
$IPAddressList = '8.8.8.8', '8.8.4.4'
Foreach ($IPAddress in $IPAddressList){
[system.net.dns]::Resolve($IPAddress).HostName
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[/quote]

Your idea to use “resolve-DNSName” gave me an idea to modify your code to use that command instead of “[system.net.dns]::Resolve($IPAddress).HostName”:

$IPList = '1.1.1.1','8.8.8.8'

foreach ($IP in $IPList) {
    Resolve-DnsName $IP | Select-Object -Property NameHost
}

Nothing exciting but it offers another option for users. Now of course Mike can import his IP list via “Get-Content” or “Import-CSV” depending on what type of file he is using.

Thanks to both of you. Follow-up question: How do I export that to a csv? I’ve tried export-csv & out-file and neither one gives me quite what I’m looking for. I’d like to have a 2-column csv file, with the IP in one column and the machine name in the other. Here’s the code I’m using:

$IPList = Get-Content -Path C:\unresolvedIPs.txt
foreach ($IP in $IPList) {
$machine = Resolve-DnsName $IP | Select-Object -Property NameHost
If($error.Count -gt "0"){
$problem = $IP + " - " + $error[0].Exception.Message
Out-File -FilePath C:\resolveiplog.csv -InputObject $problem -Append
$error.Clear()
}
Else{
$success = $ip,$machine
Out-File -FilePath C:\resolveiplog.csv -InputObject $success -Append
}
}

I’m getting a bit of a jumble for this:

NameHost -------- <machine name>x.x.x.
NameHost
--------
<machine name>
x.x.x.x

Mike,

Here you go let me know if this works for you.

<script src=“https://gist.github.com/JasonRobertson/6bdb1eedeb4ba74935dea3d28d771a01.js”></script>

Thanks, Jason - I tried your code, but got this error on the screen:

 

HostName IPAddress


Microsoft.DnsClient.Commands.DnsRecord_PTR <IP Address>
Exception calling “Add” with “1” argument(s): “Collection was of a fixed size.”
At line:16 char:9

  • $Results.Add($Object)
  • CategoryInfo : NotSpecified: (:slight_smile: , MethodInvocationException
  • FullyQualifiedErrorId : NotSupportedException

Hey Mike,

Sorry about that two errors were in the script. Forgot the $ for the $IP in IPAddress. We will use the += method instead of the Add method for whatever reason it’s not liking that method. This can be fixed by using the ArrayList type, but that more than we need here. I noticed you are outputting the errors to CSV file as well? Are you wanting this to have an error in the .csv file as well?

foreach ($IP in $IPList) {
   #Create a ps custom object to allow what properties and values you desire.Use PSCustomOBject and Ordered to simplify code.
   $Object= [PSCustomObject][Ordered]@{
      HostName=Resolve-DNSName$ip
      IPAddress=$IP
   }
   If($error.Count-gt"0"){
      $problem=$IP + " - " + $error[0].Exception.Message
      Out-File-FilePath C:\resolveiplog.csv -InputObject $problem -Append
      $error.Clear()
   }
   Else{
      Write-Output $Object
      $Results+=$Object
   }
}
$Results | Export-CSV -NoTypeInformation -Path C:\Users\e5zbk8h\resolveiplog.csv

Hi, Jason - tried your code and got another error :frowning: :

Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named ‘op_Addition’.
At line:15 char:7

  • $Results+=$Object
  • CategoryInfo : InvalidOperation: (op_Addition:String) , RuntimeException
  • FullyQualifiedErrorId : MethodNotFound

 

In answer to your question about the .csv file, I’m writing it to a .csv so that I can sort the output by the results (either a machine name or an error message).

Mike, can you paste the complete code set you are running?
Did you append variables to his code? I’m not seeing a call to “op_addition in” his code sample.

 

Edit: - may be an issue with the += method.

Try this…

$IPList | ForEach-Object {
   #Create a ps custom object to allow what properties and values you desire. Use PSCustomOBject and Ordered to simplify code.
   $Object = [PSCustomObject]@{
      HostName  = Resolve-DNSName $ip
      IPAddress = $_
   }
   
   if($error.Count- gt "0") {
      "$_-$($error[0].Exception.Message)" | Add-Content -Path "C:\resolveiplog.csv"
      $error.Clear()
   }
   else{
      $Object
   }
} | Export-CSV -NoTypeInformation -Path "C:\Users\e5zbk8h\resolveiplog.csv"

FWIW the .Add() method was failing because you’re trying to use it on an array. Arrays are, as the error indicates, fixed size; you can’t actually add things to them. I’m guessing something in the way you attempted to put in the += solution didn’t quite go right, which is why that errored.

Even when it doesn’t error, though, I’d recommend not using that unless you know for an absolute fact that the collections you’ll be working with will be fairly small. += operations on arrays (remember, they can’t change size) basically destruct the whole array, put the items in a new array, and then give it back to you. When you do this repeatedly, you pile on overhead with every single += operation, which can very easily get unwieldy.

Alternate solution with regular foreach:

$Results = foreach ($IP in $IPList) {
    # Create a ps custom object to allow what properties and values you desire.Use PSCustomOBject and Ordered to simplify code.
    $Object = [PSCustomObject]@{
        HostName  = Resolve-DNSName $ip
        IPAddress = $IP
    }

    if($error.Count -gt "0") {
        "$IP-$($error[0].Exception.Message)" | Add-Content -Path "C:\resolveiplog.csv"
        $error.Clear()
    }
    else {
        $Object
    }
}

$Results | Export-CSV -NoTypeInformation -Path "C:\Users\e5zbk8h\resolveiplog.csv"

Joel,

Great alternative! Sorry had some account issues and couldn’t respond in a timely manner. Below is the results I have with the updated code. It will take into account the error as well now. I used [System.Collections.ArrayList] to resolve the array issue. I would recommend reading up on it if anyone is not familiar with it. I included a few more note properties to make life a bit easier when attempting to filter in Excel/Google Sheets. I would also add this code was written in PowerShell Version 5.1 if you are using an earlier version of PowerShell it may not work. You can find out the version by using $PSVersionTable.PSVersion.

<script src=“https://gist.github.com/JasonRobertson/6bdb1eedeb4ba74935dea3d28d771a01.js”></script>

ArrayList is disrecommended by the .NET documentation for any new code – see the remarks section here: ArrayList Class (System.Collections) | Microsoft Docs

Instead, [System.Collections.Generic.List[object]] should be used for heterogenous / nonspecific list types, and System.Collections.Generic.List[T]] for specific list types, where [T] is the type of object the list should be holding.

Also, you don’t really need to manage your own collections a lot of the time; in my example above the result will end up as a standard fixed-size array, without any of the pitfalls of trying to add to arrays. PowerShell’s internal pipeline code handles the collation of the results, which uses an ArrayList anyway, and gives you back a simple array at the end once the collection is complete. While you can and do sometimes need to use your own ArrayList or List[T] collections, if you’re not doing something overly complex you can usually avoid adding on extra overhead, since there’s already an arraylist in PowerShell’s pipeline logic that it will use for this kind of thing if you code it in a way PS can handle. :slight_smile:

Joel,

Awesome data to have for future code!