114 lines
4.4 KiB
PowerShell
114 lines
4.4 KiB
PowerShell
|
function Add-HostsFileEntry {
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Add Single entry to the Hosts File
|
||
|
.PARAMETER Ip
|
||
|
IP address for entry
|
||
|
.PARAMETER Hostname
|
||
|
Hostname for entry
|
||
|
.PARAMETER Comment
|
||
|
Optional comment for entry
|
||
|
.PARAMETER HostsPath
|
||
|
optional alternate path to hosts file
|
||
|
.Notes
|
||
|
This function does not support multiple host entrys per ip address on a single line
|
||
|
This function will comment out an entry with the same hostname as the new entry, in case you want to rollback
|
||
|
.EXAMPLE
|
||
|
Add-HostsFileEntry -Ip "10.10.10.10" -Hostname "hello.world"
|
||
|
.EXAMPLE
|
||
|
Add-HostsFileEntry -Ip "10.10.10.10" -Hostname "hello.world" -HostsPath "C:\Temp\bork.txt"
|
||
|
#>
|
||
|
[CmdletBinding()]
|
||
|
Param(
|
||
|
[Parameter(Mandatory = $true)]
|
||
|
[IpAddress]$Ip,
|
||
|
|
||
|
[Parameter(Mandatory = $true)]
|
||
|
[string]$Hostname,
|
||
|
|
||
|
[Parameter(Mandatory = $false)]
|
||
|
[string]$Comment = $null,
|
||
|
|
||
|
[Parameter(Mandatory = $false)]
|
||
|
[string]$HostsPath = "$env:windir\System32\Drivers\etc\hosts"
|
||
|
)
|
||
|
|
||
|
$logLead = Get-LogLeadName
|
||
|
|
||
|
if (($Hostname.split(" ")).Count -gt 1) {
|
||
|
Write-Error "$logLead : You cannot supply more than one hostname"
|
||
|
return
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
$hostsContent = Get-HostsFileContent -hostsPath $HostsPath
|
||
|
} catch [System.IO.IOException], [System.IO.FileNotFoundException] {
|
||
|
Write-Warning "$HostsPath is locked"
|
||
|
Write-Warning "$loglead : Reinitiating after 5 seconds..."
|
||
|
Start-Sleep -Seconds 5
|
||
|
$hostsContent = Get-HostsFileContent -hostsPath $HostsPath
|
||
|
} catch {
|
||
|
Write-Warning "Error encountered when attempting to read file."
|
||
|
Write-Warning $_
|
||
|
throw
|
||
|
}
|
||
|
|
||
|
$hostsEntriesRebuilt = @()
|
||
|
$hostsFileIsDirty = $false
|
||
|
$foundMatchingLine = $false
|
||
|
[Regex]$matchAndSplitPattern = '^(?<IP>[0-9.]+)\s+(?<HostName>[\w.-]+)'
|
||
|
|
||
|
$hostsEntry = "$Ip $Hostname"
|
||
|
if ( [string]::IsNullOrWhitespace($Comment) -eq $false) {
|
||
|
$hostsEntry = "$hostsEntry # $Comment"
|
||
|
}
|
||
|
|
||
|
foreach ($hostLine in $hostsContent) {
|
||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', '', Justification = 'We want to ensure the variable is not holding onto stale information')]
|
||
|
$MATCHES = $null
|
||
|
if ($hostLine -match $matchAndSplitPattern) {
|
||
|
# MATCHES is an automatic variable, use it carefully https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-5.1#matches
|
||
|
$matchedHostname = $MATCHES["HostName"]
|
||
|
|
||
|
if ($Hostname -eq $matchedHostname) {
|
||
|
Write-Warning "$logLead : A hosts entry already exists for entry: $matchedHostname, it will be commented out"
|
||
|
$hostsEntriesRebuilt += "#" + $hostLine
|
||
|
$hostsEntriesRebuilt += $hostsEntry
|
||
|
$hostsFileIsDirty = $true
|
||
|
$foundMatchingLine = $true
|
||
|
Continue
|
||
|
}
|
||
|
}
|
||
|
$hostsEntriesRebuilt += $hostLine
|
||
|
}
|
||
|
if ($foundMatchingLine -eq $false) {
|
||
|
Write-Host "$logLead : Adding Hosts Entry : $($hostsEntry.ToString())"
|
||
|
$hostsFileIsDirty = $true
|
||
|
$hostsEntriesRebuilt += $hostsEntry
|
||
|
}
|
||
|
if ($hostsFileIsDirty -eq $true) {
|
||
|
if (Test-IsCollectionNullOrEmpty -Collection $hostsEntriesRebuilt) {
|
||
|
Write-Warning "Rebuilt file content is empty, exiting..."
|
||
|
throw
|
||
|
} else {
|
||
|
try {
|
||
|
Write-Host "$logLead : Saving Modified Hosts File to $HostsPath"
|
||
|
Set-Content -Path $HostsPath -Value $hostsEntriesRebuilt -Force
|
||
|
Write-Host "$logLead : Saved Modified Hosts File to $HostsPath"
|
||
|
} catch [System.IO.IOException], [System.IO.FileNotFoundException] {
|
||
|
Write-Warning "$loglead : $HostsPath is locked"
|
||
|
Write-Warning "$loglead : Reinitiating after 5 seconds..."
|
||
|
Start-Sleep -Seconds 5
|
||
|
Write-Host "$logLead : Attempt #2 : Saving Modified Hosts File to $HostsPath"
|
||
|
Set-Content -Path $HostsPath -Value $hostsEntriesRebuilt -Force
|
||
|
Write-Host "$logLead : Attempt #2 : Saved Modified Hosts File to $HostsPath"
|
||
|
} catch {
|
||
|
Write-Warning "Error encountered when attempting to write file."
|
||
|
Write-Warning $_
|
||
|
throw
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
Write-Host"$logLead : No changes made to hosts file"
|
||
|
}
|
||
|
}
|