Public/Remove-specFromHostsFile.ps1
|
function Remove-specFromHostsFile { <# .SYNOPSIS Removes one or more hostnames (and associated IPs) from the system's hosts file. .DESCRIPTION This function removes all entries that contain the specified hostnames from the hosts file. It supports removing multiple hostnames at once and preserves comments and formatting. .PARAMETER Hostname One or more hostnames (or domain names) to remove from the hosts file. .PARAMETER HostsFilePath Specifies the path to the hosts file. Defaults to the system hosts file. .INPUTS [string[]] – You can pipe hostnames or pass them directly. .OUTPUTS None .EXAMPLE Remove-specFromHostsFile -Hostname "example.com","example2.com" .EXAMPLE "example.com","example2.com" | Remove-specFromHostsFile .NOTES Author: owen.heaume Version 1.0.0 - Initial release 1.0.1 - Slight refactor to better support unit testing (Create HostFilePath parameter) 1.0.2 - Improved error handling 1.0.3 - Added support for multiple hostnames and improved safety. #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [string[]]$Hostname, [Parameter()] [string]$HostsFilePath = "$($Env:WinDir)\system32\Drivers\etc\hosts" ) begin { try { if (-not (Test-Path $HostsFilePath)) { throw "Hosts file not found at path: $HostsFilePath" } # Read once — preserving all lines (comments, blanks, etc.) $hostsFile = Get-Content -Path $HostsFilePath -ErrorAction Stop } catch { Write-Error "Error reading hosts file: $_" return } } process { foreach ($name in $Hostname) { try { Write-Host "Checking for '$name' in hosts file..." -ForegroundColor Gray $escaped = [Regex]::Escape($name) $pattern = "\b$escaped\b" $matchesFound = $hostsFile | Where-Object { $_ -match $pattern } if ($matchesFound) { if ($PSCmdlet.ShouldProcess($name, 'Remove from hosts file')) { Write-Host "$name - removing..." -ForegroundColor Yellow # Remove matching lines but keep comments, whitespace, and unrelated entries $hostsFile = $hostsFile | Where-Object { ($_ -notmatch $pattern) -or ($_ -match '^\s*#') } } } else { Write-Host "$name - not found in hosts file" -ForegroundColor DarkYellow } } catch { Write-Error "An error occurred processing '$name': $_" } } } end { try { if ($PSCmdlet.ShouldProcess($HostsFilePath, 'Write updated hosts file')) { # Write safely $hostsFile | Out-File -FilePath $HostsFilePath -Encoding ASCII -Force Write-Host 'Hosts file updated successfully.' -ForegroundColor Green } } catch { Write-Error "Error writing updated hosts file: $_" } } } |