Jul 11, 2012

Finding and Resolving IP's From Log Files with Powershell

Today I was given a fun little challenge from a friend. He needed to search through some server log files for IP addresses and recursively resolve hostnames from the found addresses. Considering this was on a Windows machine we made the obvious choice to play with Powershell. What came out is a useful script\function!

The script takes in an input file or folder, and an output file that ends up being a csv. With the input variable, it determines which you have provided, and moves on. If it is a folder, it recursively finds all files within the folder and uses the full path name to search files and proceeds from there. If it is a single file, it simply gets the contents and begins searching for IP addresses using regular expressions. Once all IPs are found and only unique objects are left, it uses [System.Net.Dns] to do a reverse look-up and determine hostnames if possible, if not the name is left as "Unresolved."

Please feel free to use and modify the scripts as you need. If you choose to put them in your own postings or packages, please reference where you found them.
* Note sorry for bloggers formatting... not too much I can do *
*Note 2 - Found a minor issue with it not sorting duplicates from multiple files, this has been corrected and now no matter how many files an IP is found in it only shows once in the resulting output *

FindIPs.ps1 - Used as a script

# Spenser Reinhardt
# Created 7-10-2012
# Last Modified 7-11-2012
# FindIPs.ps1
# Finds unique IPs from any sort of text file and outputs them to a csv

param([parameter(Mandatory=$true)][string]$InputType, [parameter(Mandatory=$true)][string]$OutputFile)

    new-variable -Name RegexIP -force -value ([regex]'\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b')
    $BlankTtable = @{}

    # checks if directory if so, gets full path for each file and runs search\resolve on contents
    If ($(Test-Path $InputType -PathType container)) { # checks for dir
       
        Write-Output "Hostname, IP Address" > $OutputFile # Starts csv file from scratch
       
        Get-ChildItem -Path $InputType -Recurse | ForEach-Object{ # gets file names from dir and starts foreach
            $InputFile = $_.Fullname # sets input file to full name incase we are not in the same dir
            $IPs = $IPs + $RegexIP.matches($(Get-Content($InputFile)))
           
            } # ends regex foreach

        $IPs | select -unique value | ForEach-Object { # matches for correct regex, selects unique objects only, starts foreach
               
                $Resolved = [System.Net.Dns]::GetHostByAddress($_.value) # resolves IP to hostname
               
                # checks if resolved is empty, if so writes blank hostname and correct IP
                if ($Resolved -eq $BlankTable) { $IP = $_.value; Write-Output "Unresolved,$IP" >> $OutputFile }
                # else if not empty writes correct hostname and IP
                else { $Name = $Resolved.HostName; $IP = $Resolved.AddressList; Write-Output "$Name,$IP" >> $OutputFile }
               
                $Resolved=$BlankTable # Sets resolved back to blank for restart of loop
               
            } # ends multiple object foreach  
    } # ends if for dir check

    ElseIf ((Test-Path $InputType -PathType leaf)) { # Checks for single file
       
        $InputFile = $InputType # sets inputfile to inputtype as is only one file
        Write-Output "Hostname, IP Address" > $OutputFile # starts csv from scratch
       
        $RegexIP.matches($(Get-Content($InputFile))) | select -unique value | ForEach-Object { # matches for correct regex, selects unique objects only, starts foreach
            $Resolved = [System.Net.Dns]::GetHostByAddress($_.value) # resolves IP to hostname
           
            #checks if resolved is empty, if so writes blank hostname and correct IP
            if ($Resolved -eq $BlankTable) { $IP = $_.value; Write-Output "Unresolved,$IP" >> $OutputFile }
            #else if not empty writes correct hostname and IP
            else { $Name = $Resolved.HostName; $IP = $Resolved.AddressList; Write-Output "$Name,$IP" >> $OutputFile }
           
            $Resolved=$BlankTable # Sets resolved back to blank for restart of loop
           
        } # ends regex foreach
    } # ends elseif for file check

    Else { Write-Output "Input File is either not file or folder, or not valid!`n`nUsage: .\FindIP.ps1 [Input file\folder] [Output file]" }

FindIPs.psm1 - Can be imported as a function

 # Spenser Reinhardt
# Created 7-10-2012
# Last Modified 7-11-2012
# FindIPs.ps1
# Finds unique IPs from any sort of text file and outputs them to a csv
Function FindIPs {

param([parameter(Mandatory=$true)][string]$InputType, [parameter(Mandatory=$true)][string]$OutputFile)

    new-variable -Name RegexIP -force -value ([regex]'\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b')
    $BlankTtable = @{}

    # checks if directory if so, gets full path for each file and runs search\resolve on contents
    If ($(Test-Path $InputType -PathType container)) { # checks for dir
       
        Write-Output "Hostname, IP Address" > $OutputFile # Starts csv file from scratch
       
        Get-ChildItem -Path $InputType -Recurse | ForEach-Object{ # gets file names from dir and starts foreach
            $InputFile = $_.Fullname # sets input file to full name incase we are not in the same dir
            $IPs = $IPs + $RegexIP.matches($(Get-Content($InputFile)))
           
            } # ends regex foreach

        $IPs | select -unique value | ForEach-Object { # matches for correct regex, selects unique objects only, starts foreach
               
                $Resolved = [System.Net.Dns]::GetHostByAddress($_.value) # resolves IP to hostname
               
                # checks if resolved is empty, if so writes blank hostname and correct IP
                if ($Resolved -eq $BlankTable) { $IP = $_.value; Write-Output "Unresolved,$IP" >> $OutputFile }
                # else if not empty writes correct hostname and IP
                else { $Name = $Resolved.HostName; $IP = $Resolved.AddressList; Write-Output "$Name,$IP" >> $OutputFile }
               
                $Resolved=$BlankTable # Sets resolved back to blank for restart of loop
               
            } # ends multiple object foreach  
    } # ends if for dir check

    ElseIf ((Test-Path $InputType -PathType leaf)) { # Checks for single file
       
        $InputFile = $InputType # sets inputfile to inputtype as is only one file
        Write-Output "Hostname, IP Address" > $OutputFile # starts csv from scratch
       
        $RegexIP.matches($(Get-Content($InputFile))) | select -unique value | ForEach-Object { # matches for correct regex, selects unique objects only, starts foreach
            $Resolved = [System.Net.Dns]::GetHostByAddress($_.value) # resolves IP to hostname
           
            #checks if resolved is empty, if so writes blank hostname and correct IP
            if ($Resolved -eq $BlankTable) { $IP = $_.value; Write-Output "Unresolved,$IP" >> $OutputFile }
            #else if not empty writes correct hostname and IP
            else { $Name = $Resolved.HostName; $IP = $Resolved.AddressList; Write-Output "$Name,$IP" >> $OutputFile }
           
            $Resolved=$BlankTable # Sets resolved back to blank for restart of loop
           
        } # ends regex foreach
    } # ends elseif for file check

    Else { Write-Output "Input File is either not file or folder, or not valid!`n`nUsage: .\FindIP.ps1 [Input file\folder] [Output file]" }
 } # ends function

No comments:

Post a Comment