这是在PowerShell -noprofile中的Windows XP SP3上的Powershell v2中运行。
下面的Powershell脚本如果我将其复制并粘贴到控制台中,但如果我将其作为脚本运行则不起作用。任何人都可以看到可能导致这种情况的原因吗?
脚本如下(某些名称已被更改以保护无辜者)。
#Known Error values to count instances of
$KnownErrorText = @"
Invalid Descriptor Index
Syntax error or access violation
An error occurred while attemping to update a record
Message from LDAP server: Invalid credentials
Error sending data over TCP connection
"@
#Fix the variable so it's an array
$KnownErrorText = $knownErrorText.split("`n")
#output variables
$KnownErrors = @{}
$UnknownErrors = @()
#Generate the hash to contain counts of the the known errors
foreach ($line in $knownErrorText) {$KnownErrors.Add($line,0)}
#Get error lines from the log
$scerrors = Select-String -Path "\\myserver01\d$\logs\application.log" -Pattern "Error"
"$($scerrors.count) errors to process"
$ProcessedErrors = 1
#Look at each error. Pass the error through a switch to identify whether it's
#a known error or not. If it's Known, increment the appropriate count in the hash
#if it's not known, add it to the unknown errors output variable
foreach ($e in $scerrors) {
"$($ProcessedErrors)`tProcessing`t$($e.line)"
$addToUnknown = $true
"e.line type:`t$($e.line.gettype().name)`tLength$($e.line.length)"
switch -regex ($knownErrorText) {
#Look in the text of the current error for the any of the errors in
#the KnownErrorText array
#THIS IS THE PART THAT DOESN'T WORK WHEN RUNNING IN A SCRIPT
{"$($e.line)" -match "^.*$($_).*`$"} {
Write-host "Matched $($_)" -ForegroundColor Green -BackgroundColor Black
$KnownErrors.Set_Item($_,([int]$KnownErrors.Get_Item($_))+1)
$addToUnknown = $false
#We found our match so stop
#processing the KnownErrorText array through the switch
break
}
default {
Write-host "UnMatched`t$($_)" -ForegroundColor Red -BackgroundColor Black
}
}
#If we got through all the KnownErrorText values without finding a match,
#add the error to the UnknownErrors array to be displayed
if ($addToUnknown) {$UnknownErrors += $e}
$ProcessedErrors++
if ($ProcessedErrors -ge 5) {break}
}
#Console reporting
"Known Errors:"
$KnownErrors.GetEnumerator() | Sort-Object Value -Descending
""
"$($UnknownErrors.count) Unknown Errors:"
$UnknownErrors | Foreach {$_.line}
当我将其作为脚本运行时(例如,如果保存到c:\ temp \ ErrorReporting.ps1并调用
& c:\Temp\ErrorReporting.ps1
匹配部分失败:
{"$($e.line)" -match "^.*$($_).*
$“}`
答案 0 :(得分:1)
问题是由于字符串拆分操作在脚本与控制台中的工作方式不同。粘贴到控制台可能会产生不同的行结尾,保存的脚本文件包含(\r\n
vs \n
)。因此,有助于明确指定$knownErrorText
数组,而不是拆分字符串以生成它。
$knownErrorText = 'Invalid Descriptor Index',
'Syntax error or access violation',
...
除了:
您没有按预期使用switch -Regex
。标准用法不是让一个脚本块进行-match
比较来定义案例,而是简单地提供一个与输入匹配的正则表达式字符串。例如
$myStr = 'abc123'
switch -regex ($myStr)
{
'abc\d\d\d' { 'abc with 3 numbers'; break }
'xyz\d\d\d' { 'xyz with 3 numbers'; break }
}
如果您在脚本块内部进行检查以定义案例,则实际上根本不需要-regex
标志。
您的目标似乎是检查$e.Line
是否包含任何已知的错误消息。如果是这样,那么开关可能不是最好的工具,无论如何。您可以非常简单地执行此操作:
foreach ($e in $scerrors)
{
if( $knownErrors |?{$e.Line -match $_} )
{
"$($e.Line) matches a known error"
}
else
{
"$($e.Line) does not match a known error"
}
}