I have a module that was written in PS5, and I'm adding a new function that requires PS7. I want to be able to run the function from PS5, so I'm thinking I can just have the function call pwsh, but I need to be able to pass the function parameters into the pwsh script block. Is this possible?
function Test-PS7 {
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$String
)
pwsh {
Write-Host $String
}
}
When you call
pwsh, the PowerShell (Core) CLI, with a script block ({ ... }) - which is only supported when calling from a PowerShell session - you can only pass positional arguments to that script block, using the-argsparameter (the same limitation applies topowershell.exe, the Windows PowerShell CLI).However, you can indirectly support passing named arguments by passing the automatic
$PSBoundParametersvariable as a single, positional argument, and use splatting inside the script block to pass its value through to the target command.The following demonstrates this via parameters that can be passed through to the
Get-ChildItemcmdlet,-LiteralPathand-File, as an example:Note:
To avoid potentially unnecessary overhead and to make for a more predictable execution environment, consider adding
-NoProfileto thepwshcall.Due to the limited type fidelity that cross-process serialization invariably entails (see this answer),
[switch]parameter turn into emulations which splatting doesn't recognize, necessitating the workaround above:Specifically, these emulations are
[pscustomobject](aka[psobject]) instances containing copies of the original object's properties (but not methods), and are assigned an ETS type name ofDeserialized.System.Management.Automation.SwitchParameter, accessible via the intrinsicpstypenamespropertyTherefore, the workaround code above converts such instances to
[bool]values based on the value of their.IsPresentproperty, so as to make splatting work as intended.@(...), the array-subexpression operator, around accessing the.Keysproperty, so as to ensure that a static copy of the key collection is iterated over, which permits modification of the entries of the dictionary without provoking aCollection was modified; enumeration operation may not execute.error.