IP Address resolution

Welcome Forums General PowerShell Q&A IP Address resolution

This topic contains 13 replies, has 6 voices, and was last updated by

 
Participant
3 weeks, 3 days ago.

  • Author
    Posts
  • #172024

    Participant
    Topics: 7
    Replies: 12
    Points: 34
    Rank: Member

    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.

  • #172027

    Participant
    Topics: 1
    Replies: 1529
    Points: 2,587
    Helping Hand
    Rank: Community Hero

    You could try

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

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

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

    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){
    
    [system.net.dns]::Resolve($IPAddress).HostName
    
    }
  • #172324

    Participant
    Topics: 0
    Replies: 1
    Points: 8
    Rank: Member

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

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

    PowerShell
    7 lines

    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

    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.

  • #172606

    Participant
    Topics: 7
    Replies: 12
    Points: 34
    Rank: Member

    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 -------- x.x.x.
    NameHost
    --------
    x.x.x.x
  • #172612

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    Mike,

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

  • #172888

    Participant
    Topics: 7
    Replies: 12
    Points: 34
    Rank: Member

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

     

    HostName IPAddress
    ——– ———
    Microsoft.DnsClient.Commands.DnsRecord_PTR
    Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
    At line:16 char:9
    + $Results.Add($Object)
    + ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NotSupportedException

  • #172903

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    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
  • #172978

    Participant
    Topics: 7
    Replies: 12
    Points: 34
    Rank: Member

    Hi, Jason – tried your code and got another error 🙁 :

    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).

  • #172984

    Participant
    Topics: 8
    Replies: 17
    Points: 127
    Rank: Participant

    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.

  • #173005

    Participant
    Topics: 2
    Replies: 483
    Points: 1,151
    Helping Hand
    Rank: Community Hero

    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"
  • #173011

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    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.

  • #173131

    Participant
    Topics: 2
    Replies: 483
    Points: 1,151
    Helping Hand
    Rank: Community Hero

    ArrayList is disrecommended by the .NET documentation for any new code — see the remarks section here: https://docs.microsoft.com/en-us/dotnet/api/system.collections.arraylist?view=netframework-4.8#remarks

    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. 🙂

  • #173188

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    Joel,

    Awesome data to have for future code!

You must be logged in to reply to this topic.