Powershell操作主机文件

Powershell操作主机文件,powershell,Powershell,我正在查看是否可以创建powershell脚本来更新主机文件中的内容 有人知道是否有使用powershell或任何其他脚本语言操纵主机文件的示例吗 谢谢。首先,如果您使用的是Vista或Windows 7,请确保在提升的提示符下运行以下命令: # Uncomment lines with localhost on them: $hostsPath = "$env:windir\System32\drivers\etc\hosts" $hosts = get-content $hostsPath

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

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


谢谢。

首先,如果您使用的是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

鉴于此,我认为您可以看到如何在必要时使用正则表达式来操作条目。

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

$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
}
有关更多信息,请参阅

具有设置主机条目的功能:

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

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

在PowerShell中,键入以下内容以打开您的配置文件:

C:\> Notepad $profile
C:\> Notepad $hosts
添加以下内容:

$hosts = "$env:windir\System32\drivers\etc\hosts"
保存文件,然后关闭并重新打开PowerShell,以管理员身份运行。没有提升的权限,您无法编辑主机文件

现在,您可以像编辑配置文件一样编辑主机文件:

C:\> Notepad $profile
C:\> Notepad $hosts

如果有人在寻找更高级的示例,我一直特别喜欢以下要点:

#
#用于向主机文件添加/删除/显示条目的Powershell脚本。
#
#已知的限制:
#-不处理事后带有注释的条目(“注释”)
#
$file=“C:\Windows\System32\drivers\etc\hosts”
函数添加主机([string]$filename,[string]$ip,[string]$hostname){
删除主机$filename$hostname
$ip+“`t`t”+$hostname | Out文件-编码ASCII-追加$filename
}
函数删除主机([string]$filename,[string]$hostname){
$c=获取内容$filename
$newLines=@()
foreach($c中的行){
$bits=[regex]::拆分($line,“\t+”)
如果($bits.count-等式2){
if($bits[1]-ne$hostname){
$newLines+=$line
}
}否则{
$newLines+=$line
}
}
#写入文件
清除内容$filename
foreach($换行符中的行){
$line | Out文件-编码ASCII-追加$filename
}
}
函数打印主机([string]$filename){
$c=获取内容$filename
foreach($c中的行){
$bits=[regex]::拆分($line,“\t+”)
如果($bits.count-等式2){
写入主机$bits[0]`t`t$bits[1]
}
}
}
试一试{
如果($args[0]-eq“添加”){
如果($args.count-lt 3){
抛出“添加的参数不足”
}否则{
添加主机$file$args[1]$args[2]
}
}elseif($args[0]-eq“remove”){
如果($args.count-lt 2){
抛出“删除的参数不足”
}否则{
删除主机$file$args[1]
}
}elseif($args[0]-eq“show”){
打印主机$file
}否则{
抛出“无效操作”'+$args[0]+'-必须是“添加”、“删除”、“显示”之一
}
}抓住{
写入主机$error[0]
写入主机“`nUsage:hosts add`n hosts remove`n hosts show”
}

从凯文·雷米索斯基(Kevin Remisoski)的出色回答开始,我想出了一个方法,可以一次添加/更新多个条目。我还更改了拆分中的正则表达式,以查找任何空白,而不仅仅是制表符

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)

我编写了一个快速脚本,创建了一个简单的GUI,用于向主机文件添加新记录。它将打开一个窗口,询问主机名和IP,然后将您的输入附加到主机文件

我相信它可以简化,看起来更干净。。。但是对于我的用例来说效果很好

享受吧

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$hostsfilelocation = "$env:windir\System32\drivers\etc\hosts"
$readhostsfile = Get-Content $hostsfilelocation

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Update HOSTS File'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$AddHosts = New-Object System.Windows.Forms.Button
$AddHosts.Location = New-Object System.Drawing.Point(55,120)
$AddHosts.Size = New-Object System.Drawing.Size(90,25)
$AddHosts.Text = 'Add Record'
$AddHosts.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $AddHosts
$form.Controls.Add($AddHosts)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(170,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,25)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$Hostslabel = New-Object System.Windows.Forms.Label
$Hostslabel.Location = New-Object System.Drawing.Point(10,20)
$Hostslabel.Size = New-Object System.Drawing.Size(280,20)
$Hostslabel.Text = 'Enter New HOSTNAME/FQDN:'
$form.Controls.Add($Hostslabel)

$HoststextBox = New-Object System.Windows.Forms.TextBox
$HoststextBox.Location = New-Object System.Drawing.Point(10,40)
$HoststextBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($HoststextBox)

$IPlabel = New-Object System.Windows.Forms.Label
$IPlabel.Location = New-Object System.Drawing.Point(10,60)
$IPlabel.Size = New-Object System.Drawing.Size(280,20)
$IPlabel.Text = 'Enter IP:'
$form.Controls.Add($IPlabel)

$IPtextBox = New-Object System.Windows.Forms.TextBox
$IPtextBox.Location = New-Object System.Drawing.Point(10,80)
$IPtextBox.Size = New-Object System.Drawing.Size(260,20)
$form.Controls.Add($IPtextBox)

$form.Topmost = $true

$form.Add_Shown({($HoststextBox,$IPtextbox).Select()})

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $inputhosts = $HoststextBox.Text
    $inputip = $IPtextBox.Text
    $newrecord = "$inputip $inputhosts"
    Add-Content -Path $hostsfilelocation -Value $newrecord
}

所有这些答案都非常详细。以下是添加主机文件条目所需的全部内容:

Add-Content -Path $env:windir\System32\drivers\etc\hosts -Value "`n127.0.0.1`tlocalhost" -Force
IP地址和主机名由`t分隔,t是选项卡字符的PowerShell表示法


`n是换行符的PowerShell符号。

99%的时间需要管理员权限才能修改主机记录。尝试在Powershell脚本的顶部添加此代码

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

只需附加到文件(写入,如果您有足够的权限)就可以了。取消注释效果很好,但注释只在控制台中打印[正确的]输出,我以管理员身份运行脚本,缺少一些内容?@veritas我怀疑正则表达式模式有问题。这更好吗?我发现
$hosts
变量在
foreach
之后没有更新,只是将foreach之后的所有输出管道化到文件:
$hosts | foreach{…}|输出文件$hostsPath-enc ascii
并正常工作。哦,等等:现在我看到注释部分的问题在哪里了
$hosts
变量没有重新设计;)不错;)我必须好好玩玩它,因为我最近没有使用wamp类型的环境。嗯,实际上我刚移民。我有一个双启动机器,但是由于我的其他需要,我大部分时间都被困在Windows中,所以我决定安装bash for Windows(基于Ubuntu)当从Windows本地开发环境迁移到Linux开发环境或Live版本时,ass情况下的痛苦要小得多。存在临时无法访问文件(锁定)的问题。请注意,如果我运行它两次,它通常会被释放两次。最好在重试时包装保存文件。最简单的一个。您可能希望使用
$env:windir
而不是硬编码的
C:\Windows
,以防死角…注意:您需要在添加换行符之前添加一行,否则它将仅附加到最后编辑的hosts条目,以包含上述建议。