IonutN
IonutN

Reputation: 91

Start-Job wrapper using dynamic parameters from another function ends up loading source module of the function twice

A few years ago I put together this function, that can take another Powershell function, and after specifying which of it's parameters is the "loop by" parameter can launch parallel jobs based on the array/collection of that parameter's value, effectively running the function in parallel using start-job. At the time I built it to be used for any kind of function, so I came up with using the dynamic parameter as described below, so that it will take the function's parameter as its own, and then pass those down to the start-job commandlet. (I stripped a lot of function down, with just the bits that matter for my question)

Function Invoke-FunctionAsJob 
{

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string]$FunctionName,

    # name or path of module to load inside worker jobs (.psm1 path)
    [Parameter(Mandatory=$false)]
    [string]
    $CustomModulePath
    )
DynamicParam {
    if (-not $FunctionName) {
    return
    }
    Write-Verbose "Preparing dynamic parameters"
    $Dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
    if ($CustomModulePath) {
        $FullQualifiedModule = $CustomModulePath
        Import-module $FullQualifiedModule
        $childfunctionParams = (Get-Command -All $FunctionName -FullyQualifiedModule $FullQualifiedModule).Parameters
    } else {
        Import-module $FullQualifiedModule
        $childfunctionParams = (Get-Command -All $FunctionName).Parameters
    }

    $commonparams =  [System.Management.Automation.PSCmdlet]::CommonParameters
    foreach ($p in $childfunctionParams.GetEnumerator()) {
        #if the variable is not in the common parameter set we add it to this function's parameter dictionary
        if ($p.Key -notin $commonparams) {
            $paramdata = [ordered]@{
                Name                            = $p.key
                Type                            = $p.Value.ParameterType 
                Alias                           = $p.Value.Aliases 
                ValidateSet                     = $p.Value.Attributes.GetEnumerator().validvalues 
                Mandatory                       = $p.Value.Attributes.GetEnumerator().Mandatory
                ParameterSetName                = $p.Value.ParameterSets 
                Position                        = $p.Value.Attributes.GetEnumerator().Position 
                ValueFromPipelineByPropertyName = $p.Value.Attributes.GetEnumerator().ValueFromPipelineByPropertyName
                DPDictionary                    = $Dictionary
            }
        New-DynamicParam @paramdata
        }
    }
    $Dictionary
    }

begin {

write-Information "begin block"
}
process {
write-Information "begin block"
}
end {}

Now it's all been working fine as long as the module of the function i wanted to run in parallel, had a single version installed. Now I have this module installed in my personal profile (my documents), and an older version of the module in the system folder.

What happens, and I've narrowed it down to the dynamic parameter block and the "Get-Command" commandlet I'm using, is that when invoke-functionasjob is run, the dynamic parameter block somehow feels the need to load the module in the other system location (in my case the older module). I have no dependency in that module that would explain why the older module loads. Also i've tried loading the old module first. For some reason the newer module gets loaded also.

As you see in code above i've tried using a specific module path, and added that full path to the get-command, which when i run it plain and simple, works, but not in this case. I've also tried to load the module in the dynamic param scriptblock (as you can see I have import-module in there) but still it does not stop powershell for looking for the other folder.

This is on both the VS Code host, and the Powershell core window: Name : Visual Studio Code Host Version : 2024.2.2

Name : ConsoleHost Version : 7.4.2

Any ideas on this would be appreciated.

Upvotes: 0

Views: 13

Answers (0)

Related Questions