PowerShell Forms. How come in my Form Closing event If I can't call a Function or use Write-output, but it works if I use Write-Host

PowerShell Forms. How come in my Form Closing event If I can't call a Function or use Write-output, but it works if I use Write-Host

Problem Description:

I have a small form I’m working on but I have something I’m confused about. I have a closing event
$Form.Add_Closing({}) In there I’m wanting to stop a custom logging module but it doesn’t reflect the output to the console, same if I use write-output. If I use Write-Host though, that reflects to the console. Does the Closing event just have any real output capability?

$Form.Add_Closing({
# my logging function - doesn't work
Write-Log -Stop

# Write-Output - doesn't work
Write-Output 'Test message'

# Write-Host - does work
Write-Host 'Another Test message'
})

Solution – 1

The problem applies to all events, not just Closing:

Inside a PowerShell script block serving as a .NET event delegate:

  • You can call arbitrary commands…

  • … but their success-stream (pipeline) output is discarded.

However, output to any of PowerShell’s other output streams does surface in the caller’s console, as you’ve experienced with Write-Host.

Therefore, if you simply want to print the called commands’ success output to the caller’s display, you can pipe them to Out-Host:

$Form.Add_Closing({
  Write-Log -Stop | Out-Host
})

Note:

  • Out-Host‘s output – unlike Write-Host‘s – can fundamentally neither be captured nor suppressed.

  • Output from Write-Host, which since v5 writes via the information stream, can be suppressed with 6>$null, and in principle be captured via the common -InformationVariable parameter, if your script is an advanced script and it is invoked with, say, ./yourScript -InformationVariable capturedInfoStream.
    However, this does not work with Write-Host calls made inside event-delegate script blocks.


If you want to collect success output emitted from event-delegate script blocks for later use in the script (which also allows you to control if the collected output is sent to the script’s caller or not), create a list in the script scope, to which you can append from the event-delegate script blocks:

# Initialize a list to collect event-delegate output in.
$outputFromEventDelegates = [Collections.Generic.List[object]] @()

# ...

$Form.Add_Closing({
  # Call the function of interest and add its output to the
  # script-scope list.
  $outputFromEventDelegates.AddRange(
    @(Write-Log -Stop)
  )
})

# ... after the .ShowDialog() call

# Now you can access all collected output.
Write-Verbose -Verbose "Output collected from event delegates:"
$outputFromEventDelegates
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject