PowerShell错误记录为空/不正确';调用信息&x27;

PowerShell错误记录为空/不正确';调用信息&x27;,powershell,exception,try-catch,Powershell,Exception,Try Catch,我正在Azure DevOps中运行PowerShell脚本,如果命令失败,我需要记录一条警告,以便观察者可以看到脚本没有按预期运行 作为警告的一部分,我希望输出脚本的路径以及发生异常的行号/偏移量 为此,我在catch或try/catch块中使用$\ucode>变量 $command = "New-AzCosmosDBAccountKey -Name {0} -ResourceGroupName {1} -KeyKind {2}" -f $Name, $ResourceGr

我正在Azure DevOps中运行PowerShell脚本,如果命令失败,我需要记录一条警告,以便观察者可以看到脚本没有按预期运行

作为警告的一部分,我希望输出脚本的路径以及发生异常的行号/偏移量

为此,我在
catch
或try/catch块中使用
$\ucode>变量

$command = "New-AzCosmosDBAccountKey -Name {0} -ResourceGroupName {1} -KeyKind {2}" -f $Name, $ResourceGroupName, $keyKind
Write-Verbose ("##[command] {0}" -f $command)
try {
    Invoke-Expression $command
}
catch
{
    Write-Host ("##[warning] {0}" -f $_.Exception.Message -replace "`r`n", ". ")
    Write-Host ("##vso[task.logissue type=warning;sourcepath={0};linenumber={1};columnnumber={2};]{3}" -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.InvocationInfo.OffsetInLine, $_.Exception.Message -replace "`r`n", ". ")
}
但是,由于某种原因,在
$.InvocationInfo
中,
ScriptName
为空,
ScriptLineNumber
offsetineline
都设置为
1

如果我输出
$\u0.ScriptStackTrace
我会看到有三条消息,大概
$\u0
依赖于堆栈跟踪中的最后一条消息

at <ScriptBlock>, <No file>: line 1
at <ScriptBlock>, C:\pathTo\My-Script.ps1: line 40
at <ScriptBlock>, <No file>: line 1
at,:第1行
在,C:\pathTo\My-Script.ps1:第40行
在,:第1行

我不明白的是堆栈跟踪上的这些消息来自何处,以及为什么它们不包含脚本名称、行号等。

在OP上的评论指出我的问题是由于使用了
调用表达式引起的,并建议我不使用该cmdlet之后,我研究了其他可能的解决方案,并(对我来说!)遇到了一个勇敢的新世界

遗憾的是,没有
格式Splat
函数,所以我不得不编写一个小函数,但由于它将在脚本中使用多次,所以我并不觉得太麻烦。毫无疑问,这是微软未来将增加的内容

幸运的是,使用下面的代码片段意味着现在可以为Azure DevOps正确编写警告-

##vso[task.logissue type=warning;sourcepath=C:\pathTo\My Script.ps1;linenumber=60;columnnumer=17;]出现问题


这是由于您使用了
Invoke Expression
,这是预期的行为。首先为什么要使用
调用表达式
?@MathiasR.Jessen-啊,好吧,那太可惜了。为什么使用-因为我希望记录在Azure DevOps中运行的命令,所以通过将其添加到变量中,我可以确保由
调用表达式
输出和运行的命令的一致性。您所描述的预期行为是否在任何地方都有文档记录,以便我熟悉它?不确定它是否在任何地方都有明确的文档记录,但是
Invoke Expression
通过创建一个新的内存脚本块来工作,然后单独执行,并且此脚本块不会附加原始脚本调用信息(因为不能保证它是其中的一部分)。我已经有一段时间没有在AzDO中使用管道了,但是在管道上启用更详细的日志记录可能会为您提供完整的成绩单日志?不确定,如果您需要任何内容,则必须将其添加到脚本中。它们确实提供了一个
System.Debug
变量,但如果将该变量设置为true,则只会使用
-Debug
和/或运行脚本
-冗长
(不记得是哪个).不管怎样,我将从我的警告中排除文件/位置-这是一个小脚本,因此问题所在应该非常明显!谢谢。我应该警告您,使用
调用表达式
通常是一个非常糟糕的主意-因为任何可以影响输入的人都会在您的AzDO实例中执行任意代码。如果有人管理例如,要影响
$resourceGroupName
的值,他们可以简单地将其设置为
“GroupName;$(执行恶意代码-PwnDavidsReleaseInfra)
using namespace System.Collections.Specialized

function Format-Splat
{
    param([Parameter(Mandatory=$true)][OrderedDictionary]$Hashtable)

    $output = @()
    foreach ($key in $Hashtable.Keys)
    {
        $output += "-{0} {1}" -f $key, $Hashtable[$key]
    }    
    Write-Output ($output -join " ")
}

$parameters = [Ordered]@{ Name = $Name; ResourceGroupName = $ResourceGroupName; keyKind = $keyKind }
Write-Verbose ("##[command]New-AzCosmosDBAccountKey {0}" -f (Format-Splat $parameters))
try {
    $null = New-AzCosmosDBAccountKey @parameters
}
catch
{
    Write-Output ("##vso[task.logissue type=warning;sourcepath={0};linenumber={1};columnnumber={2};]{3}" -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.InvocationInfo.OffsetInLine, $_.Exception.Message -replace "`r`n", ". ")
}