8

我最近一直在思考的一些事情,我想从 Stack Overflow 的好人那里得到一些意见。

我在不同的计划上运行了大量的 PowerShell 脚本(使用任务计划程序)。这些脚本通常为我收集数据并将其存储在 SQL 表中。我会说我目前正在运行 40-50 个左右的脚本,也许更多。

我最近认真考虑的一件事是最好的方法:

  1. 确保如果发生任何错误,脚本将退出而不进行进一步处理。
  2. 该脚本还应该向我发送一封关于失败的电子邮件,其中包含异常详细信息,向我展示它已经走了多远。
  3. 成绩单/进度已记录,因此我可以查看任何错误并尝试在脚本中更好地处理它们。

这将是一项相当大的工作,所以我想从一开始就采用正确的方法。

我能看到实现这样的目标的唯一方法是执行以下操作:

将 $ErrorActionPreference 设置为“停止”

这应该会导致任何异常触发 Try/Catch 块。

在 Try/Catch/Finally 块中运行整个脚本。

finally 块当然是可选的。像这样的东西:

$ErrorActionPreference = "Stop"

Try
{
    $Content = gc "C:\Temp\NonExistentFile.txt"
    foreach ($Line in $Content)
    {
        Write-Host $Line
    }
}
Catch
{
    Write-Host $_ -ForegroundColor "Red" -BackgroundColor "Black"
    break
}

将“成绩单”数据记录到 HTML 中,并在失败时通过电子邮件发送内容。

我尝试了几种记录方式,对我来说关键之一是我想要的东西是:

  1. 通过提供文本和日志文件位置轻松登录。
  2. 在日志文件每行的开头包括日期/时间。

我开始将文本写入 .txt 文件,但这需要做一些工作。

Start-Transcript 没问题,但没有包括每一行的日期/时间。

我在使用 Start-Transcript 的自定义函数方面取得了一些成功,并将我发送到其中的任何文本写入 Write-Host,日期/时间位于每行的开头。

但最终我认为我需要做的是登录一个 .html 文档,然后在发生错误时通过电子邮件发送此内容。像这样的例子:

Function Send-ErrorEmail
{
    Write-Host "Would Send Email Here" -ForegroundColor "Magenta"
}

Function Write-Html
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline=$True)]$Text,
        $HTMLTag
    )

    [string]$CurrentDateTime = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss - ")

    switch ($HTMLTag)
    {
        "h1" {$ReturnText =  ("<h1>" + $Text + "</h1>")}
        "h2" {$ReturnText =  ("<h2>" + $Text + "</h2>")}
        default {$ReturnText = ("<p>" + $CurrentDateTime + $Text + "</p>")}
    }

    Write-Host -ForegroundColor "Yellow" ($CurrentDateTime + $Text)
    return $ReturnText
}

$ErrorActionPreference = "Stop"

Try
{
    #Stores the HTML File
    $LogfilePath = "C:\Temp\LogFile.html"

    #Begin HTML
    $HTML = @()
    $HTML += "<html><head></head><body>"
    $HTML += "Begin Script" | Write-Html

    #Loop through Computers
    $Computers = "LocalHost", "DoesNotExist", "127.0.0.1"
    foreach ($Computer in $Computers)
    {
        #Get Services
        $HTML += "Computer: $Computer" | Write-Html -HTMLTag "h1"
        $Services = Get-Service -Computer $Computer
        $HTML += $Services | ConvertTo-Html -Fragment
    }

    #Complete HTML
    $HTML += "Script End" | Write-Html
    $HTML += "</body></html>"
    $HTML | Out-File $LogfilePath
}
Catch
{
    #Add Exception to HTML
    $HTML += $_ | Out-String | Write-Html

    #Complete HTML
    $HTML += "</body></html>"
    $HTML | Out-File $LogfilePath

    #Send EMail
    Send-ErrorEmail

    #Exit Script
    exit
}

有什么想法吗?你认为我能做出哪些改进?显然,没有 CSS 格式的 HTML 文档很难看,发送邮件功能也没有做任何事情,但这似乎是做我想做的最简单的方法。

我当然可以在我的所有脚本中点源任何函数,以便于更改通知电子邮件地址或类似地址。

4

1 回答 1

10

对于全局错误处理,我更喜欢使用陷阱语句。

function ErrorHandler($error) 
{
    ... write out error info
    ... send email message with error info
    ... etc
}

trap { ErrorHandler $_; break }

... rest of script code

如果你想避免任何错误,那么是的,设置$ErrorActionPreferenceStop.

于 2013-01-09T23:20:37.283 回答