【问题标题】:Powershell appears to run statements asynchronously? [duplicate]Powershell 似乎异步运行语句? [复制]
【发布时间】:2020-02-28 18:21:41
【问题描述】:

我编写了一个在 Server 2012 R2 (powershell 4.0) 上运行良好的 powershell cmdlet,但是在 Windows 10 或 Server 2016 (powershell 5.1) 上,这些命令似乎并不等待对方完成,而是异步执行 (? )。这当然不是预期的行为,并且会导致 cmdlet 无法按预期运行。

脚本的核心启动一个脚本,运行 Get-ADPrincipalGroupMembership,然后运行 ​​Get-ADUser,然后是 Get-Date,最后关闭脚本。

try {
    Start-Transcript -Path $transactionFilename
    Write-Host "GROUP MEMBERSHIP FOR $($targetUsername)"
    Get-ADPrincipalGroupMembership -Credential $credential -Identity $Username -Server $domainServer | select name,distinguishedName | format-table
    Write-Host "ACCOUNT PROPERTIES FOR $($targetUsername)"
    Get-ADUser -Credential $credential -Identity $Username -Server $domainServer -Properties *
    Write-Host "CURRENT TIME"
    (Get-Date).DateTime
} catch {
} finally {
    Stop-Transcript 
    write-host "Transcript is available at"
    write-host $transactionFilename
    $Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size ($originalHostWidth, $hostHeight)
}

在 PS 4.0 上运行时,每个语句都按顺序执行 - 每个语句都等待前一个语句完成。

??????

在 PS 5.1 上运行时,Get-ADPrincipalGroupMembership 完成,然后 Write-Host "ACCOUNT PROPERTIES" 运行,然后 Write-Host "CURRENT TIME" 运行,然后 finally 块中的所有内容运行,然后 Get-ADUserGet-Date 命令运行。

??????

如您所想,在脚本中间运行Stop-Transcript 是个大问题!

我在 Google 上搜索过如何阻止 cmdlet 异步执行,但所有文章都是关于如何使其异步执行,而不是如何停止它。我不知道现在该去哪里寻求帮助。

如何调整 powershell 5.1 以同步运行语句?向后兼容 4.0 并不是绝对必要的,但会是一个额外的好处。

【问题讨论】:

  • 您将直接屏幕输出 [*-Host] 输出与间接屏幕输出 [输出流,对于您的大部分代码] 混合使用。解决方法是不要这样做……或者将| Out-Host 之类的内容添加到您想要立即显示 的项目中。 ps5中添加了延迟。?对于间接屏幕输出......这就是你所看到的。
  • 这个问题一直被问到。基本上 format-table 为对象隐式运行并增加了延迟。如果您使用 write-output 而不是 write-host,则不会有问题。
  • @Lee_Dailey:你提到不要将直接屏幕输出与间接屏幕输出混合在一起......或者......将输出传递给Out-host。在这种情况下如何不混合输出模式?
  • @SamAxe - [1] 不要使用Write-Host 是最明显的。 [grin] 相反,使用Write-Output 或将字符串单独放在一行上,将其放到输出流中。 [2] 将| Out-Host 添加到尚未使用*-Host cmdlet 之一的每一行。
  • 链接的副本包含更详细的解释。

标签: powershell


【解决方案1】:

@Lee_Dailey 和 @js2010 的每个 cmets 通过将 format-tableGet-ADUser 的输出传送到 Out-Host,我能够修改脚本以按需要运行:

try {
    Start-Transcript -Path $transactionFilename
    Write-Host "GROUP MEMBERSHIP FOR $($targetUsername)"
    Get-ADPrincipalGroupMembership -Credential $credential -Identity $Username -Server $domainServer | select name,distinguishedName | format-table | out-host
    Write-Host "ACCOUNT PROPERTIES FOR $($targetUsername)"
    Get-ADUser -Credential $credential -Identity $Username -Server $domainServer -Properties * | out-host
    Write-Host "CURRENT TIME"
    (Get-Date).DateTime
} catch {
} finally {
    Stop-Transcript 
    write-host "Transcript is available at"
    write-host $transactionFilename
    $Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size ($originalHostWidth, $hostHeight)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    相关资源
    最近更新 更多