[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] 使用powershell 修改host文件

以前一直使用cmd批处理修改host文件, 刚刚在一段ps代码中添加修改host的代码, 就搜索了一下资源, 找到如下代码, 但是测试了一下, 不稳, 问题如下, 请高手指点, 感谢!
问题1. -enc ascii 这个参数居然会把原文件编码格式改为UTF8, 真是怪了
问题2.在已经有记录的情况下,仍然会追加记录
问题3.追加完后,用notepad2打开文件,提示换行符不一致
  1. $IP_URL = "127.0.0.1 www.bing.com"
  2. if ((Get-Content $env:windir\System32\drivers\etc\hosts | ?{ $_ -match "/s$IP_URL" }) -eq $null)
  3. {
  4. "`n$IP_URL" | Out-File "$env:windir\System32\drivers\etc\hosts" -Append -enc ascii
  5. echo "已添加!"
  6. }
  7. else
  8. {
  9. echo "已存在"
  10. }
复制代码

  1. $IP_URL = "127.0.0.1 www.bing.com"
  2. if ((Get-Content $env:windir\System32\drivers\etc\hosts | ?{ $_ -match "$($IP_URL -replace '\s+','\s+')" }) -eq $null)
  3. {
  4. "$IP_URL" | ac "$env:windir\System32\drivers\etc\hosts"
  5. echo "已添加!"
  6. }
  7. else
  8. {
  9. echo "已存在"
  10. }
复制代码

TOP

回复 2# idwma


    感谢大侠帮忙, 现在可以了, 请教下面代码中把空格替换成空格什么意思?
$IP_URL -replace '\s+','\s+'

TOP

回复 3# 5i365


    你看这两个是一样的吗?
  1. $IP_URL = "127.0.0.1 www.bing.com"
  2. $IP_URL11 = "127.0.0.1   www.bing.com"
  3. $IP_URL -match $IP_URL11
  4. $IP_URL -match "$($IP_URL11 -replace '\s+','\s+')"
复制代码

TOP

回复 4# idwma


感谢指点, 是不一样, 我其实不明白的是, 为什么要替换的和替换为的 是一样的正则表达, 按我的理解应该替换为'\s{1}'或'\s'

$IP_URL -match "$($IP_URL11 -replace '\s+','\s{1}')"

TOP

回复 5# 5i365

试试第一行多加几个空格前后增加中间穿插若干个空格
是不是感觉这个替换多于了,不加也可以的

TOP

回复 6# idwma


    感谢指点, 确实感觉多余了, 不加怎么可以? 我试了不行, 返回false

TOP

回复 6# idwma


    大侠, 如果是一次添加多行条目, 应该怎么改, 例如:
$IP_URL = @(
        "127.0.0.1 www.bing.com"
        "127.0.0.1 www.sina.com"
)

TOP

  1. $IP_URL = @(
  2.         "127.0.0.1 www.bing.com"
  3.         "127.0.0.1 www.sina.com"
  4. )
  5. $IP_URL -notmatch "$((Get-Content $env:windir\System32\drivers\etc\hosts | ?{ $_ -match "$($IP_URL -join '|')"}) -join '|')"|ac "$env:windir\System32\drivers\etc\hosts"
复制代码

TOP

回复 9# idwma


    刚试了下, 没有生效

TOP

回复 9# idwma


    老外的代码参考:
  1. # Uncomment lines with localhost on them:
  2. $hostsPath = "$env:windir\System32\drivers\etc\hosts"
  3. $hosts = get-content $hostsPath
  4. $hosts = $hosts | Foreach {if ($_ -match '^\s*#\s*(.*?\d{1,3}.*?localhost.*)')
  5.                            {$matches[1]} else {$_}}
  6. $hosts | Out-File $hostsPath -enc ascii
  7. # Comment lines with localhost on them:
  8. $hosts = get-content $hostsPath
  9. $hosts | Foreach {if ($_ -match '^\s*([^#].*?\d{1,3}.*?localhost.*)')
  10.                   {"# " + $matches[1]} else {$_}} |
  11.          Out-File $hostsPath -enc ascii
复制代码
-----------------------------------------------------------------------------------------------
  1. function setHostEntries([hashtable] $entries) {
  2.     $hostsFile = "$env:windir\System32\drivers\etc\hosts"
  3.     $newLines = @()
  4.     $c = Get-Content -Path $hostsFile
  5.     foreach ($line in $c) {
  6.         $bits = [regex]::Split($line, "\s+")
  7.         if ($bits.count -eq 2) {
  8.             $match = $NULL
  9.             ForEach($entry in $entries.GetEnumerator()) {
  10.                 if($bits[1] -eq $entry.Key) {
  11.                     $newLines += ($entry.Value + '     ' + $entry.Key)
  12.                     Write-Host Replacing HOSTS entry for $entry.Key
  13.                     $match = $entry.Key
  14.                     break
  15.                 }
  16.             }
  17.             if($match -eq $NULL) {
  18.                 $newLines += $line
  19.             } else {
  20.                 $entries.Remove($match)
  21.             }
  22.         } else {
  23.             $newLines += $line
  24.         }
  25.     }
  26.     foreach($entry in $entries.GetEnumerator()) {
  27.         Write-Host Adding HOSTS entry for $entry.Key
  28.         $newLines += $entry.Value + '     ' + $entry.Key
  29.     }
  30.     Write-Host Saving $hostsFile
  31.     Clear-Content $hostsFile
  32.     foreach ($line in $newLines) {
  33.         $line | Out-File -encoding ASCII -append $hostsFile
  34.     }
  35. }
  36. $entries = @{
  37.     'aaa.foo.local' = "127.0.0.1"
  38.     'bbb.foo.local' = "127.0.0.1"
  39.     'ccc.foo.local' = "127.0.0.1"
  40. };
  41. setHostEntries($entries)
复制代码
--------------------------------------------------------------
  1. $domainName = "www.abc.com"
  2. $rplaceStr = ""
  3. $rHost = "C:\Windows\System32\drivers\etc\hosts"
  4. $items = Get-Content $rHost | Select-String $domainName
  5. Write-host $items
  6. foreach( $item in $items)
  7. {
  8. (Get-Content $rHost) -replace $item, $rplaceStr| Set-Content $rHost
  9. }
复制代码

TOP

本帖最后由 5i365 于 2022-2-28 18:22 编辑

回复 9# idwma


    自己想了个办法, 但是如果host最后一行不是空行, 则第一行网址会跑到前一行的后面
测试了一下, add-content 确实有这个问题, 文件中最后一行没有空行, 就追加到最后一行的末尾了
  1. $Hosts = "$env:windir\System32\drivers\etc\hosts"
  2. $urls = @(
  3. "www.baidu.com"
  4. "www.bing.com"
  5. ) |
  6. foreach{
  7. if ((gc $Hosts | Select-String $_) -eq $null)
  8. {
  9. ac $hosts "127.0.0.1 $_"
  10. }
  11. }
复制代码

TOP

  1. $IP_URL = @(
  2.         "127.0.0.1 www.bing.com"
  3.         "127.0.0.1 www.sina.com"
  4. )
  5. $a=(Get-Content "$env:windir\System32\drivers\etc\hosts" | ?{ $_ -match "$($IP_URL -join '|')"}) -join '|'
  6. if ($a -eq '')
  7. {
  8. $IP_URL | ac "$env:windir\System32\drivers\etc\hosts"
  9. echo "已添加!"
  10. }
  11. else
  12. {
  13. $IP_URL -notmatch "$a" | ac "$env:windir\System32\drivers\etc\hosts"
  14. echo "已存在"
  15. }
复制代码

TOP

回复 13# idwma


    大侠, 使用ac和out-file都有这个问题, 最后一行没有空行, 就会追加到最后一行的末尾

TOP

回复 14# 5i365
  1. $Hosts = "$env:windir\System32\drivers\etc\hosts"
  2. $a=gc $Hosts
  3. $urls = @(
  4. "www.baidu.com"
  5. "www.bing.com"
  6. ) |
  7. foreach{
  8. if($a[-1] -ne ''){ac $hosts ''}elseif ((gc $Hosts | Select-String $_) -eq $null)
  9. {
  10. ac $hosts "127.0.0.1 $_"
  11. }
  12. }
复制代码

TOP

返回列表