Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC Proposal: ScriptBlocks to handle non-terminating message processing #196
Comments
|
What about: & $sb -Id 12345678 -ErrorAction [ActionPreference]::Continue( {Write-MessageLog $_} ) |
That syntax doesn't allow you to determine what you want PowerShell to do with the message based on the logic within the script block (i.e. you can't use |
|
Why? It is the same but only we put the script block in another ast. I even expect that it will be easier to implement and it will work faster. In addition, it clearly describes the intentions while the original sentence simply offers an arbitrary script block (I mean, if there is to remove the |
|
@iSazonov There are a number of challenges with the alternate syntax that you proposed, so I'll go into more detail:
For those reasons, I don't think that alternate proposal would be easy to implement at all. |
|
Moved into PR #219. |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.

@jpsnover suggested in PowerShell Issue #6010 that an
[-OnError <ScriptBlock>]is added to the common parameters in PowerShell that takes precedence over-ErrorActionand$ErrorActionPreference. In response to that issue, PR #182 has been opened by @TylerLeonhardt with an RFC that proposes we change the trap statement to accommodate non-terminating errors. There are several challenges between the original issue and the proposed RFC:With those challenges in mind, I propose instead that we extend what is allowed in
-*Actioncommon parameters, such that aScriptBlockcan be passed into those parameters. Further, I also propose that we allow aScriptBlockto be assigned to any$*Preferencevariable as well. This will allow scripters and script, function and module authors to apply custom message processing to their scripts for any type of non-terminating message that is not silenced or ignored.Terminating messages will remain handled by try/catch statements or trap statements the way they are defined in PowerShell 6.2 and earlier releases.
Motivation
As a scripter or a script, function, or module author,
I can use a
ScriptBlockwith*Preferencevariables and-*Actionparameters,So that I can perform custom processing for all messages generated by my scripts without the complexity of redirection operators in many different locations.
User experience
Here is an example demonstrating how a scripter may handle non-terminating (as well as terminating) messages in PowerShell once this RFC is implemented:
In the case of the first example, the message log will contain the first verbose message and the warning message, and the internal error message log (that may be from a module) will contain the internal errors that were silenced.
In the case of the second example, the message log will contain both verbose messages.
This approach offers more functionality than the RFC in PR #182 without mixing up the important distinction and decisions that need to made when handing terminating and non-terminating errors.
Specification
If a
ScriptBlockis present in a$*Preferencevariable when a message of the appropriate type is raised, theScriptBlockwould be run with$_assigned to the appropriateErrorRecordorInformationalRecordinstance. TheseScriptBlockinstances would be used to process whatever messages they received, and they would identify the action the scripter would like taken once the processing is complete by returning anActionPreferenceenumeration value.To make logging messages easier, if the
ScriptBlockdoes not return anActionPreference, PowerShell would automatically apply the defaultActionPreferencefor that type of message (Continuefor progress, warning and error messages,SilentlyContinuefor information, verbose and debug messages).While those two paragraphs explain the functionality simply enough, this would probably be a decent amount of work to implement.
It is important to note that this design would not be a breaking change because today you cannot assign a
ScriptBlockto a-*Actioncommon parameter, nor can you assign them to a$*Preferencevariables.Alternate proposals and considerations
Make the
ScriptBlockanEventHandlerThe
ScriptBlockimplementation looks like event handlers, so an alternative approach would be to define a specific event handler type and having theScriptBlockdesign conform to that event handler. For example, in PowerShell we could define aStreamedMessageEventArgsclass that has aActionproperty of typeActionPreference, and require that theScriptBlocktake parameters($MessageRecord, $EventArgs), where$MessageRecordis the message that was raised, and$EventArgsis an instance ofStreamedMessageEventArgsused to define theActionPreferenceto take once the message is processed. For this approach,$_would still be assigned to the message record to allow theScriptBlocklogic to remain as simple as possible. Scripters would need to assign a value to$EventArgs.Actionin theScriptBlockin order to change the default behavior (it would be assigned to the default behavior for the corresponding message type by default).The benefits of this alternative are as follows:
ScriptBlockreturnActionPreferenceis a little more explicit (PowerShell will return whatever is output from theScriptBlockby default, so this makes the important part of what is returned clear).$EventArgs.Actionin theScriptBlock, keeping their code simple.ScriptBlockto the parameter or variable they want, and PowerShell will typecast it as an event handler appropriately.The downsides to this approach are as follows:
ScriptBlockif they want to change the defaultActionPreference, which may be a little more complicated than simply working with letting anActionPreferenceenumeration value (which could even be a string) be returned from theScriptBlock.Add
-VerboseAction,-DebugActionand-ProgressActioncommon parametersIt is important to consider the RFC proposal to allow execution preferences to persist beyond module and script scope here because it uses common parameters to pass execution preferences to other modules and/or scripts. In order for that to work properly for all message types, such that
ScriptBlockaction preferences for verbose, debug, and progress messages also propagate beyond module/script scope, we would need to add-VerboseAction,-DebugAction, and-ProgressActionto the common parameter lists. The implementation of these would simply be the same as-WarningActionor-InformationAction, but for their respective streams.The benefits of having these additional common parameters are as follows:
ActionPreferencevalues orScriptBlockmessage handlers can propagate beyond the scope of modules or scripts, allowing them to function more like cmdlets do.The downsides to these common parameters are as follows:
-Verboseand-Debugcommon parameters, so there is some overlap; however, the PowerShell engine would raise an error if both-Verboseand-VerboseActionwere used in an invocation, or-Debugand-DebugActionwere used in an invocation, so there would be no conflict in invocation. Scripters would simply choose one or the other.