powershell

Import list of IP, and then resolve-DNS for each of the IP address(es)


I wish to modify the below script, so the imported unique IP address from a text file can be translated into hostname in a separate.CSV file.

Get-ChildItem -Path C:\Logs\Input\ -Filter *.csv |
    Get-Content |
            Sort-Object -Unique | Sort -desc |
                Set-Content -Path C:\LOGS\Unique-$($ColumnNames).txt

Input:

12.34.56.78
111.222.333.444
8.8.8.8

Output:

12.34.56.78 - hosta.domain.com
111.222.333.444 - hostX.net
8.8.8.8 - something wrong

Solution

  • If your input & output files are CSV, then you should make use of the *-Csv cmdlets for importing and exporting files in CSV format.

    I'm assuming you want inputs and outputs similar to below.

    Input

    ips.csv

    12.34.56.78
    111.222.333.444
    8.8.8.8
    

    Output

    ips-hostnames.csv

    IpAddress,HostName
    12.34.56.78,hosta.domain.com
    111.222.333.444,hostX.net
    8.8.8.8,No such host is known.
    

    Demo

    $inputDirectory = "C:\Input"
    $outputDirectory = "C:\Output"
    
    # Create output directory if it doesn't exist
    if (-not(Test-Path -Path $outputDirectory -PathType Container)) {
        New-Item -Path $outputDirectory -ItemType Directory
    }
    
    # Go through each CSV file in input directory
    foreach ($csv in Get-ChildItem -Path $inputDirectory -Filter *.csv -Recurse) {
    
        # Import CSV contents with IpAddress header
        $csvFile = Import-Csv -Path $csv.FullName -Header IpAddress
    
        # Get output path of CSV
        $csvName = Split-Path -Path $csv.FullName -LeafBase
        $csvOutputFileName = "{0}-{1}.csv" -f  $csvName, "hostnames"
        $csvOutputPath = Join-Path -Path $outputDirectory -ChildPath $csvOutputFileName
        
        # Export to CSV file with IpAddress & HostName headers
        & {
            foreach ($ip in $csvFile.IpAddress) {
    
                # Attempt to fetch DNS hostname
                try {
                    [PSCustomObject]@{
                        IpAddress = $ip
                        HostName = [System.Net.Dns]::GetHostEntry($ip).HostName
                    }
                }
    
                # Could not resolve DNS hostname
                catch {
                    [PSCustomObject]@{
                        IpAddress = $ip
                        HostName = $_.Exception.InnerException.Message
                    }
                }
            }
        } | Export-Csv -Path $csvOutputPath -NoTypeInformation -UseQuotes AsNeeded
    }
    

    Explanation

    1. Import each CSV file contents with Import-Csv, making sure to set a header if the CSV file has no headers(seems to be the case from your input file).
    2. Create a CSV output path. You can decide what this can be, but something like ips-hostnames.csv should work. We can use Split-Path with -LeafBase to get the filename of the input CSV, then combine this with the output directory to create a full path using Join-Path.
    3. Create a PSCustomObject to represent the output CSV columns. You can have 2 columns for your IP addresses and hostnames.
    4. Use [System.Net.Dns]::GetHostEntry to resolve an IP to a DNS hostname, assuming reverse DNS lookups are configured already. We can wrap this in a try/catch block to catch an exception if the method could not resolve the DNS, and set the hostname entry to the exception message.
    5. Export output CSV files with Export-Csv.