2010-04-08 114 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