Welcome Forums General PowerShell Q&A IP Address resolution

Viewing 13 reply threads
  • 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: 2
      Replies: 1736
      Points: 3,552
      Helping Hand
      Rank: Community Hero

      You could try

      [System.Net.Dns]::gethostentry($ipaddress).hostname
    • #172075
      Participant
      Topics: 0
      Replies: 115
      Points: 433
      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

      <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

      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 -------- <machine name>x.x.x.
      NameHost
      --------
      <machine name>
      x.x.x.x
    • #172612
      Participant
      Topics: 0
      Replies: 115
      Points: 433
      Helping Hand
      Rank: Contributor

      Mike,

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

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

    • #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 <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: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : NotSupportedException

    • #172903
      Participant
      Topics: 0
      Replies: 115
      Points: 433
      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: 512
      Points: 1,309
      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: 115
      Points: 433
      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.

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

    • #173131
      Participant
      Topics: 2
      Replies: 512
      Points: 1,309
      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: 115
      Points: 433
      Helping Hand
      Rank: Contributor

      Joel,

      Awesome data to have for future code!

Viewing 13 reply threads
  • The topic ‘IP Address resolution’ is closed to new replies.