0

这是在 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 "^.*$($_).*$"}`

4

1 回答 1

1

问题是由于字符串拆分操作在脚本和控制台中的工作方式不同。粘贴到控制台可能会产生保存的脚本文件包含的不同行尾(\r\n与 just 相比\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"
   }
}
于 2012-10-10T18:03:19.047 回答