2010-04-08 78 views
27

我正在查看是否可以创建PowerShell脚本来更新主机文件中的内容。Powershell操纵主机文件

有人知道是否有任何使用powershell或任何其他脚本语言操纵主机文件的示例?

谢谢。

+0

只是追加到文件(写入它,它有足够的权限)应该做的伎俩。 – ChristopheD 2010-04-08 18:37:01

回答

26

一起来,如果你是在Vista或Windows 7,确保你从提升的提示符下运行这些命令:

# Uncomment lines with localhost on them: 
$hostsPath = "$env:windir\System32\drivers\etc\hosts" 
$hosts = get-content $hostsPath 
$hosts = $hosts | Foreach {if ($_ -match '^\s*#\s*(.*?\d{1,3}.*?localhost.*)') 
          {$matches[1]} else {$_}} 
$hosts | Out-File $hostsPath -enc ascii 

# Comment lines with localhost on them: 
$hosts = get-content $hostsPath 
$hosts | Foreach {if ($_ -match '^\s*([^#].*?\d{1,3}.*?localhost.*)') 
        {"# " + $matches[1]} else {$_}} | 
     Out-File $hostsPath -enc ascii 

有鉴于此,我认为,你可以看到如何使用正则表达式来处理条目必要。

+0

取消注释工作很好,但评论只打印控制台中的[适当]输出,我以管理员身份运行脚本,缺少某些内容? – veritas 2012-07-26 18:10:45

+0

@veritas我怀疑正则表达式模式存在问题。这是更好的''^ \ s *([^#]。+?\ d {1,3}。*?localhost。*)'' – 2012-07-26 18:56:50

+0

我发现'$ hosts'变量在'foreach '并在对文件进行foreach之后简单地对所有输出进行流水线操作:'$ hosts | foreach {...} | Out-File $ hostsPath -enc ascii'并且它可以工作。 – veritas 2012-07-26 19:03:05

2

我写了一个代码来删除主机中的条目。您可以轻松地更改代码以从代码中添加条目。

$domainName = "www.abc.com" 
$rplaceStr = "" 
$rHost = "C:\Windows\System32\drivers\etc\hosts" 
$items = Get-Content $rHost | Select-String $domainName 
Write-host $items 
foreach($item in $items) 
{ 
(Get-Content $rHost) -replace $item, $rplaceStr| Set-Content $rHost 
} 

欲了解更多信息,请参阅 http://nisanthkv.blog.com/2012/06/13/remove-host-entries-using-powershell/

+0

您不需要使用html来插入代码,只需用4个空格缩进代码即可。 – Dhara 2012-06-14 19:37:06

17

Carbon module一个用于设置主机条目Set-HostsEntry功能:在处理hosts文件

Set-HostsEntry -IPAddress 10.2.3.4 -HostName 'myserver' -Description "myserver's IP address" 
0

对我来说,最大的痛苦是记住哪里它是。我在我的PowerShell配置文件中设置了一个指向我的hosts文件的变量,这使得在文本编辑器中编辑变得容易。

在PowerShell中,键入以下命令来打开您的个人资料:

C:\> Notepad $profile 

补充一点:

$hosts = "$env:windir\System32\drivers\etc\hosts" 

保存文件,然后关闭并重新打开PowerShell中,以管理员身份运行。您无法在没有提升权限的情况下编辑主机文件。

现在,您可以编辑您的主机文件你编辑您的资料以同样的方式:如果有人正在寻找一个更高级的例子

C:\> Notepad $hosts 
17

,我一直特别喜欢这个要点:https://gist.github.com/markembling/173887

# 
# Powershell script for adding/removing/showing entries to the hosts file. 
# 
# Known limitations: 
# - does not handle entries with comments afterwards ("<ip> <host> # comment") 
# 

$file = "C:\Windows\System32\drivers\etc\hosts" 

function add-host([string]$filename, [string]$ip, [string]$hostname) { 
    remove-host $filename $hostname 
    $ip + "`t`t" + $hostname | Out-File -encoding ASCII -append $filename 
} 

function remove-host([string]$filename, [string]$hostname) { 
    $c = Get-Content $filename 
    $newLines = @() 

    foreach ($line in $c) { 
     $bits = [regex]::Split($line, "\t+") 
     if ($bits.count -eq 2) { 
      if ($bits[1] -ne $hostname) { 
       $newLines += $line 
      } 
     } else { 
      $newLines += $line 
     } 
    } 

    # Write file 
    Clear-Content $filename 
    foreach ($line in $newLines) { 
     $line | Out-File -encoding ASCII -append $filename 
    } 
} 

function print-hosts([string]$filename) { 
    $c = Get-Content $filename 

    foreach ($line in $c) { 
     $bits = [regex]::Split($line, "\t+") 
     if ($bits.count -eq 2) { 
      Write-Host $bits[0] `t`t $bits[1] 
     } 
    } 
} 

try { 
    if ($args[0] -eq "add") { 

     if ($args.count -lt 3) { 
      throw "Not enough arguments for add." 
     } else { 
      add-host $file $args[1] $args[2] 
     } 

    } elseif ($args[0] -eq "remove") { 

     if ($args.count -lt 2) { 
      throw "Not enough arguments for remove." 
     } else { 
      remove-host $file $args[1] 
     } 

    } elseif ($args[0] -eq "show") { 
     print-hosts $file 
    } else { 
     throw "Invalid operation '" + $args[0] + "' - must be one of 'add', 'remove', 'show'." 
    } 
} catch { 
    Write-Host $error[0] 
    Write-Host "`nUsage: hosts add <ip> <hostname>`n  hosts remove <hostname>`n  hosts show" 
} 
+0

存在暂时无法访问文件(锁定)的问题。注意如果我运行两次,它通常会被释放。可能很适合在重试中包装保存超文件。 – sonjz 2017-10-18 18:01:49

4

从上面的Kevin Remisoski的出色答案开始,我想出了一个让我一次添加/更新多个条目的方法。我也改变了分裂的正则表达式来寻找任何空白区域,而不仅仅是tab。

function setHostEntries([hashtable] $entries) { 
    $hostsFile = "$env:windir\System32\drivers\etc\hosts" 
    $newLines = @() 

    $c = Get-Content -Path $hostsFile 
    foreach ($line in $c) { 
     $bits = [regex]::Split($line, "\s+") 
     if ($bits.count -eq 2) { 
      $match = $NULL 
      ForEach($entry in $entries.GetEnumerator()) { 
       if($bits[1] -eq $entry.Key) { 
        $newLines += ($entry.Value + '  ' + $entry.Key) 
        Write-Host Replacing HOSTS entry for $entry.Key 
        $match = $entry.Key 
        break 
       } 
      } 
      if($match -eq $NULL) { 
       $newLines += $line 
      } else { 
       $entries.Remove($match) 
      } 
     } else { 
      $newLines += $line 
     } 
    } 

    foreach($entry in $entries.GetEnumerator()) { 
     Write-Host Adding HOSTS entry for $entry.Key 
     $newLines += $entry.Value + '  ' + $entry.Key 
    } 

    Write-Host Saving $hostsFile 
    Clear-Content $hostsFile 
    foreach ($line in $newLines) { 
     $line | Out-File -encoding ASCII -append $hostsFile 
    } 
} 

$entries = @{ 
    'aaa.foo.local' = "127.0.0.1" 
    'bbb.foo.local' = "127.0.0.1" 
    'ccc.foo.local' = "127.0.0.1" 
}; 
setHostEntries($entries) 
+0

不错;)我将不得不使用它,最近以为我没有使用wamp类型的环境。那么,其实我刚刚迁移了。我有一个双启动机器,但是因为我的其他需要,我在大多数时间被困在Windows中,所以我决定安装Windows(基于Ubuntu)的bash和man在屁股情况下多么不痛苦的时候它适用于从Windows本地开发环境迁移到Linux Dev或Live版本。 – 2017-05-01 00:03:26