Batch (Updater and DNS cache) crashed my system...
https://github.com/StevenBlack/hosts/blob/dbdcb032706dfe548745266218501afa93c14ad5/updateHostsWindows.bat
On modern Windows 10 and Windows 11 systems, the file paths
%SYSTEMROOT%\SysWOW64\config\system %SYSTEMROOT%\system32\config\system do not exist. These paths were used in older privilege-checking batch file techniques, but Microsoft has since hardened system directories and registry hives. Trying to access these on Windows 11 will typically result in an error, even when run as administrator.
Implications for your script The script attempts to check for administrator rights by accessing these files with cacls.exe. On Windows 11, this check will always fail because the files donβt exist, meaning the script will always try to re-launch itself with elevated privileges, or just fail the privilege check. What to do instead? A more robust, modern approach for checking admin rights in batch scripts is to use the NET SESSION command:
batch net session >nul 2>&1 if %errorLevel% neq 0 ( echo Requesting administrative privileges... goto UACPrompt ) else ( goto gotAdmin ) net session requires admin rights, but doesnβt rely on deprecated or non-existent files.
Hello! Thank you for opening your first issue in this repo. Itβs people like you who make these host files better!
Thank you for this Florian @Enelass
I would entertain a PR from someone that fixes this π
Hey Steven, I started fixing the batch to then send a PR but... I'd actually advise against hosting a large hosts file on Windows 11 entirely... You might want to consider warning users based on my experience which I suspect can be reproduced on other Win11 endpoints...
Catastrophic failure
-
My system experienced network freeze, where both explorer.exe and browsers (brave, edge) would freeze or not open at all... Killing svchost.exe running
%SystemRoot%\system32\svchost.exe -k NetworkService -pwould allow explorer to respond but that process would just re-spawn. -
Worse the hosts file, could not be deleted (even as admin) since read by
svchostsKilling svchosts liketaskkill /f /im svch*would expectedly cause a BSOD / Kernal Panic and would free the handle on the file -
Running
disable-dnscache-service-win.batis not any better... After running the script my NICs were disabled, and could not be re-enabled.
Reverting the changes:
Reverting the changes implied:
- Using msconfig to reboot in safe mode (now named)
-
Delete hosts, or restoring one of its backup
-
Reverting registry changes
reg add "HKLM\SYSTEM\CurrentControlSet\services\Dnscache" /v Start /t REG_DWORD /d 2 /f -
Reboot
msconfig, select "Normal Startup" and restart...
Possibly a better design for blocking DNS on Windows:
The hosts file wasn't designed to handle such number of entries... Pi-hole or AdGuard on a container for Windows or dnscrypto-proxy
Thanks Florian @Enelass.
Windows is such a shitshow. It's really embarrassing.
In the past we've "sort-of" accommodated Windows by keeping the hosts file sizes reasonable. But the hosts files sizes have ballooned recently, and we're in a tough spot again.
@krystian3w and @hawkeye116477 can I have your input on the following notion?
The hosts files here have gotten too big again.
Part of me wants to give a π to Windows and decide, I can't support that shit anymore. I would probably also ban the X/Twitter domain t.co and fully embrace Peter's @pgl's bold path at the same time. This would be a "bite the bullet" scenario to take this into the future.
OTOH, if you are able to curate the KADhosts list downwards a little, that would defer this decision.
Ultimately it's unavoidable, I think. Windows is flaming garbage, and I'd love to be rid of its concerns and constraints entirely.
What do you think?
The bot does its best to throw out domains that are considered dead based on whois and parking lists once a month (recently the bot has been known to hang at some early stage of checking in the subdocker and after ~5 hours MS kills the task e.g. https://github.com/FiltersHeroes/ScriptsPlayground/actions/runs/14950655096/job/41999874717), someone would have to look through the file full time with an unknown domain expiration date:
-
https://github.com/FiltersHeroes/ScriptsPlayground/blob/master/expired-domains/KAD-unknown.txt (600 to check)
-
https://github.com/FiltersHeroes/ScriptsPlayground/blob/master/expired-domains/KAD-unknown_limit.txt (87 to check)
-
https://github.com/FiltersHeroes/ScriptsPlayground/blob/master/expired-domains/KAD-unknown_no_internet.txt (34 to check)
-
https://github.com/FiltersHeroes/ScriptsPlayground/blob/master/expired-domains/KADhosts-unknown.txt (11 to check)
Then maybe more lines will evaporate every week/month.
Perhaps the fault lies with CERT Polska (sometimes they block +100 domains per our interval of copying their suggestions, so +1200 new hosts may appear per day) it would be useful if they reported the page to the superadmin of hosting or register if it is a domain only for phishing and not infected with CMS vulnerabilities or weak FTP/admin passwords.
In the worst case, we may need to take a step back, test whether CERT domains are active and beg GitLab for unlimited CI/CD time within open source projects.
Partial optimization up to about 50% for the KADHosts list could be provided by someone's own script to verify whether it makes sense to imply a line with www. appended (with zero need for gluing, the number of lines would drop to about 79 thousands from about 156 thousands).
Partial optimization up to about 50% for the KADHosts list could be provided by someone's own script to verify whether it makes sense to imply a line with www. appended (with zero need for gluing, the number of lines would drop to about 79 thousands from about 156 thousands).
Well, in ideal world would be so much better if hosts will block whole domain like uBO does that :smile:
Thank you for this @hawkeye116477 and @krystian3w.
Unfortunately hosts files mechanisms are never gonna change π
I'll think about all this. Thank you for your input, and I'm keen to hear any other thoughts you may have.
Hey guys, I had this exact problem today too when I tried this huge hosts file.
My solution to empty the hosts file was the following:
-
Look for the process using hosts (in this case svchost.exe) and its PID This can be done like this: Β·Open Task Manager Β·Click on Performance tab Β·Click on Resource Monitor
Β·Β·On Resource Monitor, click on CPU
Β·Β·On the search bar that appears on the CPU tab, search "hosts" Β·Β·It should appears svchost.exe with its PID (please, make sure to get the PID of the svchost.exe that is running hosts, not any other one)
-
Create a bat file with the following (change the number for the correct PID for the svchost.exe that is using hosts)
taskkill /f /pid 19692
echo # > C:\Windows\System32\drivers\etc\hosts
Then, execute the batch script as an admin and the problem should (hopefully) be fixed.
I have been watching this issue since it was posted and was staying out of it as I figured someone else would take care of it and there's a lot to unpack here and I haven't had much time lately, but I feel bad for the needless struggles you all are having as there are viable solutions already. I sort of already have solutions for everything here, but first I will walk through my opinions, concerns, and questions.
There are 2 problems in this issue; first is the update host script and second is large hosts files in modern Windows (which I have long since solved and I have a very simple solution already provided in Steven's README).
1. Update Hosts Script
This is my main issue that I am holding back on helping with because
- CMD batch scripts have not been a recommended method of scripting in Windows for near 18 years and definitely not in the last 10 years or so. No one in this day and age should even think 'cmd.exe' when thinking about the command line/scripting in Windows. Powershell is king and the fact that no one else here has mentioned it means to me that you may need more help with using any solution I come up with (which is fine, but I need time to do so).
- If I do create an alternative method I have to go through the process of writing, posting in my repos, making a PR here if Steven wants it and as I stated before I have been busy and I was not ready to even think about focusing on this... until now maybe.
- I actually have a tool that people can use that is featured in Steven's README under Interesting Applications called BlackHosts which can do nearly the same thing, though it uses JSDelivr and has less features. This is an executable. This solution is not for everyone, but you can try it if you want.
2. System/DNS Cache Hanging
Directly below the section with this update script in this repository is information I personally contributed to this repo about this issue, a solution, and a tool I have created to help with this issue. Please read more here in the 2nd paragraph under the section here: https://github.com/StevenBlack/hosts#warning-using-this-hosts-file-in-windows-may-require-disabling-dns-cache-service
I have helped many people with this problem over the last few years and it always works. The main problem is that the Windows DNS Caching service doesn't handle lots of entries very wells. It's not the size of the file so much as it is the number of entries. The solution is to combine multiple urls into single IP lines and in Windows each IP (0.0.0.0 and 127.0.0.1 for example) can handle up to 9 entries per line so 81000 entries (for example) can then become 9000 entries. As with my other program above I have another program called Hosts Compress for Windows (I didn't write it for Linux as it's not needed there) and it is also featured in Steven's README in this repository under https://github.com/StevenBlack/hosts?tab=readme-ov-file#interesting-applications. I have 3 tools there: BlackHosts and the 2 directly below which essentially do the same thing (hosts compression), but the executable is exponentially faster. Once you compress the hosts file your machine and internet should run like a charm in nearly any version of Windows including the latest update. I maintain at least 20 machines of friends and family with various versions of Windows from XP on up and I use this for those machines often (I am also SysAdmin professionally, but of course, none of this is allowed in those environments).
I will write something soon as an updater script in Powershell, but until then you can all use my compression tool to compress the hosts file and replace. It has features to compress in place or compress a copy and you can replace yourself manually. Your system can run perfectly fine with this solution. As stated above you can find the link for my tools in this repo or go directly to my repository for more information on usage and the downloads.
BlackHosts https://github.com/Lateralus138/blackhosts
Hosts Compress (executable written in C++) - Recommended fast solution https://github.com/Lateralus138/hosts-compress-windows
Hosts Compress - Script (old powershell compression that can take several minutes) - not necessarily recommended, but there for those who want to try. https://github.com/Lateralus138/hosts-compression-scripts
I will start working on a Powershell update script probably this weekend if anyone is interested.
Update: I have started on a Powershell hosts file updater script last weekend and working on it more this Sunday US CST (tomorrow for me). Just didn't want people to think I have forgotten.
I also intend to rewrite BlackHosts with libcurl (instead of being dependent on JSDelvr) and with more options.
I am done writing and testing a full Powershell script that does what the original batch script does and more. The script is backwards compatible with Powershell 5.1 so no extra installs (PowerCore) are needed. I am not sure exactly where this will be posted yet in this repository, but I will also host in my repos and so my next step is to create that repo with information/instructions. This is well tested in both Windows 10 and 11. For now you can copy and use the file from here. The main issues nowadays is almost always that the hosts file is in use (svchost.exe|DNS cache of course) and so using this in a loop while $LASTEXITCODE is greater than 0 is always recommended. Same with my hosts compression program. while ($LASTEXITCODE -gt 0) { .\updateHostsWindows/ps1 } as stated in the code below for example. If you don't want to wait for the hosts file to be unused you can always run this while loop and then use a file unlocker (IoBit Unlocker for example) to unlock the hosts file and it should work right away and exit the loop. Again, same with my hosts compression program. This seems to be a headache for some, but everything I've provided here in my posts should make it much easier and work correctly.
For now until I get everything posted in its rightful place:
<#
.SYNOPSIS
Install/update hosts files found at https://github.com/StevenBlack/hosts/.
.DESCRIPTION
Install/update consolidated hosts files found at
https://github.com/StevenBlack/hosts/.
.PARAMETER Alternate
Update hosts with one of the alternate hosts file found in Steven's alternates
directory.
.PARAMETER OutFile
Download the file only, do not update. Defaults to the current path.
.PARAMETER NoBackup
Do not create a backup file.
.PARAMETER Force
Force continue the script on errors.
.PARAMETER Restore
Restore the hosts file with the current skeleton backup if one exists and
exits.
#>
<#
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β This Powershell script updates the Windows hosts file from one of the β
β various consolidated hosts files found at at: β
β https://github.com/StevenBlack/hosts β
β This script is written for backwards compatibility for Powershell 5.1+ β
β as PowerCore is not installed by default. β
β β
β Original script written by: β
β Ian Pride (Lateralus138) β
β [email protected] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#>
<#
βββββββββββββββββββββ
β Parse parameters. β
βββββββββββββββββββββ
#>
Param(
[String]$Alternate,
[String]$OutFile,
[Switch]$NoBackup,
[Switch]$Force,
[Switch]$Restore
)
<#
βββββββββββββββββββββ
β Global variables. β
βββββββββββββββββββββ
#>
$seperator = '-' * 80
$baseHostsUrl = 'https://raw.githubusercontent.com/StevenBlack/hosts/refs/heads/master/'
$WriteStatus = {
Param(
[ValidateScript({ $_.Length -gt 0 })][String]$Message,
[Switch]$IsError
)
switch ($IsError){
$true { $color = 'Red' }
default { $color = 'Green' }
}
$lastColor = $host.ui.RawUI.ForegroundColor
$host.ui.RawUI.ForegroundColor = $color
$Message
$host.ui.RawUI.ForegroundColor = $lastColor
}
<#
ββββββββββββββββββββββ
β About this script. β
ββββββββββββββββββββββ
#>
@"
$seperator
This Powershell script updates the Windows hosts file from one of the various
consolidated hosts files found at at: https://github.com/StevenBlack/hosts
$seperator
If updating the hosts file fails due to the hosts file being in use then it's
best to just keep trying. It's not always in use though it is hard to figure
out when it's free so it's recommended to use while loop on `$LASTEXITCODE to
keep trying. E.G.: while (`$LASTEXITCODE -gt 0) { .\updateHostsWindows.ps1 }.
$seperator
Use: Get-Help .\updateHostsWindows.ps1 -Detailed (or -Full) for more
information.
$seperator
"@
<#
βββββββββββββββββββββββββββββββββββ
β Check administrative privileges β
βββββββββββββββββββββββββββββββββββ
#>
' Checking if we are in a shell with administrative privileges.'
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
$argString = ''
$PSBoundParameters.GetEnumerator() | Foreach-Object {
$argString += ' -' + $_.Key + ' ' + $_.Value
}
' Attempting to restart this script as administrator.'
try {
Start-Process powershell `
-ArgumentList "-NoLogo -NoExit -NoProfile -Command `"Set-Location $PWD`; $PSCommandPath $argString`"" `
-Verb RunAs `
-ErrorAction SilentlyContinue
} catch {
&$WriteStatus $(" " + $_.Exception.Message + "`n") -IsError
}
exit 1
}
if ($Alternate -eq 'True') { $Alternate = '' }
if ($OutFile -eq 'True') { $OutFile = '' }
$hostsFile = $Env:SystemRoot + '\System32\drivers\etc\hosts'
$hostsSkeleton = $hostsFile + '.skel'
<#
ββββββββββββββββββββββββ
β Restore last backup. β
ββββββββββββββββββββββββ
#>
if ($Restore){
Write-Host " Attempting to restore $hostsSkeleton"
if (-not (Test-Path -Path $hostsSkeleton -PathType Leaf )) {
&$WriteStatus $(' ' + $hostsSkeleton + " not found.`n") -IsError
exit 2
}
try {
Copy-Item -Path $hostsSkeleton -Destination $hostsFile -ErrorAction Stop
$successMessage =
@"
Successfully restored $hostsSkeleton to $hostsFile.
"@
&$WriteStatus $successMessage
} catch {
&$WriteStatus $(
" Could not restore the hosts file.`n " +
$_.InvocationInfo.MyCommand.Name + ': ' + $_.Exception.Message + "`n If the file was in use please try again. It will eventually be free.`n"
) -IsError
exit 3
}
exit 0
}
<#
ββββββββββββββββββββββββββββββ
β Backup current hosts file. β
ββββββββββββββββββββββββββββββ
#>
if (-not ($OutFile)){
switch ($NoBackup){
$true { " No backup will be created." }
default {
" Attempting to create a back up of $hostsFile."
try {
Copy-Item -Path $hostsFile -Destination $hostsSkeleton -ErrorAction Stop
$successMessage =
@"
Successfully created a backup of the current hosts file at
$hostsSkeleton.
"@
&$WriteStatus $successMessage
} catch {
&$WriteStatus $(
" Could not create a backup of the hosts file.`n " +
$_.InvocationInfo.MyCommand.Name + ': ' + $_.Exception.Message
) -IsError
if (-not ($Force)) {
&$WriteStatus " This script will now exit (use the -Force switch to force continue on error).`n" -IsError
exit 4
}
}
}
}
}
<#
ββββββββββββββββββββββββββββ
β Select which hosts file. β
ββββββββββββββββββββββββββββ
#>
switch ($Alternate.Length -gt 0) {
$true { $hostsUrl = $baseHostsUrl + 'alternates/' + $Alternate + '/hosts' }
default { $hostsUrl = $baseHostsUrl + 'hosts' }
}
<#
βββββββββββββββββββββββββββββββ
β Get remote hosts file data. β
βββββββββββββββββββββββββββββββ
#>
try {
" Attempting to get data from`n $hostsUrl."
$response = Invoke-WebRequest -Uri $hostsUrl
} catch {
&$WriteStatus $(' ' + $_.Exception.Message + "`n") -IsError
exit 5
}
if (-not($response.StatusDescription -eq 'OK')) {
&$WriteStatus $(
" Could not retrieve a valid reponse from`n $hostsUrl. [" +
$response.StatusCode + '] ' + $response.StatusDescription + "`n"
) -IsError
exit 6
}
<#
ββββββββββββββββββββββββββββββββββββ
β Install, update, or create file. β
ββββββββββββββββββββββββββββββββββββ
#>
if ($OutFile.Length -gt 0){
" Attempting to create output file $OutFile."
try {
$response.Content | Out-File -FilePath $OutFile -Encoding utf8
} catch {
&$WriteStatus $(
" Could not create file: $OutFile.`n " + $_.Exception.Message + "`n"
) -IsError
exit 7
}
&$WriteStatus " Successfully created file: $OutFile.`n"
exit 0
}
" Attempting to update $hostsFile."
try {
$response.Content | Out-File -FilePath $hostsFile -Encoding utf8
} catch {
&$WriteStatus $(
" Could not update: $hostsFile.`n " + $_.Exception.Message + "`n"
) -IsError
exit 8
}
&$WriteStatus " Successfully updated: $hostsFile.`n"
<#
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β If the system hosts file has been installed or update then flush the DNS cache. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#>
try {
" Attempting to flush the DNS cache."
ipconfig /flushdns
} catch {
&$WriteStatus $(
" Could not flush the DNS cache.`n" + $_.Exception.Message + "`n"
) -IsError
exit 9
}
&$WriteStatus " Successfully flushed the DNS cache.`n"
exit 0
This is interesting, thank you for this Ian @Lateralus138.
I will certainlly entertain a pull request that packages this, along with documentation added to the readme_template.md file, to add this to the repository.
This is interesting, thank you for this Ian @Lateralus138.
I will certainlly entertain a pull request that packages this, along with documentation added to the
readme_template.mdfile, to add this to the repository.
Alright, I have created my repository and will now work on yours. As you can see I will have to come up with a condensed version of the documentation and/or link to my repo.
Edit: pull request submitted.