Skip to content

Instantly share code, notes, and snippets.

@tnhung2011
Created December 15, 2025 14:27
Show Gist options
  • Select an option

  • Save tnhung2011/206b1a85dea6e181a09b6d35a5312300 to your computer and use it in GitHub Desktop.

Select an option

Save tnhung2011/206b1a85dea6e181a09b6d35a5312300 to your computer and use it in GitHub Desktop.
Aggregates local hosts files to the global one, rejecting any duplicates
@echo off
:: detect wrapping
:: writePublic defined = jump to :writePublic
:: this evades CTRL-C canceling all operations
:: https://stackoverflow.com/a/27131024
if "%~1"=="" if defined writePublic (goto writePublic) else (goto noargs)
set writePublic=
setlocal enableextensions enabledelayedexpansion
if "%~1"=="/?" goto help
set "hosts=%SystemRoot%\System32\drivers\etc\hosts"
set "args=%*"
set "args.proc=%args:*/d:=%"
if "%args.proc%"=="%args%" goto checkNoc
for /f "tokens=1" %%d in ("%args.proc%") do (
set "args=!args:/d:%%d=!"
echo:>>"%%~d" && set hosts="%%~d" || (
1>&2 echo ERROR: Unable to create file: %%d
exit /b 1
)
)
:checkNoc
set "args=%args:/noc%=%"
set "args.proc=%args:/noc=%"
:: for/f strips leading whitespaces
::set args.proc
for /f "tokens=* delims=]" %%a in ("]%args.proc%") do if ""=="%%a" (
:noargs
1>&2 echo ERROR: Insufficient arguments
exit /b 1
)
set ignoreComments=
if not "%args%"=="%args.proc%" set ignoreComments=1
set "args=%args.proc%"
:: does not update timestamp
for %%f in (%hosts%) do (
echo DESTINATION: %%~f
ren %%f "%%~nxf" || (
1>&2 echo ERROR: File locked or insufficient credentials (i.e. not admin^).
exit /b 1
)
)
:: detect cr/lf at end of file
:: https://www.dostips.com/forum/viewtopic.php?f=3&t=11311#p70156
findStr /v $ %hosts% >nul && echo:>>%hosts%
:: /noc specified
if defined ignoreComments (
set hosts.temp="%temp%\hosts"
>!hosts.temp! findstr /rc:"^[^#]" %hosts%
set writePublic=1
rem wrap
cmd /c "%~f0"
rem deletion failure won't affect errorlevel
del !hosts.temp!
1>&2 echo Successfully deleted !hosts.temp!
exit /b 0
)
:: fall through
:: /noc not specified
set hosts.temp=%hosts%
:writePublic
for %%f in (%args%) do (
echo SOURCE: %%~f
for /f "useback tokens=1,2 eol=#" %%a in ("%%~f") do (
>nul find /c /i "%%b" %hosts.temp% && (
echo [EXISTS] %%b
) || (
echo [%%a] %%b
echo:%%a %%b>>%hosts%
)
))
exit /b 0
:help
echo Aggregates HOSTS files, writing any entry with nonmatching hostnames
echo to the destination
echo:
echo HOSTS [/noc] sources [/d:destination]
echo:
for /f %%A in ('prompt $H ^&echo on ^&for %%B in ^(1^) do rem') do set bs=%%A
echo %bs% sources Specifies the HOSTS file(s) to be aggregated. Wildcards can be used.
echo %bs% /d:destination Specifies the destination HOSTS file.
echo %bs% (default: %%SystemRoot%%\System32\drivers\etc\hosts)
echo %bs% /noc Ignore comments when matching against the destination.
echo %bs% If the console window is closed while specifying /noc (not Ctrl+C),
echo %bs% you should clean up this temporary file: "%%temp%%\hosts"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment