Skip to main content

How to Back Up the Hosts File in Batch Script

Before making any changes to the hosts file, whether for development testing, website blocking, or security hardening, you should always create a backup. If a modification goes wrong, you need a way to instantly restore the original state. A Batch script can create timestamped copies of the hosts file, ensuring you have a recovery point for every modification session. This is especially important because a malformed hosts file can cause widespread connectivity issues across all applications on the machine.

This guide will explain how to create reliable, organized backups of the hosts file.

Method 1: Timestamped Backup to a Dedicated Directory

Creates a backup with a locale-independent timestamp in the filename, stored in a dedicated backup directory.

Implementation

@echo off
setlocal

set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"
set "BackupDir=%~dp0HostsBackups"

:: Verify the hosts file exists
if not exist "%HostsFile%" (
echo [ERROR] Hosts file not found: %HostsFile% >&2
endlocal
exit /b 1
)

:: Create backup directory
if not exist "%BackupDir%\" (
mkdir "%BackupDir%"
if errorlevel 1 (
echo [ERROR] Could not create backup directory: %BackupDir% >&2
endlocal
exit /b 1
)
)

:: Generate locale-independent timestamp
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyyMMdd_HHmmss''"'
) do set "Timestamp=%%t"

set "BackupFile=%BackupDir%\hosts_%COMPUTERNAME%_%Timestamp%.bak"

:: Create the backup
copy "%HostsFile%" "%BackupFile%" >nul 2>&1

if errorlevel 1 (
echo [ERROR] Failed to create backup. >&2
echo Check write permissions to: %BackupDir% >&2
endlocal
exit /b 1
)

:: Verify the backup matches the original
fc "%HostsFile%" "%BackupFile%" >nul 2>&1

if errorlevel 1 (
echo [WARNING] Backup was created but does not match the original. >&2
echo The file may have been modified during the copy. >&2
) else (
echo [OK] Backup verified: it matches the original.
)

echo [OK] Backup saved to: %BackupFile%

:: Show backup size
for %%f in ("%BackupFile%") do echo [OK] Size: %%~zf bytes

endlocal
exit /b 0

Why locale-independent timestamps:

The %date:~-4%%date:~3,2%%date:~0,2% assumes a specific regional date format. On non-US systems, the substring positions extract wrong characters, producing garbled filenames like 202_ _0__5.bak. PowerShell's Get-Date -Format 'yyyyMMdd_HHmmss' produces 20240510_143205 regardless of locale.

Why %COMPUTERNAME% in the filename:

If backups from multiple machines are stored in a shared location, the computer name distinguishes which machine each backup came from. Even for local backups, it prevents confusion if the backup directory is copied to another machine.

Why fc verification:

The copy command can silently fail in rare circumstances (disk full during write, file locked by antivirus). Comparing the backup with the original using fc confirms the backup is a complete, identical copy.

Method 2: Quick In-Place Backup

For emergency situations where you need a backup immediately before making a change, stored right next to the original for instant access during restore.

@echo off
setlocal

set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"

:: Verify admin privileges (needed to write to the etc directory)
net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Writing to the hosts directory requires administrator privileges. >&2
endlocal
exit /b 1
)

if not exist "%HostsFile%" (
echo [ERROR] Hosts file not found. >&2
endlocal
exit /b 1
)

:: Check if a backup already exists
if exist "%HostsFile%.bak" (
echo [INFO] An existing backup was found: %HostsFile%.bak
echo.

:: Show when the existing backup was created
for %%f in ("%HostsFile%.bak") do echo Existing backup date: %%~tf

echo.
set /p "Overwrite=Overwrite the existing backup? (YES/no): "
if /i not "!Overwrite!"=="YES" (
echo [INFO] Keeping existing backup. No changes made.
endlocal
exit /b 0
)
)

copy "%HostsFile%" "%HostsFile%.bak" >nul 2>&1

if errorlevel 1 (
echo [ERROR] Failed to create backup. >&2
endlocal
exit /b 1
)

echo [OK] Backup saved as: %HostsFile%.bak
echo.
echo [RESTORE] To restore the backup:
echo copy "%HostsFile%.bak" "%HostsFile%"
echo ipconfig /flushdns

endlocal
exit /b 0
Administrative Rights for In-Place Backup

Saving a .bak file in the C:\Windows\System32\drivers\etc\ directory requires administrator privileges, i.e. the same as modifying the hosts file itself. Method 1 (saving to a different directory) may not require elevation depending on the backup directory location.

In-Place Backup Overwrites Previous Backup

The .bak file is a single recovery point. Each new backup overwrites the previous one. If you make a change, back up, make a bad change, back up again, you've lost the good backup. For multiple recovery points, use Method 1 (timestamped backups).

Method 3: Pre-Modification Guard (Integrated Backup)

Use this as a reusable subroutine at the beginning of any script that modifies the hosts file. It creates a timestamped backup before the modification proceeds.

@echo off
setlocal

set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"

:: Verify admin privileges
net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Administrator privileges required. >&2
endlocal
exit /b 1
)

:: =============================================
:: Step 1: Create pre-modification backup
:: =============================================
call :BackupHosts
if errorlevel 1 (
echo [ABORT] Backup failed. Hosts file will not be modified. >&2
endlocal
exit /b 1
)

:: =============================================
:: Step 2: Your modification code here
:: =============================================

:: Example: Add an entry
set "NewEntry=127.0.0.1 blocked-site.example.com"

findstr /i /c:"blocked-site.example.com" "%HostsFile%" >nul 2>&1
if errorlevel 1 (
echo # Added by %USERNAME% on %date% >> "%HostsFile%"
echo %NewEntry% >> "%HostsFile%"
echo [OK] Added: %NewEntry%
ipconfig /flushdns >nul 2>&1
) else (
echo [SKIP] Entry already exists.
)

endlocal
exit /b 0


:: =============================================
:: Backup Subroutine
:: =============================================
:BackupHosts
set "BakDir=%~dp0HostsBackups"

if not exist "%BakDir%\" mkdir "%BakDir%" 2>nul

for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyyMMdd_HHmmss''"'
) do set "BakFile=%BakDir%\hosts_%COMPUTERNAME%_%%t.bak"

copy "%HostsFile%" "%BakFile%" >nul 2>&1
if errorlevel 1 (
echo [ERROR] Could not create backup: %BakFile% >&2
exit /b 1
)

echo [GUARD] Backup created: %BakFile%
exit /b 0

Why the backup must succeed before modification:

If the backup fails (disk full, permissions issue, backup directory inaccessible), the script aborts WITHOUT modifying the hosts file. This prevents the scenario where a modification goes wrong and there's no backup to restore from. The if errorlevel 1 check after call :BackupHosts enforces this rule.

Integrating into any hosts modification script:

Any script that writes to the hosts file should call the :BackupHosts subroutine first:

:: At the start of any hosts modification script:
call :BackupHosts
if errorlevel 1 (
echo [ABORT] Cannot proceed without a backup.
exit /b 1
)
:: Safe to modify the hosts file from here

Method 4: Restore from Backup

Creating backups is only useful if you can restore them. This method lists available backups and restores a selected one.

@echo off
setlocal EnableDelayedExpansion

set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"
set "BackupDir=%~dp0HostsBackups"

net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Restoring requires administrator privileges. >&2
endlocal
exit /b 1
)

if not exist "%BackupDir%\" (
echo [ERROR] Backup directory not found: %BackupDir% >&2
echo No backups are available to restore. >&2
endlocal
exit /b 1
)

:: List available backups
echo [INFO] Available hosts file backups:
echo --------------------------------------------------
echo.

set "BackupCount=0"
for /f "delims=" %%f in ('dir /b /o-d "%BackupDir%\hosts_*.bak" 2^>nul') do (
set /a "BackupCount+=1"
set "Backup[!BackupCount!]=%%f"
for %%s in ("%BackupDir%\%%f") do (
echo !BackupCount!. %%f (%%~zs bytes, %%~tf^)
)
)

if %BackupCount% equ 0 (
echo (No backups found)
endlocal
exit /b 1
)

echo.
echo --------------------------------------------------
echo.

set /p "Selection=Enter backup number to restore (or Q to quit): "

if /i "!Selection!"=="Q" (
echo [INFO] Cancelled.
endlocal
exit /b 0
)

:: Validate selection
if not defined Backup[%Selection%] (
echo [ERROR] Invalid selection. >&2
endlocal
exit /b 1
)

set "SelectedFile=!Backup[%Selection%]!"
set "SelectedPath=%BackupDir%\!SelectedFile!"

echo.
echo [INFO] Selected: !SelectedFile!
echo.

:: Show a preview of what will be restored
echo [INFO] Active entries in the backup:
findstr /v /r "^#" "!SelectedPath!" | findstr /v /r "^$" | findstr /v /i "localhost"
echo.

set /p "Confirm=Restore this backup? (YES/no): "
if /i not "!Confirm!"=="YES" (
echo [INFO] Cancelled. No changes made.
endlocal
exit /b 0
)

:: Create a backup of the CURRENT hosts file before overwriting
copy "%HostsFile%" "%HostsFile%.pre-restore.bak" >nul 2>&1

:: Restore
copy /y "!SelectedPath!" "%HostsFile%" >nul 2>&1

if errorlevel 1 (
echo [ERROR] Restore failed. >&2
endlocal
exit /b 1
)

echo [OK] Hosts file restored from: !SelectedFile!

ipconfig /flushdns >nul 2>&1
echo [OK] DNS cache flushed.

:: Log the restore
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do echo [%%t] RESTORE: !SelectedFile! by %USERNAME% on %COMPUTERNAME% >> "%~dp0hosts_changes.log"

endlocal
exit /b 0

Why the restore creates its own backup:

Before overwriting the current hosts file with a backup, the script copies the current file to hosts.pre-restore.bak. This allows you to undo the restore if you selected the wrong backup, i.e. a backup of the backup, ensuring you never lose the current state.

Method 5: Automatic Backup Rotation

Backups accumulate over time. This method cleans up old backups while keeping recent ones.

@echo off
setlocal

set "BackupDir=%~dp0HostsBackups"
set "RetentionDays=30"

if not exist "%BackupDir%\" (
echo [INFO] No backup directory found. Nothing to clean up.
endlocal
exit /b 0
)

echo [INFO] Cleaning up backups older than %RetentionDays% days...

set "Deleted=0"
forfiles /P "%BackupDir%" /M "hosts_*.bak" /D -%RetentionDays% /C "cmd /c echo [DEL] @file & del @path" 2>nul

:: Count remaining backups
for /f %%n in ('dir /b "%BackupDir%\hosts_*.bak" 2^>nul ^| find /c /v ""') do set "Remaining=%%n"

echo [OK] Cleanup complete. %Remaining% backup(s) retained.

endlocal
exit /b 0
Schedule Backup Rotation

Run Method 5 as a monthly scheduled task to prevent backup files from accumulating indefinitely. The default 30-day retention keeps enough history for typical troubleshooting while preventing unbounded growth.

How to Avoid Common Errors

Wrong Way: Always Overwriting the Same Backup File

:: LOSES ALL PREVIOUS RECOVERY POINTS
copy hosts hosts.bak
:: Bad change...
copy hosts hosts.bak
:: The "good" backup is now the "bad" backup!

With a single .bak file, creating a new backup after a bad change overwrites the good backup, leaving you with no recovery point.

Correct Way: Use timestamped filenames (Method 1) so each backup is unique and previous recovery points are preserved.

Wrong Way: Modifying the Hosts File Without Backing Up First

If the modification goes wrong (bad entry, encoding corruption, accidental overwrite), there's no way to recover without manually reconstructing the file.

Correct Way: Use Method 3's guard pattern, as the backup MUST succeed before any modification proceeds.

Problem: Backup Fails Silently

The copy command may fail without producing an obvious error message, especially when the destination directory doesn't exist or when permissions prevent the write.

Solution: All methods in this guide check if errorlevel 1 after the copy command and report failures explicitly. Method 1 additionally verifies the backup matches the original with fc.

Problem: Backup Directory Fills Up

Without rotation, daily or per-change backups accumulate indefinitely. The hosts file is small (typically 1–10 KB), but thousands of backups over years add up.

Solution: Method 5 provides automatic rotation using forfiles. Schedule it monthly or include it as part of your maintenance routines.

Problem: Cannot Write to drivers\etc Directory

The C:\Windows\System32\drivers\etc\ directory is protected. In-place backups (Method 2) require administrator privileges.

Solution: Method 1 saves backups to a separate directory (relative to the script) which may not require elevation. Method 2 requires elevation and checks for it.

Best Practices and Rules

1. Back Up Before EVERY Modification

Make this a non-negotiable rule. Every script that writes to the hosts file should begin with a backup step. Method 3 provides a reusable subroutine for this.

2. Use Timestamped Filenames

Each backup should have a unique filename containing the date and time. This preserves multiple recovery points and shows when each backup was created.

3. Verify Backups After Creation

Use fc to compare the backup against the original. A backup that doesn't match the original is useless for recovery.

4. Keep a Restore Script Ready

Creating backups without a restore procedure is incomplete. Method 4 provides an interactive restore with backup listing, preview, and confirmation.

5. Rotate Old Backups

Schedule Method 5 monthly to prevent backup accumulation. Keep at least 30 days of history for troubleshooting.

6. Store Backups Outside the System Directory

Saving backups to C:\Windows\System32\drivers\etc\ (Method 2) requires admin rights and mixes backups with system files. A dedicated backup directory (Method 1) is cleaner, easier to manage, and may not require elevation.

7. Include the Computer Name in Backup Filenames

If backups from multiple machines are consolidated to a shared location, the computer name prevents filename collisions and identifies the source machine.

Conclusions

Backing up the hosts file before modification is a simple but critical discipline that prevents connectivity disasters. By using timestamped filenames, verifying backup integrity, requiring successful backup before allowing modification, and providing a tested restore procedure, you ensure that any hosts file change can be instantly rolled back. Combined with automatic rotation to prevent backup accumulation, this creates a complete backup lifecycle that is reliable, organized, and professional.