Powershell:如果命令输出与预期的 3 个字符串数组不同,则发送电子邮件

Powershell: Sending an email if output of command differs from the array of 3 strings that is expected

这是我目前得到的

如果命令放置第四行输出,则正则表达式不匹配,但对我来说是匹配的。

有什么想法吗?

$From = "cody@tech.com"
$To = "cody@tech.com"
$Subject = "hello"
$Body = "body"
$SMTPServer = "smtp.office365.com"
$SMTPPort = "587"
$Attachment = "c:\checkpointlog.txt"

$RE = [regex]"(?smi)^Checkpointing to checkpoint.*^MD5 \(checkpoint.*^Rotating D:\Perforce\Server\journal to journal.*?$"

$output = p4d -jc
$output | add-content c:\checkpointlog.txt

if ($output -notmatch $RE) { 
    $param = @{
        From        = $From
        To          = $To
        Subject     = $Subject
        Body        = $Body 
        SmtpServer  = $SMTPServer 
        port        = $SMTPPort 
        Usessl      = $True
        Credential  = $cred 
        Attachments = $Attachment
    }
    Send-MailMessage @param
    Write-Host 'unexpected value, email sent' 
    exit
}
else {
Write-Host 'continuing script' 

}

Perforce Helix 服务器命令 p4 -jc 的输出应始终类似于以下 3 行:

Checkpointing to checkpoint.22... 
MD5 (checkpoint.22) = F561234wer2B8E5123456767745645616D 
Rotating D:\Perforce\Server\journal to journal.21...

我想在 if 语句中使用正则表达式,这样如果输出与下面的 3 行字符串不匹配,则会发送一封包含日志文件的电子邮件供我们检查。

Checkpointing to checkpoint.*
MD5 (checkpoint.*
Rotating D:\Perforce\Server\journal to journal.*

我希望用通配符*来计算增量数

任何想法都会很棒!


$RE = [regex]"(?smi)^Checkpointing to checkpoint.*^MD5 \(checkpoint.*^Rotating D:\Perforce\Server\journal to journal.*?$"

$output = p4d -jc
$output | add-content c:\checkpointlog.txt

if ($output -notmatch $RE) { 
    $param = @{
        From        = $From
        To          = $To
        Subject     = $Subject
        Body        = $Body 
        SmtpServer  = $SMTPServer 
        port        = $SMTPPort 
        Usessl      = $True
        Credential  = $cred 
        Attachments = 'c:\checkpointlog.txt'
    }
    Send-MailMessage @param
    exit
}

我知道您想使用 RegEx,但也许这会有所帮助?它可能不是最好的,但应该可以。

$file='checkpointlog.txt'

$line1Expected="Checkpointing to checkpoint*"
$line2Expected="MD5 (checkpoint*"
$line3Expected="Rotating D:\Perforce\Server\journal to journal*"

$line1Actual=Get-Content($file) | Select -Index 0
$line2Actual=Get-Content($file) | Select -Index 1
$line3Actual=Get-Content($file) | Select -Index 2


if($line1Actual -like $line1Expected`
    -and $line2Actual -like $line2Expected`
    -and $line3Actual -like $line3Expected){
}else{
    echo 'send mail'
}
  • 您的 regex 尝试匹配 多行 , 因此 需要一个 单行多行字符串作为输入.

  • 捕获外部程序的输出returns一个数组字符串(行).

  • 使用字符串的 数组 作为 -match 运算符的 LHS 会导致 PowerShell 将正则表达式与每个字符串匹配 个别.

因此,p4d 输出的行与换行符连接起来形成一个多行字符串,以便您的正则表达式可以匹配多行:

$output = (p4d -jc) -join "`n"

此外,如果您希望确保您的正则表达式匹配整个输入,而不仅仅是子字符串 ,重组你的正则表达式如下:

  • 删除行内选项 m(多行)以便 ^$ 真正只匹配多行的开始和结束线串

  • 删除行内选项 s,这样 . 就不会匹配换行符,而用 \n 显式匹配换行符(而不是 ^).

$RE = '(?i)^Checkpointing to checkpoint.*\nMD5 \(checkpoint.*\nRotating D:\Perforce\Server\journal to journal.*$'