1

I wrote a powershell cmdlet that works great on Server 2012 R2 (powershell 4.0), however on Windows 10 or Server 2016 (powershell 5.1) the commands do not appear to wait for each other to finish, but rather execute asynchronously (?). This is certainly not desired behavior and is causing the cmdlet to not function as intended.

The core of the script starts a transcript, runs Get-ADPrincipalGroupMembership followed by Get-ADUser and then Get-Date, and finally closes the transcript.

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)
}

When run on PS 4.0 each statement is executed in order - each one waiting for the previous to finish.

When run on PS 5.1 the Get-ADPrincipalGroupMembership finishes, then the Write-Host "ACCOUNT PROPERTIES" runs then Write-Host "CURRENT TIME" runs, then everything in the finally block runs then the Get-ADUser and Get-Date commands run.

As you can imagine, having Stop-Transcript run in the middle of the script is a show-stopper!

I've Googled for stopping a cmdlet from executing asynchronously, but all the articles are about how to make it execute async - not how to stop it. I'm not sure where to look for help now.

How can I adjust powershell 5.1 to run the statements synchronously? Backwards compatibility with 4.0 is not strictly necessary, but would be a bonus.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
  • 2
    you have mixed _direct screen output_ [`*-Host`] output with _indirect screen output_ [output stream, for most of your code]. the fix is to NOT do that ... or to add something like `| Out-Host` to the items you want to display _immediately_. a delay was added in ps5.? for indirect screen output ... that is what you are seeing. – Lee_Dailey Feb 28 '20 at 18:39
  • 1
    This question is asked all the time. Basically format-table is running implicitly for objects and adds a delay. If you used write-output instead of write-host it wouldn't be a problem. – js2010 Feb 28 '20 at 18:41
  • @Lee_Dailey: you mentioned not mixing direct screen output with indirect screen output... OR... pipe the output to `Out-host`. How would one not mix output modes in this scenario? – Sam Axe Feb 28 '20 at 18:50
  • 1
    @SamAxe - [1] don't use `Write-Host` is the most obvious. [*grin*] instead, use `Write-Output` or just drop the string onto the output stream by placing it all alone on a line. [2] literally add `| Out-Host` to every line that does not already use one of the `*-Host` cmdlets. – Lee_Dailey Feb 28 '20 at 22:11
  • The linked duplicates contain more detailed explanations. – mklement0 Feb 29 '20 at 05:55

1 Answers1

1

Per comments from @Lee_Dailey and @js2010 I was able to modify the script to function as desired by piping the output from format-table and Get-ADUser to 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)
}
Sam Axe
  • 33,313
  • 9
  • 55
  • 89