Hosts Tool

Schnell die Windows hosts-Datei verwalten: Add, Remove, List — immer mit Backup.
PowerShell • Windows • Single Script

Was macht das Tool?

Du kannst Hosts-Einträge hinzufügen/aktualisieren (ohne Duplikate), Einträge entfernen und bestehende Einträge listen/filtern. Vor jeder Änderung wird automatisch ein .bak-Backup erstellt.

Standardpfad:
%windir%\System32\drivers\etc\hosts

Wichtig (Adminrechte)

Add und Remove brauchen Adminrechte, weil Windows die hosts-Datei schützt. List geht ohne Admin.

Tipp: PowerShell als Administrator starten → dann läuft’s stressfrei.

Quick Start

# 1) Script herunterladen
# 2) In einem Ordner speichern (z.B. Downloads)
# 3) PowerShell öffnen (Admin für Add/Remove)

# Eintrag setzen / updaten
.\HostsTool.ps1 -Action Add -Hostname "intranet.local" -IP "10.10.10.10"

# Eintrag entfernen
.\HostsTool.ps1 -Action Remove -Hostname "intranet.local"

# Auflisten
.\HostsTool.ps1 -Action List

# Filtern
.\HostsTool.ps1 -Action List -Filter "local"
DNS: Standardmäßig macht das Tool danach ipconfig /flushdns. Wenn du das nicht willst: -NoFlushDns

Execution Policy (falls Windows meckert)

# Temporär für diese Session:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

# Oder (wenn du’s dauerhaft für den User willst):
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Hinweis: Das ist normal bei eigenen Scripts. „Bypass“ nur nutzen, wenn du weißt, was du tust.

Script (Preview)

Zum Nachschauen. Der Download ist identisch.

<#
.SYNOPSIS
  Hosts-Datei verwalten (Add/Update/Remove/List) inkl. Backup.
.DESCRIPTION
  - Fügt Einträge hinzu oder aktualisiert vorhandene
  - Entfernt Einträge
  - Listet Einträge (optional gefiltert)
  - Erstellt Backup vor Änderungen
  - Verhindert Duplicate-Spam und hält Format sauber
.EXAMPLES
  .\HostsTool.ps1 -Action Add    -Hostname "intranet.local" -IP "10.10.10.10"
  .\HostsTool.ps1 -Action Remove -Hostname "intranet.local"
  .\HostsTool.ps1 -Action List
  .\HostsTool.ps1 -Action List   -Filter "local"
#>

[CmdletBinding()]
param(
  [Parameter(Mandatory)]
  [ValidateSet("Add","Remove","List")]
  [string]$Action,

  [string]$Hostname,
  [string]$IP,

  [string]$Filter,

  [string]$HostsPath = "$env:windir\System32\drivers\etc\hosts",

  [switch]$NoFlushDns
)

function Test-IsAdmin {
  $id = [Security.Principal.WindowsIdentity]::GetCurrent()
  $p  = New-Object Security.Principal.WindowsPrincipal($id)
  return $p.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

function Backup-File([string]$Path) {
  $stamp = Get-Date -Format "yyyyMMdd-HHmmss"
  $bak = "$Path.$stamp.bak"
  Copy-Item -Path $Path -Destination $bak -Force
  return $bak
}

function Normalize-Hostname([string]$h) {
  if ([string]::IsNullOrWhiteSpace($h)) { return $null }
  return $h.Trim().ToLower()
}

function Validate-IP([string]$ip) {
  if ([string]::IsNullOrWhiteSpace($ip)) { return $false }
  $tmp = $null
  return [System.Net.IPAddress]::TryParse($ip.Trim(), [ref]$tmp)
}

function Read-Hosts([string]$Path) {
  if (!(Test-Path $Path)) { throw "Hosts-Datei nicht gefunden: $Path" }
  return Get-Content -Path $Path -Encoding ASCII
}

function Write-Hosts([string]$Path, [string[]]$Lines) {
  # Hosts ist typischerweise ASCII/ANSI – wir schreiben bewusst ASCII.
  Set-Content -Path $Path -Value $Lines -Encoding ASCII -Force
}

function Flush-DnsIfNeeded {
  if (-not $NoFlushDns) {
    try { ipconfig /flushdns | Out-Null } catch {}
  }
}

# --- Start ---
if ($Action -ne "List" -and -not (Test-IsAdmin)) {
  throw "Bitte PowerShell als Administrator starten (Hosts-Datei braucht Adminrechte)."
}

$hn = Normalize-Hostname $Hostname

switch ($Action) {

  "List" {
    $lines = Read-Hosts $HostsPath

    # Parse: IP + Hostname am Zeilenanfang, Kommentare ignorieren
    $entries = foreach ($line in $lines) {
      $t = $line.Trim()
      if ($t -eq "" -or $t.StartsWith("#")) { continue }

      # Match: IP whitespace hostname (weitere Aliase ignorieren wir hier)
      if ($t -match '^(?<ip>\S+)\s+(?<host>\S+)\s*(?<rest>.*)$') {
        [PSCustomObject]@{
          IP       = $Matches.ip
          Hostname = $Matches.host
          Raw      = $line
        }
      }
    }

    if ($Filter) {
      $entries | Where-Object { $_.Hostname -like "*$Filter*" -or $_.IP -like "*$Filter*" } | Format-Table -AutoSize
    } else {
      $entries | Format-Table -AutoSize
    }
    break
  }

  "Add" {
    if (-not $hn) { throw "Bitte -Hostname angeben." }
    if (-not (Validate-IP $IP)) { throw "Bitte eine gültige -IP angeben (IPv4 oder IPv6)." }

    $lines = Read-Hosts $HostsPath
    $bak = Backup-File $HostsPath

    $newLine = "{0}`t{1}" -f $IP.Trim(), $hn

    $found = $false
    $out = foreach ($line in $lines) {
      $t = $line.Trim()
      if ($t -match '^(?<ip>\S+)\s+(?<host>\S+)\s*(?<rest>.*)$') {
        $host = ($Matches.host).Trim().ToLower()
        if ($host -eq $hn) {
          $found = $true
          # Update statt Duplicate
          $newLine
          continue
        }
      }
      $line
    }

    if (-not $found) {
      # saubere Trennzeile, wenn Datei nicht mit Leerzeile endet
      if ($out.Count -gt 0 -and ($out[-1].Trim() -ne "")) {
        $out += ""
      }
      $out += $newLine
    }

    Write-Hosts $HostsPath $out
    Flush-DnsIfNeeded

    Write-Host "OK: Eintrag gesetzt -> $newLine"
    Write-Host "Backup: $bak"
    break
  }

  "Remove" {
    if (-not $hn) { throw "Bitte -Hostname angeben." }

    $lines = Read-Hosts $HostsPath
    $bak = Backup-File $HostsPath

    $removed = $false
    $out = foreach ($line in $lines) {
      $t = $line.Trim()
      if ($t -match '^(?<ip>\S+)\s+(?<host>\S+)\s*(?<rest>.*)$') {
        $host = ($Matches.host).Trim().ToLower()
        if ($host -eq $hn) {
          $removed = $true
          continue
        }
      }
      $line
    }

    Write-Hosts $HostsPath $out
    Flush-DnsIfNeeded

    if ($removed) {
      Write-Host "OK: Eintrag entfernt -> $hn"
    } else {
      Write-Host "Hinweis: Kein Eintrag gefunden für -> $hn"
    }
    Write-Host "Backup: $bak"
    break
  }
}
Altmark Cloud • Tools