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.

5
  • 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. Commented Feb 28, 2020 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. Commented Feb 28, 2020 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? Commented Feb 28, 2020 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. Commented Feb 28, 2020 at 22:11
  • The linked duplicates contain more detailed explanations. Commented Feb 29, 2020 at 5:55

1 Answer 1

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)
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.