Powershell Catch仅打印修改后的错误

时间:2016-01-12 18:21:50

标签: powershell powershell-v3.0

我的csv文件包含以下值:

User,TimeStamp
Pinky,11/4/2015 5:00
Brain,
Leo,never
Don,unspecified

我想确保TimeStamp列的此文件具有日期或$ null值。为此,我使用以下代码:

Function HealthCheckTimeStampColumn
{
    Param ($userInputCsvFileWithPath)

    Write-Host "Checking if TimeStamp column has invalid values..."
    Import-Csv $userInputCsvFileWithPath | %{
        if ($_.TimeStamp)
        {
            Try
            {
                ([datetime]$_.TimeStamp).Ticks | Out-Null
            }
            Catch [system.exception]
            {
                $Error.Clear()
                $invalidValue = $_.TimeStamp
                Write-Error "Invalid Value found `"$_.TimeStamp`"; Value expected Date or `"`""
                Exit
            }
        }
    }
    Write-Host "All values were found valid."
    Write-Host "TimeStamp Healthcheck Column Passed"
    Write-Host ""
}

使用此代码,我收到此错误:

Invalid Value found "Cannot convert value "never" to type "System.DateTime". Error: "The string was not recognized as
a valid DateTime. There is an unknown word starting at index 0.".TimeStamp"; Value expected Date or ""
At C:\Scripts\Tests\TestTime.ps1:247 char:42
+     Import-Csv $userInputCsvFileWithPath | %{
+                                             ~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

如果我尝试这行代码而不是:

Write-Error "Invalid Value found `"$invalidValue`"; Value expected Date or `"`""

我收到此错误:

Invalid Value found ""; Value expected Date or ""
At C:\Scripts\Tests\TestTime.ps1:247 char:42
+     Import-Csv $userInputCsvFileWithPath | %{
+                                             ~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

我期待看到的错误是:

Invalid Value found "never"; Value expected Date or ""
At C:\Scripts\Tests\TestTime.ps1:247 char:42
+     Import-Csv $userInputCsvFileWithPath | %{
+                                             ~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

谁能告诉我我做错了什么?

2 个答案:

答案 0 :(得分:2)

将PerSerAl的观察结果转化为答案:

$ _更改从foreach-object循环(但在catch块之外)到catchblock时的含义。在第一种情况下,它是当前对象(行),显然具有值"从不"因为它的时间戳。但是在catch块中,它是由于错误而生成的错误记录。所以要解决:

Function HealthCheckTimeStampColumn
{
    Param ($userInputCsvFileWithPath)

    Write-Host "Checking if TimeStamp column has invalid values..."
    Import-Csv $userInputCsvFileWithPath | %{
        $row = $_
        if ($_.TimeStamp)
        {
            Try
            {
                ([datetime]$_.TimeStamp).Ticks | Out-Null
            }
            Catch [system.exception]
            {
                $Error.Clear()
                $invalidValue = $_.TimeStamp
                Write-Error "Invalid Value found `"$row.TimeStamp`"; Value expected Date or `"`""
                Exit
            }
        }
    }
    Write-Host "All values were found valid."
    Write-Host "TimeStamp Healthcheck Column Passed"
    Write-Host ""
}

顺便说一句,如果你想处理整个文件,你需要从catch块中删除exit

答案 1 :(得分:2)

您也不需要try / catch块。它们适用于意外和不可避免的错误。无论看about_Type_Operators,您都会看到-as-is更优雅地处理这种情况。

  

-is :当输入是指定的.NET Framework类型的实例时,返回TRUE。

     

-as :将输入转换为指定的.NET Framework类型。

-as遇到字符串或某些不能转换为[datetime]的内容时,它将返回null。更重要的是它不会出错。我建议您检查非空值和无效日期时间的所有值。捕获变量中的所有内容。然后检查变量是否有任何值。一次打印!然后退出,如果你想。我还说明user2460798's answer关于退出使用的说法。

Function HealthCheckTimeStampColumn{
    Param ($userInputCsvFileWithPath)
    $badRows = Import-Csv $userInputCsvFileWithPath | 
        Where-Object{-not [string]::IsNullOrEmpty($_.TimeStamp) -and ($_.TimeStamp -as [datetime]) -eq $null}
    if($badRows){
        $badRows | ForEach-Object{
            Write-Host "'$($_.Timestamp)' is not a valid datetime" -ForegroundColor Red
        }
        Write-Error "$($badRows.Count) Invalid Value(s) found"
    } else {
        "All values were found valid.","TimeStamp Healthcheck Column Passed","" | Write-Host
    }
}