Retrieving contents of Hosts file using PowerShell

I decided that I wanted a way to view all of the hosts file on a bunch of servers and see just what is listed.  Most of the code is fairly straight-forward where I use Test-Connection and Test-Path to validate whether a system is online and then whether the Hosts file is under a WinNT folder or Windows folder. If a system was upgraded, there is potential that the Hosts file resides under WinNT.

Once the validation is done and everything is still checking out OK, I can then grab the contents of the file using the Switch command and the –file and –regex switches. By doing this, I am going to read each line of the file one line at a time. By supplying the –regex switch, I can define a regular expression to look for a specific item, in this case, the initial IPV4 IP address using this line:

"^\d\w+"

Yes, this is a weak regular expression for finding the IPV4 address, but I felt it was all I needed because there would only be a few things in the hosts file to find.

Also, since everything in that line is one big string, I have to perform a split in order to grab exactly what I need to include the IP address, hostname associated with the IP and any notes that happen to be with that information. I also clear out any extra spaces so the array created is always accurate when I add the items into the collection.

$new = $_.Split("") | ? {$_ -ne ""}

After which then everything else goes into the Default grouping and I then perform an If statement to verify that the is no comment block (#) and no white space on the hosts file using the following line:

 If (!("\s+" -match $_ -OR $_.StartsWith("#"))) {

If it has neither of those, then it is assumed to be an IPV6 address and adds it to the collection. I was going to write a regular expression for IPV6 addresses, but since there are a few different variations of how an IPV6 address can be, I decided to just go with my original idea of looking for everything but the IPV6 and then setting the Default action of the switch to be the IPV6 address. For an idea of what a regular expression would look like on IPV6, check this out.

Here is an example of using the function:

Capture

As you can see, the output shows the Computer, IPV4, IPV6 , the associated hostname for the IP and any notes that might have been left on the Hosts file. Nothing too wild going on here. But running it on your enterprise network may or may not reveal some surprises that you were not expecting.

You can scan your network and then export the results to a CSV report by piping the output to Export-CSV.

 

Code

Poshcode

Script Repository

Function Get-HostsFile { 
<#   
.SYNOPSIS   
   Retrieves the contents of a hosts file on a specified system 
.DESCRIPTION 
   Retrieves the contents of a hosts file on a specified system 
.PARAMETER Computer 
    Computer name to view host file from 
.NOTES   
    Name: Get-HostsFile 
    Author: Boe Prox 
    DateCreated: 15Mar2011  
.LINK  
    https://boeprox.wordpress.com        
.EXAMPLE   
    Get-HostsFile "server1" 
 
Description 
-----------     
Retrieves the contents of the hosts file on 'server1' 
 
 
#>  
[cmdletbinding( 
    DefaultParameterSetName = 'Default', 
    ConfirmImpact = 'low' 
)] 
    Param( 
        [Parameter( 
            ValueFromPipeline = $True)] 
            [string[]]$Computer                                                
                         
        ) 
Begin { 
    $psBoundParameters.GetEnumerator() | % {   
        Write-Verbose "Parameter: $_"  
        } 
        If (!$PSBoundParameters['computer']) { 
        Write-Verbose "No computer name given, using local computername" 
        [string[]]$computer = $Env:Computername 
        } 
    $report = @() 
    } 
Process { 
    Write-Verbose "Starting process of computers" 
    ForEach ($c in $computer) { 
        Write-Verbose "Testing connection of $c" 
        If (Test-Connection -ComputerName $c -Quiet -Count 1) { 
            Write-Verbose "Validating path to hosts file" 
            If (Test-Path "\\$c\C$\Windows\system32\drivers\etc\hosts") { 
                Switch -regex -file ("\\$c\c$\Windows\system32\drivers\etc\hosts") { 
                    "^\d\w+" { 
                        Write-Verbose "Adding IPV4 information to collection" 
                        $temp = "" | Select Computer, IPV4, IPV6, Hostname, Notes 
                        $new = $_.Split("") | ? {$_ -ne ""} 
                        $temp.Computer = $c 
                        $temp.IPV4 = $new[0] 
                        $temp.HostName = $new[1] 
                        If ($new[2] -eq $Null) { 
                            $temp.Notes = "NA" 
                            } 
                        Else { 
                            $temp.Notes = $new[2] 
                            } 
                        $report += $temp 
                        } 
                    Default { 
                        If (!("\s+" -match $_ -OR $_.StartsWith("#"))) { 
                            Write-Verbose "Adding IPV6 information to collection" 
                            $temp = "" | Select Computer, IPV4, IPV6, Hostname, Notes 
                            $new = $_.Split("") | ? {$_ -ne ""} 
                            $temp.Computer = $c 
                            $temp.IPV6 = $new[0] 
                            $temp.HostName = $new[1] 
                            If ($new[2] -eq $Null) { 
                                $temp.Notes = "NA" 
                                } 
                            Else { 
                                $temp.Notes = $new[2] 
                                } 
                            $report += $temp 
                            } 
                        }                         
                    } 
                }#EndIF 
            ElseIf (Test-Path "\\$c\C$\WinNT\system32\drivers\etc\hosts") { 
                Switch -regex -file ("\\$c\c$\WinNT\system32\drivers\etc\hosts") { 
                    "^#\w+" { 
                        } 
                    "^\d\w+" { 
                        Write-Verbose "Adding IPV4 information to collection" 
                        $temp = "" | Select Computer, IPV4,IPV6, Hostname, Notes 
                        $new = $_.Split("") | ? {$_ -ne ""} 
                        $temp.Computer = $c 
                        $temp.IPV4 = $new[0] 
                        $temp.HostName = $new[1] 
                        If ($new[2] -eq $Null) { 
                            $temp.Notes = "NA" 
                            } 
                        Else { 
                            $temp.Notes = $new[2] 
                            } 
                        $report += $temp 
                        } 
                    Default { 
                        If (!("\s+" -match $_ -OR $_.StartsWith("#"))) { 
                            Write-Verbose "Adding IPV6 information to collection" 
                            $temp = "" | Select Computer, IPV4, IPV6, Hostname, Notes 
                            $new = $_.Split("") | ? {$_ -ne ""} 
                            $temp.Computer = $c 
                            $temp.IPV6 = $new[0] 
                            $temp.HostName = $new[1] 
                            If ($new[2] -eq $Null) { 
                                $temp.Notes = "NA" 
                                } 
                            Else { 
                                $temp.Notes = $new[2] 
                                } 
                            $report += $temp 
                            } 
                        }                         
                    }         
                }#End ElseIf 
            Else { 
                Write-Verbose "No host file found" 
                $temp = "" | Select Computer, IPV4, IPV6, Hostname, Notes 
                $temp.Computer = $c 
                $temp.IPV4 = "NA" 
                $temp.IPV6 = "NA"                 
                $temp.Hostname = "NA" 
                $temp.Notes = "Unable to locate host file" 
                $report += $temp 
                }#End Else 
            } 
        Else { 
            Write-Verbose "No computer found" 
            $temp = "" | Select Computer, IPV4, IPV6, Hostname, Notes 
            $temp.Computer = $c 
            $temp.IPV4 = "NA" 
            $temp.IPV6 = "NA"             
            $temp.Hostname = "NA" 
            $temp.Notes = "Unable to locate Computer" 
            $report += $temp             
            } 
        } 
    } 
End { 
    Write-Output $report 
    } 
}

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell, scripts and tagged , , . Bookmark the permalink.

6 Responses to Retrieving contents of Hosts file using PowerShell

  1. Dave Pidgeon says:

    Nice 🙂

  2. mjolinor says:

    Nice. One thing you might add is a check of

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DataBasePath.

    The default location is Windows\system32\drivers\etc\hosts, but it can be changed to another location using that registry key.

  3. Chris Brown says:

    Awesome! Now how about (Add|Update|Remove)-HostFileEntry?

    • Boe Prox says:

      Thanks, I started on something like that to Add/Remove but then got sidetracked on something else. Hopefully I can come back to it and finish it up and post the code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s