powershellpowershell-7.0

Can I pass parameters while calling PS7 from PS?


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

Solution

  • 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 -args parameter (the same limitation applies to powershell.exe, the Windows PowerShell CLI).

    However, you can indirectly support passing named arguments by passing the automatic $PSBoundParameters variable 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-ChildItem cmdlet, -LiteralPath and -File, as an example:

    function Test-PS7 {
      param(
          [Parameter(Mandatory)]
          [ValidateNotNullOrEmpty()]
          [string] $LiteralPath,
          [switch] $File
      )
    
      pwsh {
        param($boundParameters)
    
        # Compensate for the problem of [switch] parameters not
        # deserializing as such and splatting of [switch] parameters
        # requiring *[bool]* values.
        foreach ($key in @($boundParameters.Keys)) {
          if ($boundParameters[$key].pstypenames -contains 'Deserialized.System.Management.Automation.SwitchParameter') {
            $boundParameters[$key] = $entry.IsPresent
          }
        }
    
        # Now @boundParameters can be used for splatting
        Get-ChildItem @boundParameters
    
      } -args $PSBoundParameters
    
    }
    

    Note: