HostFile.ps1

Function global:Open-HostFile()
{
    Param (
        [Parameter(Mandatory=$false )]
        [ValidateScript({Test-Path $_})]
        [string]$HostFilePath = "$env:windir\System32\drivers\etc\hosts"
    )

    $process = Resolve-Path "$env:windir\system32\notepad.exe"

    Start-Process $process -ArgumentList $HostFilePath -Verb RunAs -PassThru
}

Function Get-HostFileEntries()
{
    Param (
        [Parameter(Mandatory=$false)]
        [ValidateScript({Test-Path $_})]
        [string]$HostFilePath = "$env:windir\System32\drivers\etc\hosts"
    )

    # Fetch content of the hostfile and keep only the non-default adresses
    Get-Content $HostFilePath | Where-Object {-not ([string]::IsNullOrWhiteSpace($_) -or $_ -like "#*")} 
}

Function Add-HostFileEntries()
{
    Param(
        [Parameter(Mandatory=$true)]
        [string] $ip, 
        
        [Parameter(Mandatory=$true)]
        [string] $hostname, 

        [Parameter(Mandatory=$false)]
        [ValidateScript({Test-Path $_})]
        [string]$hostFilePath = "$env:windir\System32\drivers\etc\hosts",

        [Parameter(Mandatory=$false)]
        [string] $comment
    )

    # Remove empty entries and separate ips from hostnames for comparison
    $currentEntries = Get-HostFileEntries $hostFilePath | ForEach-Object {
        if (-not [string]::IsNullOrWhiteSpace($_))
        {
            $_.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)
        }
    }

    if ($currentEntries -contains $hostname -or $currentEntries -contains $ip) 
    {
        throw [System.Exception]("Duplicate Entry. The entry already exist " + $ip + " " + $hostname)
    }

    $hostEntryLine = "`r`n$ip $hostname"

    if (-not [string]::IsNullOrWhiteSpace($comment))
    {
        if ($comment -notlike "#*")
        {
            $comment = "#$comment"
        }

        $hostEntryLine = "`r`n$comment$hostEntryLine"
    }


    Add-Content $HostFilePath $hostEntryLine -Force -NoNewline
}