How to Restore the Hosts File from a Backup in Batch Script
Restoring the Windows Hosts file from a backup is a critical recovery operation for system administrators and developers. Whether you are reverting changes made during a development cycle, recovering from a malicious modification, or rolling back a failed configuration change, automating the restoration process ensures consistency and reduces human error. A proper restore script validates the backup, handles file protections, verifies the result, and flushes the DNS cache, all in one reliable operation.
This guide provides a comprehensive approach to safely restoring your Hosts file using Batch scripting.
Understanding the Restore Process
The restore operation involves more than simply copying a file. A professional restore script must handle several concerns:
- Verify admin rights
- Locate and validate the backup file
- Create a pre-restore snapshot of the current hosts file (so the restore itself can be undone)
- Clear file protection attributes
- Copy the backup to the hosts file location
- Verify the restored file matches the backup
- Re-apply file protection attributes
- Flush the DNS cache
To modify or restore the Hosts file, your Batch script must be executed with "Run as Administrator." The drivers\etc directory is a protected system folder, and any write operation without elevation fails with "Access Denied."
Method 1: Restore from a Specific Backup File
This method restores the hosts file from a known backup path, with full validation, pre-restore safety snapshot, and verification.
Implementation
@echo off
setlocal EnableDelayedExpansion
:: Define paths
set "HostsPath=%SystemRoot%\System32\drivers\etc\hosts"
set "BackupPath=%~1"
if "%BackupPath%"=="" (
echo Usage: %~nx0 ^<backup_file_path^>
echo.
echo Restores the hosts file from a backup.
echo.
echo Examples:
echo %~nx0 C:\HostsBackups\hosts_20240510_143205.bak
echo %~nx0 "%HostsPath%.bak"
echo %~nx0 "\\Server\Backups\hosts_WORKSTATION07.bak"
endlocal
exit /b 1
)
echo ============================================================
echo Hosts File Restoration
echo ============================================================
echo.
:: 1. Check for administrative privileges
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] This script must be run as Administrator. >&2
endlocal
exit /b 1
)
:: 2. Verify the backup file exists
if not exist "%BackupPath%" (
echo [ERROR] Backup file not found: %BackupPath% >&2
endlocal
exit /b 1
)
:: Verify the backup is not empty
for %%f in ("%BackupPath%") do set "BackupSize=%%~zf"
if "%BackupSize%"=="0" (
echo [ERROR] Backup file is empty (0 bytes^). >&2
echo This is not a valid hosts file backup. >&2
endlocal
exit /b 1
)
:: 3. Show current hosts file status
echo [INFO] Current hosts file:
for %%f in ("%HostsPath%") do (
echo Size: %%~zf bytes
echo Modified: %%~tf
)
echo.
echo [INFO] Backup to restore:
echo Path: %BackupPath%
echo Size: %BackupSize% bytes
echo.
:: Preview the backup's active entries
echo [INFO] Active entries in the backup:
findstr /v /r "^#" "%BackupPath%" | findstr /v /r "^$"
if errorlevel 1 echo (No active entries - default/clean hosts file^)
echo.
:: 4. Confirm the restore
set /p "Confirm=Restore the hosts file from this backup? (YES/no): "
if /i not "!Confirm!"=="YES" (
echo [INFO] Cancelled. No changes made.
endlocal
exit /b 0
)
:: 5. Create a pre-restore snapshot (backup the CURRENT state before overwriting)
set "PreRestoreBackup=%HostsPath%.pre-restore"
copy "%HostsPath%" "!PreRestoreBackup!" >nul 2>&1
if not errorlevel 1 (
echo [OK] Pre-restore snapshot saved: !PreRestoreBackup!
echo (If the restore is wrong, copy this file back^)
)
:: 6. Clear file protection attributes
attrib -r -s -h "%HostsPath%" >nul 2>&1
:: 7. Perform the restoration
echo [ACTION] Restoring hosts file...
copy /y "%BackupPath%" "%HostsPath%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Failed to copy backup to hosts file. >&2
echo [INFO] Attempting to restore pre-restore snapshot... >&2
copy /y "!PreRestoreBackup!" "%HostsPath%" >nul 2>&1
attrib +r "%HostsPath%" >nul 2>&1
endlocal
exit /b 1
)
:: 8. Verify the restored file matches the backup
fc "%HostsPath%" "%BackupPath%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Verification passed - restored file matches backup.
) else (
echo [WARNING] Restored file does not match backup exactly. >&2
echo The file may have been modified by antivirus or encoding conversion. >&2
echo Review with: type "%HostsPath%" >&2
)
:: 9. Re-apply read-only attribute
attrib +r "%HostsPath%" >nul 2>&1
:: 10. Flush DNS cache
ipconfig /flushdns >nul 2>&1
echo [OK] DNS cache flushed.
echo.
echo ============================================================
echo Restoration complete.
echo ============================================================
:: Log the operation
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do echo [%%t] RESTORE: From "%BackupPath%" by %USERNAME% on %COMPUTERNAME% >> "%~dp0hosts_changes.log"
endlocal
exit /b 0
Key techniques explained:
The attrib command: The hosts file may have read-only (R), system (S), or hidden (H) attributes set, either by Windows or by antivirus software. The -r -s -h flags remove all three before the copy, and +r re-applies read-only afterward to protect the file from accidental modification.
Pre-restore snapshot: Before overwriting the current hosts file, the script saves it as hosts.pre-restore. If the wrong backup is restored, you can recover the previous state without searching for another backup.
The copy /y flag: The /y switch suppresses the overwrite confirmation prompt. Without it, the script would hang waiting for user input during automated execution.
The fc verification: After copying, fc (File Compare) verifies the restored file is byte-for-byte identical to the backup. This catches silent copy failures, encoding conversions, or antivirus interference.
Method 2: Interactive Restore from Backup Directory
When multiple timestamped backups exist, this method lists them and lets the user choose which one to restore.
@echo off
setlocal EnableDelayedExpansion
set "HostsPath=%SystemRoot%\System32\drivers\etc\hosts"
set "BackupDir=%~1"
if "%BackupDir%"=="" set "BackupDir=%~dp0HostsBackups"
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Administrator privileges required. >&2
endlocal
exit /b 1
)
if not exist "%BackupDir%\" (
echo [ERROR] Backup directory not found: %BackupDir% >&2
endlocal
exit /b 1
)
:: List available backups (newest first)
echo [INFO] Available backups in %BackupDir%:
echo --------------------------------------------------
echo.
set "Count=0"
for /f "delims=" %%f in ('dir /b /o-d "%BackupDir%\hosts_*.bak" 2^>nul') do (
set /a "Count+=1"
set "Backup[!Count!]=%%f"
for %%s in ("%BackupDir%\%%f") do (
echo !Count!. %%f
echo Size: %%~zs bytes ^| Date: %%~tf
)
echo.
)
if !Count! equ 0 (
echo (No backup files found matching hosts_*.bak^)
endlocal
exit /b 1
)
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
)
if not defined Backup[!Selection!] (
echo [ERROR] Invalid selection. >&2
endlocal
exit /b 1
)
set "SelectedFile=!Backup[%Selection%]!"
set "SelectedPath=%BackupDir%\!SelectedFile!"
:: Show preview
echo.
echo [INFO] Selected: !SelectedFile!
echo.
echo [INFO] Active entries in this backup:
findstr /v /r "^#" "!SelectedPath!" | findstr /v /r "^$"
if errorlevel 1 echo (No active entries - clean/default hosts file^)
echo.
set /p "Confirm=Restore this backup? (YES/no): "
if /i not "!Confirm!"=="YES" (
echo [INFO] Cancelled.
endlocal
exit /b 0
)
:: Pre-restore snapshot
copy "%HostsPath%" "%HostsPath%.pre-restore" >nul 2>&1
:: Clear attributes, copy, verify, re-apply
attrib -r -s -h "%HostsPath%" >nul 2>&1
copy /y "!SelectedPath!" "%HostsPath%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Restore failed. >&2
copy /y "%HostsPath%.pre-restore" "%HostsPath%" >nul 2>&1
attrib +r "%HostsPath%" >nul 2>&1
endlocal
exit /b 1
)
fc "%HostsPath%" "!SelectedPath!" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Restored and verified: !SelectedFile!
) else (
echo [WARNING] Restored but verification shows differences. >&2
)
attrib +r "%HostsPath%" >nul 2>&1
ipconfig /flushdns >nul 2>&1
echo [OK] DNS cache flushed.
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do echo [%%t] RESTORE: !SelectedFile! by %USERNAME% >> "%~dp0hosts_changes.log"
endlocal
exit /b 0
Why newest-first listing:
The most common restore scenario is "undo the last change." Listing backups newest-first (dir /o-d) puts the most relevant backup at position 1, minimizing scrolling and selection effort.
Method 3: Reset to Windows Default
When the hosts file has been heavily modified and you need a guaranteed clean state, restore the Windows default content rather than a backup.
@echo off
setlocal EnableDelayedExpansion
set "HostsPath=%SystemRoot%\System32\drivers\etc\hosts"
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Administrator privileges required. >&2
endlocal
exit /b 1
)
echo [INFO] Current custom entries:
echo.
set "CustomCount=0"
for /f %%n in ('findstr /v /r "^#" "%HostsPath%" ^| findstr /v /r "^$" ^| findstr /v /i "localhost" ^| find /c /v ""') do set "CustomCount=%%n"
if !CustomCount! equ 0 (
echo (No custom entries. Hosts file is already at default.^)
endlocal
exit /b 0
)
findstr /v /r "^#" "%HostsPath%" | findstr /v /r "^$" | findstr /v /i "localhost"
echo.
set /p "Confirm=Type RESET to restore the Windows default hosts file: "
if /i not "!Confirm!"=="RESET" (
echo [INFO] Cancelled. No changes made.
endlocal
exit /b 0
)
:: Pre-reset snapshot
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyyMMdd_HHmmss''"'
) do set "Stamp=%%t"
copy "%HostsPath%" "%HostsPath%.%Stamp%.pre-reset" >nul 2>&1
echo [OK] Pre-reset snapshot saved: %HostsPath%.%Stamp%.pre-reset
:: Clear attributes and write default
attrib -r -s -h "%HostsPath%" >nul 2>&1
(
echo # Copyright (c^) 1993-2009 Microsoft Corp.
echo #
echo # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
echo #
echo # This file contains the mappings of IP addresses to host names. Each
echo # entry should be kept on an individual line. The IP address should
echo # be placed in the first column followed by the corresponding host name.
echo # The IP address and the host name should be separated by at least one
echo # space.
echo #
echo # Additionally, comments (such as these^) may be inserted on individual
echo # lines or following the machine name denoted by a '#' symbol.
echo #
echo # For example:
echo #
echo # 102.54.94.97 rhino.acme.com # source server
echo # 38.25.63.10 x.acme.com # x client host
echo #
echo # localhost name resolution is handled within DNS itself.
echo # 127.0.0.1 localhost
echo # ::1 localhost
) > "%HostsPath%"
if !errorlevel! neq 0 (
echo [ERROR] Failed to write default hosts file. >&2
echo [INFO] Restoring from pre-reset snapshot... >&2
copy /y "%HostsPath%.%Stamp%.pre-reset" "%HostsPath%" >nul 2>&1
attrib +r "%HostsPath%" >nul 2>&1
endlocal
exit /b 1
)
attrib +r "%HostsPath%" >nul 2>&1
ipconfig /flushdns >nul 2>&1
echo [OK] Hosts file reset to Windows default.
echo [OK] DNS cache flushed.
echo [OK] %CustomCount% custom entry(ies^) removed.
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do echo [%%t] RESET TO DEFAULT: %CustomCount% entries removed by %USERNAME% >> "%~dp0hosts_changes.log"
endlocal
exit /b 0
Resetting to default removes every custom mapping, blocks, redirects, development overrides, and all other entries. This operation cannot be undone unless you have a backup of the current hosts file (a pre-reset snapshot is created automatically).
When to use Method 3 vs. Methods 1–2:
| Situation | Recommended Method |
|---|---|
| Undo a recent specific change | Method 1 (restore from known backup) |
| Choose from multiple backups | Method 2 (interactive selection) |
| Unknown/messy hosts file state | Method 3 (reset to default) |
| Suspected malware modification | Method 3 (reset) + antivirus scan |
| Troubleshooting DNS, eliminate hosts as a variable | Method 3 (reset) |
How to Avoid Common Errors
Wrong Way: Copying Without Clearing Attributes
:: MAY FAIL: hosts file may have read-only attribute
copy /y backup.bak C:\Windows\System32\drivers\etc\hosts
If the hosts file has the read-only attribute set (common after antivirus lockdown or Group Policy), the copy fails even with administrator privileges.
Correct Way: Remove attributes before copying, re-apply after:
attrib -r -s -h "%HostsPath%" >nul 2>&1
copy /y backup.bak "%HostsPath%" >nul
attrib +r "%HostsPath%" >nul 2>&1
Wrong Way: Restoring Without Verifying the Backup
A corrupt, empty, or wrong backup file will overwrite the working hosts file with garbage, breaking DNS resolution for everything.
Correct Way: All methods in this guide check that the backup exists, is not empty, and preview its contents before restoring.
Wrong Way: Not Creating a Pre-Restore Snapshot
If you restore the wrong backup, the current hosts file is gone, and there may not be another backup that matches the current state.
Correct Way: Save the current hosts file as .pre-restore before overwriting. All methods include this step.
Problem: Antivirus Blocks the Restore
Some antivirus products monitor the hosts file and block modifications, treating any change as potential malware activity.
Solution: Temporarily disable the antivirus's hosts file protection, perform the restore, then re-enable it. Some AV products (Malwarebytes, Norton) have specific settings for hosts file protection.
Problem: DNS Changes Don't Take Effect After Restore
After restoring, the old DNS mappings may persist in the Windows DNS resolver cache.
Solution: Always flush the DNS cache after any hosts file modification:
ipconfig /flushdns >nul 2>&1
All methods in this guide include this step.
After restoring, verify the change took effect:
:: View the restored file
type %SystemRoot%\System32\drivers\etc\hosts
:: Test that a previously redirected hostname now resolves via DNS
ping -n 1 previously-redirected-site.com
:: Should show the DNS-resolved IP, not the old hosts file IP
Remember: use ping to test hosts file resolution, NOT nslookup (which bypasses the hosts file).
Best Practices and Rules
1. Always Create a Pre-Restore Snapshot
Before overwriting the hosts file, save the current version. This allows you to undo the restore if the wrong backup was selected.
2. Verify After Restoring
Use fc to compare the restored file against the backup. A mismatch indicates the copy was corrupted, intercepted by antivirus, or affected by encoding conversion.
3. Flush DNS After Every Restore
ipconfig /flushdns clears cached DNS entries. Without this, old hosts file mappings may persist for minutes.
4. Handle File Attributes
Always clear the read-only attribute before copying and re-apply it afterward. This prevents "Access Denied" errors on protected hosts files.
5. Preview Before Restoring
Display the backup's active entries before confirming the restore. This prevents accidentally restoring a backup that contains unwanted entries (old blocks, wrong redirects).
6. Log Every Restore Operation
Record what was restored, from which backup, when, and by whom. This provides an audit trail for change management and troubleshooting.
Conclusion
Restoring the Hosts file via Batch script is an operation that demands care, as a bad restore can break DNS resolution for every application on the machine. By following the structured approach in this guide, permission checks, backup validation, pre-restore snapshots, attribute management, post-restoration verification, and DNS cache flushing, you perform this sensitive operation with confidence. Whether restoring from a specific backup, selecting from a timestamped archive, or resetting to the Windows default, these scripts ensure the restoration is safe, verified, and reversible.