跟踪Powershell脚本中输出的来源 [英] Tracing where output is coming from in a Powershell script

查看:30
本文介绍了跟踪Powershell脚本中输出的来源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在Powershell脚本中跟踪输出(到控制台)的位置?我有一个向我输出信息的脚本,但我不确定输出的是哪一行。例如,是否可以使用Set-PSBreakpoint,并在信息返回到控制台时告诉它中断?

干杯


我收到数百个"false"在自己的线路上返回。 以下是输出来自的代码部分:

    $ar = Function-which_returns_array_of_objects
    $gr = Function-which_returns_array_of_objects

    Write-Host "To begin with..."
    Write-Host "$($ar.count) assets"
    Write-Host "$($gr.count) goods"

    foreach($asset in $ar){
        if(!(Test-NoNA -string $asset.Serial)){continue}

        #See if the particular serial number exists in Goods Received
        $found = @()
        $gr | Where {$_.SerialNumber -eq $asset.serial} | %{
            $found += $_
            # and then mark the entry as one that has to be deleted from GR
            $_.Delete = "YES"
        }
        if($found.count -eq 1){
            #Serial Number has been found once in GR
            #We want to check its PN...
            if(Test-NoNA -string $found.PartNumber -and $found.PartNumber -ne $asset.Model){
                #add it to the asset if its good and not the same as the model number...
                $asset.PartNumber -eq $found.PartNumber
            }
        }elseif(!$found -or $found.count -eq 0){
            #No entries found in GR
            #Shouldn't be the case but doesn't actually do any damage as we'd be deleting the GR entry anyway
        }elseif($found.count -gt 1){
            #More than one match for the SN - probably means a SN like "N/A" has got through the earlier checks
            Write-Warning "More than one match for SN: '$($asset.serial)'"
        }else{
            #Default catcher
            Write-Warning "Unknown Error for SN: '$($asset.serial)'"
        }
    }

另外,这里是Test-NONA:

function Test-NoNA($string){
#check that the given string is not blank, N/A, ?, etc. Returns true if string is good
if($string -and $string -ne "" -and $string -ne "N/A" -and $string -ne "NA" -and $string -ne '?' -and $string -isnot [System.DBNull]){return $true}
}

推荐答案

很遗憾,

  • Set-PSBreakpoint -Command可以很好地使用显式cmdlet调用

    • 例如,调用脚本./myscript.ps1中的Write-OutputWrite-Host会导致使用先前的Set-PSBreakpoint -Command Write-* ./myscript.ps1调用进入调试器),
  • 不使用隐式输出,来自既未捕获也未重定向输出的语句(例如,'foo'1 + 2Get-Date)。

在手头的特定情况下,像$asset.PartNumber -eq $found.PartNumber这样的语句由于混淆了-eq运算符(比较)和=运算符(赋值)而导致了不需要的输出,正如Lee_Daily所诊断的那样。-eq生成输出(比较的布尔值结果),而=不生成输出。

解决办法

  • 在调用脚本之前运行Set-PSDebug -Trace 1,该脚本会在其生成的输出(如果有的话)之前打印每个源代码行。-Trace 2提供了其他详细信息。

  • 使用以下技术,可以隐式或显式地告诉您每条生成成功输出的语句的位置和源代码

    ./myscript.ps1 | % { Write-Verbose -vb "Output from $(($entry=(Get-PsCallStack)[1]).Location): $($entry.Position.Text)"; $_ }
    
    • 脚本的成功输出通过ForEach-Object(%)逐个对象处理,在传递手头的对象($_)之前,生成详细消息,报告位置(脚本路径和行号)以及原始语句的源代码(通过Get-PSCallStack获得)。
  • 如果要检查给定行上的脚本运行时状态,请说15

    • Set-PSBreakpoint -Script ./myscript.ps1 -Line 15

    • 或者,在PSv5+中,如果可以(临时)修改脚本,请在要中断调试器的位置调用Wait-Debugger脚本。

  • Visual Studio Code的调试功能与PowerShell extension一起使用设置断点和/或逐条语句执行脚本。

    • 或者,直接在PowerShell窗口中使用Set-PSDebug -Step执行等效操作。

这篇关于跟踪Powershell脚本中输出的来源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆