I want to share this code to update the HOSTS file with a windows task at regular times.
Note.- Hosts addresses can change or need password in the future, so take care. This code needs a help file cabeza.txt or a string with similar code and the corresponding modification
Text for cabeza.txt at the end of code. Text and comments in Spanish Language but you can googeling translate.
Code
"
# Script para Automatizar la actualización del archivo HOSTS de Windows por medio de una tarea y
# fusionando los tres archivos de las direcciones siguientes:
# http://www.malwaredomainlist.com/hostslist/hosts.txt
# http://someonewhocares.org/hosts/zero/hosts"
# http://www.winhelp2002.mvps.org/hosts.txt
#Inicio
#--------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------
# Comprobamos que el archivo HOSTS existe en el directorio de windows
$path = "c:\windows\system32\drivers\etc\HOSTS"
# Si no existe, creamos uno de la nada y si existe seguimos el programa
If(-not(Test-Path -path $path))
{
$h="127.0.0.1 localhost"
New-Item -Path $path -ItemType file -Value $h -force
}
Else
{
}
# Ahora comprobamos si existe el hosts.bak y si no hay hacemos uno
# Podiamos si existe el HOSTS hacer un .bak del HOSTS pero hacemos este de fortuna
# porque después el programa ya pone los valores verdaderos.
$path = "c:\windows\system32\drivers\etc\hosts.bak"
If(-not(Test-Path -path $path))
{
$h="127.0.0.1 localhost"
New-Item -Path $path -ItemType file -Value $h -force
}
Else
{
}
# como queremos que tambien en la carpeta auxiliar estén los dos, tanto el HOSTS como el hosts.bak
# miramos si existen y si no existen copiamos los archivos del directorio de windows y los ponemos en este
$path = "c:\HOSTSUPDATE\HOSTS"
# Si no existe, copiamos el de windows y si existe seguimos el programa
If(-not(Test-Path -path $path))
{
Copy-Item c:\windows\system32\drivers\etc\HOSTS C:\HOSTSUPDATE
}
Else
{
}
$path = "C:\HOSTSUPDATE\hosts.bak"
# Si no existe, copiamos el de windows y si existe seguimos el programa
If(-not(Test-Path -path $path))
{
Copy-Item c:\windows\system32\drivers\etc\hosts.bak C:\HOSTSUPDATE
}
Else
{
}
cd C:\HOSTSUPDATE
#Si no hay backup de hosts actual, hacer uno
$MirarSiHostsbak = "c:\HOSTSUPDATE\hosts.bak"
$FileExists = (Test-Path $MirarSiHostsbak -PathType Leaf)
# Comprobamos que el Hosts es el del dia porque hayamos encendido el ordenador mas de una vez
# ya que el Hosts se genera nada mas encender el ordenador. Para ello cogemos la fecha que
# hay en el HOSTS actual. Si el ordenador permanece encendido mas de un dia entonces la tarea
# ha de programarse para una hora concreta en que sepamos que va a estar encendido.
$fileNames = "C:\HOSTSUPDATE\HOSTS"
$fecha=Get-Date -format "dd-MM-yyyy"
# Ahora cogemos la fecha de hoy del ordenador
$result = Get-Content $fileNames | Select-String $fecha -quiet -casesensitive
# Comparamos ambas fechas para ver si son iguales
If ($result -eq $fecha)
{
# Si las fechas coinciden,SALIR sin hacer nada. Ya existe el archivo con esa fecha
# El programa sale aquí y no realiza ninguna operación
}
Else{ # En caso contrario, realizar todo el proceso. Primero descargamos los archivos al ordenador
#Descargar el hosts de 'malwaredomainlist.com' a la carpeta HOSTSUPDATE
#una manera de hacerlo es con Invoke y la otra con Start. Start es más rápido
$error.clear()
$fileURL = "http://www.malwaredomainlist.com/hostslist/hosts.txt"
$destination = "C:\HOSTSUPDATE\file1.log"
#Invoke-WebRequest $fileURL -OutFile $destination
Start-BitsTransfer $fileURL $destination
#Descargar el hosts de 'someonewhocares.org' a la carpeta HOSTSUPDATE
#otra manera de hacerlo pero puede que sea mas lento porque es linea a linea
$error.clear()
#$urls = "http://someonewhocares.org/hosts/zero/hosts"
#$fileNames = "C:\HOSTSUPDATE\file2.log"
#$webclients = New-Object System.Net.WebClient
#$webclients.DownloadFile($urls,$fileNames)
#nos quedamos con esta
$urls = "http://someonewhocares.org/hosts/zero/hosts"
$fileNames = "C:\HOSTSUPDATE\file2.log"
#Invoke-WebRequest $urls -OutFile $filenames
Start-BitsTransfer $urls $filenames
# Fusionar los dos archivos en el primero
$error.clear()
$file2 = Get-Content "file2.log"
Add-Content "file1.log" $file2
# obtenemos el día de hoy y si es un 7 ,14,21 o un 28 entonces descargamos
# el hosts de 'www.winhelp2002.mvps.org'
$data=$a = (Get-Date).Day
if ($data -eq 7 -or $data -eq 14 -or $data -eq 21 -or $data -eq 28) {
#Descargar el hosts de MVPS to HOSTSUPDATE folder
$error.clear()
$fileURL = "http://www.winhelp2002.mvps.org/hosts.txt"
$fileName = "C:\HOSTSUPDATE\file3.log"
#$webclient = New-Object System.Net.WebClient
#$webclient.DownloadFile($fileURL,$fileName)
#Invoke-WebRequest $fileURL -OutFile $filename
Start-BitsTransfer $fileURL $filename
# Fusionar el file1.log con el de MVPS
$error.clear()
$file3 = Get-Content "file1.log"
Add-Content "file3.log" $file3
}
else { # en caso de que no sea dia 7 ,14,21 o 28 seguir con la operacion sin bajar el MVPS Hosts
$error.clear()
$file3 = Get-Content "file1.log"
Add-Content "file3.log" $file3
}
#Eliminar las lineas de comentarios para poder añadir las mias propias con el archivo cabeza.txt
New-Item -ItemType file "file4.log" -force
Select-String '#' .\file3.log -notmatch | % {$_.Line} | set-content file4.log
#Reemplazar un string 127.0.0.1 por 0.0.0.0
$new = (Get-Content "file4.log") -replace "127.0.0.1", "0.0.0.0"
Set-Content file4.log $new
#Reemplazar un string 0.0.0.0 por 255.255.255.0
$new = (Get-Content "file4.log") -replace "0.0.0.0", "255.255.255.0"
Set-Content file4.log $new
#elimina las líneas que contienen localhost,local y broadcasthost porque todos los ficheros las repiten
# y así ponemos solo las que vienen en el archivo cabeza.txt
New-Item -ItemType file "file6.log" -force
Select-string -path .\file4.log -pattern localhost, local,broadcasthost -notmatch | % {$_.Line} | set-content file6.log
# convertir dos espacios o mas en solo uno, para poder ordenar bien ya que algun hosts tiene dos espacios
# entre el 255.255.255.0 y el hostsname
$new2 = (Get-Content "C:\HOSTSUPDATE\file6.log") -replace '\s+', ' '
Set-Content "C:\HOSTSUPDATE\file6.log" $new2
# Aqui ordenamos las lineas de menor a mayor por numeros y letras a la vez que elimina duplicados
New-Item -ItemType file "HOSTS1" -force
$ins1 = Get-Content "file6.log"
$ins2 = $ins1 | sort -Unique
Add-Content "C:\HOSTSUPDATE\HOSTS1" $ins2
#Fusiona el archivo cabeza.txt (que es la cabecera) con el HOSTS1
$error.clear()
New-Item -ItemType file "HOSTS2.log" -force
$HOSTS2 = Get-Content "C:\HOSTSUPDATE\cabeza.txt"
$HOSTS3 = Get-Content "C:\HOSTSUPDATE\HOSTS1"
Add-Content "C:\HOSTSUPDATE\HOSTS2.log" $HOSTS2
Add-Content "C:\HOSTSUPDATE\HOSTS2.log" $HOSTS3
#Cambiar la fecha1 de cabeza a la fecha de recogida de datos. Es decir la fecha actual cuando
# se inicia el ordenador por primera vez en el día o si no se inicia porque ha estado encendido
# todo el tiempo
$fecha=Get-Date -format "dd-MM-yyyy"
$fecha2=Get-Date
$fecha2=[DateTime]::Parse($fecha2)
$filelist = Get-ChildItem "C:\HOSTSUPDATE\HOSTS2.log"
foreach ($file in $filelist){
$new = (Get-Content $file.fullname) -replace "fecha1", $fecha
Set-Content $file.fullname $new
$new2 = (Get-Content $file.fullname) -replace "fecha2", $fecha2
Set-Content $file.fullname $new2
}
# Aqui ya construimos el HOSTS renombrando el HOSTS2. log y eliminamos los archivos auxiliares.
if (!($error[0])) {
if(!($FileExists)) {
Remove-Item c:\HOSTSUPDATE\HOSTS
Rename-Item C:\HOSTSUPDATE\HOSTS2.log HOSTS
Remove-Item C:\HOSTSUPDATE\file1.log
Remove-Item C:\HOSTSUPDATE\file2.log
Remove-Item C:\HOSTSUPDATE\file3.log
Remove-Item C:\HOSTSUPDATE\file4.log
Remove-Item C:\HOSTSUPDATE\file6.log
Remove-Item C:\HOSTSUPDATE\HOSTS1
}
else {
Remove-Item C:\HOSTSUPDATE\hosts.bak
Rename-Item C:\HOSTSUPDATE\HOSTS hosts.bak
Rename-Item C:\HOSTSUPDATE\HOSTS2.log HOSTS
Remove-Item C:\HOSTSUPDATE\file1.log
Remove-Item C:\HOSTSUPDATE\file2.log
Remove-Item C:\HOSTSUPDATE\file3.log
Remove-Item C:\HOSTSUPDATE\file4.log
Remove-Item C:\HOSTSUPDATE\file6.log
Remove-Item C:\HOSTSUPDATE\HOSTS1
}
# Aqui borramos los archivos antiguos y copiamos los nuevos de la carpeta auxiliar a la de Windows
Set-ItemProperty C:\Windows\System32\Drivers\etc\hosts.bak -name IsReadOnly -value $false
Set-ItemProperty C:\Windows\System32\Drivers\etc\HOSTS -name IsReadOnly -value $false
Remove-Item C:\Windows\System32\Drivers\etc\hosts.bak #esto funciona
Rename-Item C:\Windows\System32\Drivers\etc\HOSTS hosts.bak
#hasta aquí funciona. Ahora tenemos que poner el HOST de AdZHost en Windows
Copy-Item -Path C:\HOSTSUPDATE\HOSTS -Destination C:\Windows\System32\Drivers\etc\HOSTS
Set-ItemProperty C:\Windows\System32\Drivers\etc\HOSTS -name IsReadOnly -value $true
Set-ItemProperty C:\Windows\System32\Drivers\etc\hosts.bak -name IsReadOnly -value $true
}
else {
#$error[0]
}
# Aqui enviamos los emails cuando corresponda. En el caso de uno solo, lo hacemos todos los días
# En el caso de envio a varios lo hacemos cada 7 dias.
#Esto es para uno solo
#$EmailTo = "a friend@orange.es"
#$EmailFrom = "myemail@gmail.com"
#$Subject = "Archivo HOSTS"
#$Body = "Hay que ponerlo en C:\windows\system32\Drivers\etc y substituir el que hay.Cada semana recibirás la actualización"
#$SMTPServer = "smtp.gmail.com"
#$filenameAndPath = "C:\HOSTSUPDATE\HOSTS"
#$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
#$attachment = New-Object System.Net.Mail.Attachment($filenameAndPath)
#$SMTPMessage.Attachments.Add($attachment)
#$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
#$SMTPClient.EnableSsl = $true
#$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("miemail", "miclave");
#$SMTPClient.Send($SMTPMessage)
#esto es para varios
$date=$a = (Get-Date).Day
if ($date -eq 7 -or $date -eq 14 -or $date -eq 21 -or $date -eq 28) {
$recipients="a friend@hotmail.com" , "anotherfriend@hotmail.com" , "my@orange.es"
$filenameAndPath = "C:\HOSTSUPDATE\HOSTS"
$storage = "C:\HOSTSUPDATE\tdata.txt"
$secureString = Get-Content -Path $storage | ConvertTo-SecureString
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString)
$pasw = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
$secpasswd = ConvertTo-SecureString $pasw -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("myemail", $secpasswd)
Send-MailMessage -from myemail@gmail.com -To $recipients -Subject "Archivo HOSTS" -Body "Hay que ponerlo en C:\windows\system32\Drivers\etc y substituir el que hay.Cada semana recibirás la actualización" -SMTPServer "smtp.gmail.com" -Attachments $filenameAndPath -Credential $mycreds -Usessl
}
else {
}
} # para cerrar el else de comprobación de fecha
# Puesto aquí para no olvidar, la rutina de como se genera el
#archivo tdata.txt que almacena la clave codificada del email
#figura en el archivo storecredential.ps1
#$storage = "C:\HOSTSUPDATE\tdata.txt"
#$mysecret = 'miclavedelemail'
#$mysecret |
# ConvertTo-SecureString -AsPlainText -Force |
# ConvertFrom-SecureString |
# Out-File -FilePath $storage
------------------------
cabeza.txt
"
# Este Archivo HOSTS es el resultado de la fusion de los tres archivos
# descargados de las paginas siguientes:
# http://someonewhocares.org/hosts/zero/
# http://www.malwaredomainlist.com/hostslist/hosts.txt
# http://www.winhelp2002.mvps.org/hosts.txt
# Los dos primeros se actualizan casi cada dia. El tercero lo hace con mucho
# mas espacio de tiempo. Lo he puesto aqui por su popularidad y lo buscamos
# solo los dias 7 ,14,21 y 28 de cada mes.
# Este archivo no redirige a 127.0.0.1 ni a 0.0.0.0 si no a 255.255.255.0. Ver Wikipedia española para entenderlo.
# Actualización automática programada todos los días a las 12:00 horas
# Nota.- No hay acentos en las palabras porque las escribe mal.
# Por Emilio Mari en Fecha:fecha1
# Fecha Larga: fecha2
#<localhost>
127.0.0.1 localhost loopback
::1 localhost #[IPv6]
#</localhost>
#Llamadas cortas
192.168.1.1 livebox # entrada al modem livebox para trabajar en el
193.41.234.22 ing # www.ingdirect.es
#Final llamadas Cortas
#Inicio de paginas bloqueadas
"
No "" but the code inside