【问题标题】:How should I do Powershell error handling?我应该如何进行 Powershell 错误处理?
【发布时间】:2021-10-11 08:58:46
【问题描述】:

我有以下代码:

function main {
    #get all content
    [XML]$xml = Get-Content $XMLfile

    $finalObject = $xml.bom.components.component | ForEach-Object {
        $lic = $_.licenses.license.id
        $url = $_.licenses.license.url
        $web = ($_.externalReferences.reference | Where-Object { $_.type -eq 'website' }).url
        [PSCustomObject]@{
            'Name'    = if ($web) { '[{0}]({1})' -f $_.Name, $web } elseif ($url) { '[{0}]({1})' -f $_.Name, $url } elseif (!$url) { $_.Name } else {'Unknown'}
            'Version' = $_.version
            'License' = if ([string]::IsNullOrWhiteSpace($lic)) { 'Unknown' } else { $lic }
        }
    }
    # convert to markdown
    $finalObject | ConvertTo-MarkDownTable  | Out-File -FilePath $saveMdFile

}

现在我想用 powershell 进行错误处理。例如,如果 XML 不存在或无法保存,我希望有错误日志。然后应将日志单独保存在文件中。我将它们定义如下:

function main {
    #get all content
    [XML]$xml = Get-Content $XMLfile

    Write-Log -Message "No file was found: $($xmlfile)" -Level Info -Path $logpath

    $finalObject = $xml.bom.components.component | ForEach-Object {
        $lic = $_.licenses.license.id
        $url = $_.licenses.license.url
        $web = ($_.externalReferences.reference | Where-Object { $_.type -eq 'website' }).url
        [PSCustomObject]@{
            'Name'    = if ($web) { '[{0}]({1})' -f $_.Name, $web } elseif ($url) { '[{0}]({1})' -f $_.Name, $url } elseif (!$url) { $_.Name } else {'Unknown'}
            'Version' = $_.version
            'License' = if ([string]::IsNullOrWhiteSpace($lic)) { 'Unknown' } else { $lic }
        }
    }
    # convert to markdown
    $finalObject | ConvertTo-MarkDownTable  | Out-File -FilePath $saveMdFile

    Write-Log -Message "No path was found: $($xmlfile)" -Level Info -Path $logpath
}

到目前为止,我的日志不起作用,并且在发生错误时也不会保存文件。有谁知道我该如何解决这个问题?

【问题讨论】:

  • 可能是try catch?
  • 你没有解释变量 $XMLfile$saveMdFile 来自哪里,也没有解释你的 Write-Log 函数来自哪里。如果您的意思是在Get-Content $XMLfile 因为找不到文件而失败时捕获错误,请先使用Test-Path
  • $logpath 来自哪里?
  • 我们还没有收到您的来信.. 我的回答解决了您的问题吗?如果是这样,请通过单击左侧的 图标来考虑accepting。这将帮助其他有类似问题的人更轻松地找到它,并有助于激励其他人回答您将来可能遇到的任何问题。

标签: powershell logging error-handling save script


【解决方案1】:

假设您使用here 中的Write-Log 函数和您之前的问题herethere 中的ConvertTo-MarkDownTable,您需要做的就是确保变量$XMLfile$saveMdFile$logpath 在您的 main 函数中是已知且有效的。

一种方法是使用Test-Path,我个人会将这些变量设置为带有默认路径的可选参数,这样您就可以接受这些默认值或使用不同的路径调用函数。

类似这样的:

function main {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false, Position = 0)]
        [string]$xmlFile = 'C:\Users\kraer\Desktop\bom.xml',

        [Parameter(Mandatory = $false, Position = 1)]
        [string]$logpath = 'C:\Users\kraer\Desktop\siteinfo.log',

        [Parameter(Mandatory = $false, Position = 2)]
        [string]$saveMdFile = 'C:\Users\kraer\Desktop\siteinfo.md'
    )

    # try and write to the log
    try {
        Write-Log -Message "Logging started: '$((Get-Date).ToString())'" -Level Info -Path $logpath -ErrorAction Stop
    }
    catch {
        Write-Warning "Error from 'Write-Log': $($_.Exception.Message)"
        return   # exit the function
    }

    # check if the XML file can be found
    if (!(Test-Path -Path $xmlFile -PathType Leaf)) {
        Write-Warning "Xml file '$xmlFile' not found"
        Write-Log -Message "No file was found: '$xmlfile'" -Level Error -Path $logpath
        return   # exit the function
    }

    # get all content. better use this, so you will get the encoding right
    $xml = [System.XML.XMLDocument]::new()
    $xml.Load($xmlFile)
    # assuming this does what you want
    $finalObject = $xml.bom.components.component | ForEach-Object {
        $lic = $_.licenses.license.id
        $url = $_.licenses.license.url
        $web = ($_.externalReferences.reference | Where-Object { $_.type -eq 'website' }).url
        [PSCustomObject]@{
            'Name'    = if ($web) { '[{0}]({1})' -f $_.Name, $web } elseif ($url) { '[{0}]({1})' -f $_.Name, $url } elseif (!$url) { $_.Name } else {'Unknown'}
            'Version' = $_.version
            'License' = if ([string]::IsNullOrWhiteSpace($lic)) { 'Unknown' } else { $lic }
        }
    }
    # convert to markdown
    try {
        $finalObject | ConvertTo-MarkDownTable | Set-Content -Path $saveMdFile -ErrorAction Stop
    }
    catch {
        Write-Warning "Could not write to file '$saveMdFile'"
        Write-Log -Message "Could not write to file '$saveMdFile'" -Level Error -Path $logpath
    }
}

【讨论】:

    猜你喜欢
    • 2011-12-01
    • 2023-03-07
    • 1970-01-01
    • 2011-08-19
    • 2015-07-07
    • 1970-01-01
    • 2013-06-28
    相关资源
    最近更新 更多