提问人:Maximus Gebo 提问时间:11/3/2023 最后编辑:mklement0Maximus Gebo 更新时间:11/6/2023 访问量:75
如何在 PowerShell 中打印脚本块内容
How can I print script block content in PowerShell
问:
嗨,大家好,我想创建一个函数,该函数将检查所选命令的执行情况,如果捕获失败,请重试 3 次,并显示带有重试消息的命令名称。我在要评估的函数括号之间放置了一个测试命令“测试连接”,重试似乎有效,但是我无法打印要打印的命令名称。我尝试使用“$($MyInvocation.MyCommand.ScriptBlock)”,但它打印出我正在检查的已执行行的整个函数。任何人都可以在这里提供建议吗? 提前非常感谢
function Execute-WithRetry([ScriptBlock]$command) {
$Stoploop = $false
$count = 0
do {
try {
& $command
Write-Host "Download completed"
$Stoploop = $true
}
catch {
if ($count -eq 3) {
Write-Host "Could not download after 3 retries."
$Stoploop = $true
}
else {
Write-Host "Could not download the files retrying in 5 seconds..."
Write-Host "Executing: $($MyInvocation.MyCommand.ScriptBlock)"
Start-Sleep -Seconds 5
}
}
$count++
}
While ($Stoploop -eq $false)
pause
}
Execute-WithRetry {
Test-Connection -ComputerName 192.10.129.15 -ErrorAction Stop
}
答:
1赞
mklement0
11/4/2023
#1
前言:
这个答案解决了所提出的问题:如何获取其调用触发错误的脚本块的整个源代码表示。
Mathias 的有用回答演示了如何提取触发错误的脚本块源代码中的特定行。
看起来您正在寻找存储在 中的脚本块的源代码表示形式。$command
调用脚本块只返回 (没有括号 和 ),因此,只需引用 中的脚本块 ,即可扩展的字符串具有相同的效果。.ToString()
{
}
"..."
因此,这应该做你想要的(周围和只是为了给出原始脚本块文字的完整外观):{
}
Write-Host "Executing: {$command}"
注意:
- 字符串表示正是您放置在其中的内容,即脚本块文本,因此可以包含换行符。
{...}
一个简化的例子:
# Sample function that prints the source code of a given script block.
function Foo { param([scriptblock] $Command) "Source code: {$Command}" }
# Sample call
# ->
# "Source code: { Get-Date -Format 'yyyy' }"
Foo -Command { Get-Date -Format 'yyyy' }
直接调用脚本块文本使行为显而易见:.ToString()
# -> " Get-Date -Format 'yyyy' "
{ Get-Date -Format 'yyyy' }.ToString()
3赞
Mathias R. Jessen
11/4/2023
#2
如注释中所述,如果您只想从脚本块中获取“冒犯”行,请从块内的错误记录中获取调用信息(而不是 ),并使用该属性获取失败的语句开始的行:catch
$MyInvocation
Line
function Invoke-Retry {
param([scriptblock]$Command)
$stop = $false
$count = 0
$ErrorActionPreference = 'Stop'
do {
try {
&$Command
Write-Host "Download completed"
$stop = $true
}
catch {
if ($count -ge 3) {
Write-Host "Could not download after 3 retries."
$stop = $true
}
else {
Write-Host "Could not download the files, retrying in 5 seconds"
Write-Host "Error occurred while executing: `n>> $($_.InvocationInfo.Line)" -ForegroundColor Red
Start-Sleep -Seconds 5
}
}
$count++
} while (-not $stop)
pause
}
这应该给你脚本块中的实际行:
PS ~> Invoke-Retry {
Test-Connection -ComputerName doesntexist
}
Could not download the files retrying in 5 seconds
Error occurred while executing:
>> Test-Connection -ComputerName doesntexist
Could not download the files retrying in 5 seconds
Error occurred while executing:
>> Test-Connection -ComputerName doesntexist
Could not download the files retrying in 5 seconds
Error occurred while executing:
>> Test-Connection -ComputerName doesntexist
Could not download after 3 retries.
Press Enter to continue...:
注: 从版本 7.4 开始,调用 info 类还通过 Statement
属性公开任何多行语句的完整范围
评论
0赞
mklement0
11/6/2023
做得很好(我的回答从字面上回答了这个问题)。很高兴知道 ;从 PowerShell 7.4.0-rc.1 开始,它有一个(小)问题:请参阅 GitHub 问题 #20638。.InvocationInfo.Statement
1赞
Mathias R. Jessen
11/6/2023
@mklement0 感谢您的提醒,看来我们需要更多的测试 ^_^
评论
$MyInvocation.Line
Line
$MyInvocation
try {Test-Connection nonexistingfqdn -ErrorAction Stop}catch {Write-Host "Failed at '$($_.InvocationInfo.Line |% Trim)'"}