iNNOKENTIY21
Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Код: param ( # Полный путь к файлу hosts # По умолчанию папка windows\system32\drivers\etc\hosts [ValidateScript({[IO.File]::Exists($PSItem)})] [IO.FileInfo] $PathHosts = (Join-Path -Path $env:windir -ChildPath 'system32\drivers\etc\hosts'), # Полный путь к директории, где лежат файлы в формате hosts # По умолчанию в папке пользователя Documents\Hosts\BlockIP [IO.DirectoryInfo] $PathBlock = (Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath 'Hosts\BlockIP'), # Директория для резервной копии. # По умолчанию в папке пользователя Documents\Hosts\Backups [string] $BakFileDir = (Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath 'Hosts\Backups'), # Имя файла резервной копии. # По умолчанию имя файла из $PathHosts + FileTime + .bak # Преобразовать FileTime обратно в человекочитаемую дату время: # [datetime]::FromFileTime(long FileTime) [string] $BakFileName = ($PathHosts.Name + "-$((Get-Date).ToFileTime()).bak"), # Регулярное выражение для разбора строк. # Важно, что бы строка делилась на три именнованых части: ip, hostname, tail # https://github.com/webmd-health-services/Carbon/blob/develop/Carbon/Functions/Set-HostsEntry.ps1 [regex] $Pattern = '^(?<IP>[0-9a-f.:]+)\s+(?<HostName>[^\s#]+)(?<Tail>.*)$', # Переключаетль "тихо", если указан, то вывода не будет, всё сделает молча, кроме ошибок. [switch] $Silent ) # Проверка существования директории указанной в $PathBlock, если нет, стоп ошибка if (![IO.Directory]::Exists($PathBlock)) { throw "$PathBlock - директория не найдена!" } # Проверка существования директории указанной в $BakFileDir, если нет, стоп ошибка if (![IO.Directory]::Exists($BakFileDir)) { throw "$BakFileDir - директория не найдена!" } # Ковертирует строку в объект с тремя полями: ip, hostname, tail # Принимает строку [string], отдаёт объект [PSCustomObject] filter ConvertFrom-Hosts { if ($PSItem.Trim() -match $pattern) { [PSCustomObject] @{ IP = $matches["IP"] Host = $matches["HostName"] Tail = $matches["Tail"].Trim() } } } # Проверяет правильность записи ip # Принимает объект в котором есть поле ip, отдаёт тот же объект, если прошел проверку filter ValidIP { $ip = $null if ([ipaddress]::TryParse($PSItem.ip, [ref] $ip)) { $PSItem } } # Конвертирует объект с тремя полями: ip, hostname, tail, в строку с расстановкой табуляторов filter ConvertTo-Hosts { "`t{0}`t`t{1}`t`t{2}" -f $PSItem.IP, $PSItem.Host, $PSItem.Tail } $hosts = Get-Content -Path $PathHosts -ErrorAction Stop | ConvertFrom-Hosts $block = ls -file -path $PathBlock | Get-Content | ConvertFrom-Hosts | ValidIP # Формируется список для добавления, без дублей ip, без уже имеющихся ip в $PathHosts $append = $block | group -Property ip | % {$PSItem.Group[0]} | ? ip -NotIn $hosts.ip if ($append) { $BakFile = Join-Path -Path $BakFileDir -ChildPath $BakFileName Copy-Item -Path $PathHosts -Destination $BakFile Add-Content -Path $PathHosts '' $append | ConvertTo-Hosts | Add-Content -Path $PathHosts if (!$Silent) {$append} [void] {ipconfig /flushdns} } <# .SYNOPSIS Добавление строк в hosts из файлов .DESCRIPTION Добавляет в файл типа hosts строки с ip адресами, из файлов в указанной директории. Файлы из которых нужно добавить строки, тоже должны быть в формате hosts. Проверяет правильность записи ip, неправильные игнорируются в hosts не добавляются. Проверяет добавляемые ip с уже имеющимеся в hosts. Проверяет на дубли (одинаковые) ip, полученные из файлов. Bakups файлы не удаляются, копятся с меткой времени, в укзанной папке. Автор: iNNOKENTIY21 #> |
|