伙计我在将Perl脚本转换为PowerShell时遇到了一些问题,我需要一些帮助。在我们机器的主机文件中,我们阻止了所有测试环境的URL。在我的PERL脚本中,根据选择的环境,它将注释掉所选环境的行以允许访问并阻止其他环境,以便测试人员不会错误地在错误的环境中执行操作。
我需要帮助转换为powershell
以下是我在PERL中的内容:
sub editHosts {
print "Editing hosts file...\n";
my $file = 'C:\\Windows\\System32\\Drivers\\etc\\hosts';
my $data = readFile($file);
my @lines = split /\n/, $data;
my $row = '1';
open (FILE, ">$file") or die "Cannot open $file\n";
foreach my $line (@lines) {
if ($line =~ m/$web/) {
print FILE '#'."$line\n"; }
else {
if ($row > '21') {
$line =~ s/^\#*127\.0\.0\.1/127\.0\.0\.1/;
$line =~ s/[#;].*$//s; }
print FILE "$line\n"; }
$row++;
}
close(FILE);
}
以下是我在Powershell中尝试过的内容:
foreach ($line in get-content "C:\windows\system32\drivers\etc\hosts") {
if ($line -contains $web) {
$line + "#"
}
我尝试过包含set-content的变体,包括以前在主机文件中的内容等等。
任何帮助将不胜感激!
谢谢, 格兰特
答案 0 :(得分:2)
-contains是一个“set”运算符,而不是子字符串运算符。试试.Contains()或者像。
答案 1 :(得分:2)
这将注释掉与变量$word
匹配的行,同时从不匹配项中删除#
(标题除外):
function Edit-Hosts ([string]$Web, $File = "C:\windows\system32\drivers\etc\hosts") {
#If file exists and $web is not empty/whitespace
if((Test-Path -Path $file -PathType Leaf) -and $web.Trim()) {
$row = 1
(Get-Content -Path $file) | ForEach-Object {
if($_ -like "*$web*") {
#Matched PROD, comment out line
"#$($_)"
} else {
#No match. If past header = remove comment
if($row -gt 21) { $_ -replace '^#' } else { $_ }
}
$row++
} | Set-Content -Path $file
} else {
Write-Error -Category InvalidArgument -Message "'$file' doesn't exist or Web-parameter is empty"
}
}
用法:
Edit-Hosts -Web "PROD"
答案 2 :(得分:0)
对于Frode F.的答案,这是一个类似的答案,但我还没有评论加上我的2c值,所以必须提供替代答案。
在这个示例中,看起来像是从perl移动到PowerShell的其中一个问题是,当我们使用Get-Content
获取文件的内容时,它是一个“离线”副本,即没有进行任何编辑直接到文件本身。一种方法是将新内容编译到整个文件,然后将其写回磁盘。
我认为perl中的print FILE "some text\n";
构造可能与PowerShell中的"some text" | Out-File $filename -Encoding ascii -Append
类似,尽管你会使用后者(1)逐行写入新的/空文件或(2)接受您附加现有内容。
关于编辑主机文件的另外两件事:
无论如何,这是使用Out-File
的上一个答案的版本:
$FileName = "C:\windows\system32\drivers\etc\hosts"
$web = "PROD"
# Get "offline" copy of file contents
$FileContent = Get-Content $FileName
# The following creates an empty file and returns a file
# object (type [System.IO.FileInfo])
$EmptyFile = New-Item -Path $FileName -ItemType File -Force
foreach($Line in $FileContent) {
if($Line -match "$web") {
"# $Line" | Out-File $EmptyFile -Append -Encoding ascii
} else {
"$Line" | Out-File $EmptyFile -Append -Encoding ascii
}
}
($Line -match "$web")
获取 $ web 变量中的任何内容,并将其视为正则表达式。在我的示例中,我假设您只是想匹配一个简单的文本字符串,但您可能正在尝试匹配IP地址等。您有几个选项:
($Line -like "*$web*")
。($Line -match [Regex]::Escape($web))
执行此操作。 -replace
。所以......这是foreach
循环的更新版本:
$LineCount = 1
foreach($Line in $FileContent) {
if($Line -match [Regex]::Escape($web) {
# ADD comment to any matched line
$Line = "#" + $Line
} elseif($LineCount -gt 21) {
# Uncomment the other lines
$Line = $Line -replace '^[# ]+',''
}
# Remove 'stacked up' comment characters, if any
$Line = $Line -replace '[#]+','#'
$Line | Out-File $EmptyFile -Append -Encoding ascii
$LineCount++
}
答案 3 :(得分:0)
如果您想验证其中的内容然后添加条目,则可以使用以下内容,该内容旨在以交互方式运行,并返回您在变量中指定的所有现有条目:
注意:“ t是powershell”在'Tab'命令的脚本方法中。
$hostscontent
# Script to Verify and Add Host File Entries
$hostfile = gc 'C:\Windows\System32\drivers\etc\hosts'
$hostscontent1 = $hostfile | select-string "autodiscover.XXX.co.uk"
$hostscontent2 = $hostfile | select-string "webmail.XXX.co.uk"
$1 = "XX.XX.XXX.XX`tautodiscover.XXX.co.uk"
$2 = "webmail.XXX.co.uk"
# Replace this machines path with a path to your list of machines e.g. $machines = gc \\machine\machines.txt
$machines = gc 'c:\mytestmachine.txt'
ForEach ($machine in $machines) {
If ($hostscontent1 -ne $null) {
Start-Sleep -Seconds 1
Write-Host "$machine Already has Entry $1" -ForegroundColor Green
} Else {
Write-Host "Adding Entry $1 for $machine" -ForegroundColor Green
Start-Sleep -Seconds 1
Add-Content -Path C:\Windows\System32\drivers\etc\hosts -Value "XX.XX.XXX.XX`tautodiscover.XXX.co.uk" -Force
}
If ($hostscontent2 -ne $null) {
Start-Sleep -Seconds 1
Write-Host "$machine Already has Entry $2" -ForegroundColor Green
} Else {
Write-Host "Adding Entry $2 for $machine" -ForegroundColor Green
Start-Sleep -Seconds 1
Add-Content -Path C:\Windows\System32\drivers\etc\hosts -Value "XX.XX.XXX.XX`twebmail.XXX.co.uk" -Force
}
}