1

Is there a way to check if a command-line parameter was specified for a PowerShell script from a module (.psm1 file)? I do not need the value, just have to know if the parameter was specified. The $PSBoundParameters.ContainsKey method does not seem to work.

TestParam.psm1:

function Test-ScriptParameter {
    [CmdletBinding()]
    param ()
    # This does not work (always returns false):
    return $PSBoundParameters.ContainsKey('MyParam')
}

Export-ModuleMember -Function *

TestParam.ps1:

[CmdletBinding()]
param (
    $MyParam= "Default"
)

$path = Join-Path (Split-Path -Path $PSCommandPath -Parent) 'TestParam.psm1'
Import-Module $path -ErrorAction Stop -Force

Test-ScriptParameter

This must return false:

PS>.\TestParam.ps1

This must return true:

PS>.\TestParam.psq -MyParam ""

This must return true:

PS>.\TestParam.ps1 -MyParam "Runtime"
4
  • 1
    This seems like a poor design. Your module/function shouldn't have a dependency on the caller like this. Is this a possible X-Y Problem? Why do you need to do this? Commented Apr 10, 2019 at 7:26
  • @boxdog: Its not an X-Y problem to be precise but yes I do understand what you meant.. Alek: Can you explain the need of this approach? Commented Apr 10, 2019 at 7:33
  • I am writing a comandlet that reads a config file and populates script's variables from config file settings. I want the code to check if a setting present in the config file was also specified via command line and if so, give the command line a preference. E.g. if the script was invoked with the -MyParam XYZ, and the MyParam setting in the config file was set to ABC, the value of the $MyParam in the script would be XYZ. I know, generally what I want to do would not be kosher, but in my particular case, it is needed. Commented Apr 10, 2019 at 15:12
  • This is what I am trying to do: github.com/alekdavis/ConfigFile Commented Apr 11, 2019 at 5:52

2 Answers 2

1

It cannot be done like you are thinking about it. The PSBoundParameters variable is native to the cmdlet's execution and as such depends on the param block of the cmdlet's definition. So in your case, the Test-ScriptParameter is checking if it was invoked with the parameter MyParam but since it doesn't specify it, then it will be always false.

To achieve what I believe you want, you need to create a function that checks into a hash structure like the PSBoundParameters for a specific key. The key needs to be provided by name. But then a simple $PSBoundParameters.ContainsKey('MyParam') wherever you need it should suffice.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Alex. I understand how $PsBoundParameters works. I was hoping there were a way to get script's $PSBoundParameters from a module cmdlet, but looks like it's not an option.
There is like this @PSBoundParametets but the issue is that the cmdled being called must have specified a valid matching parameter set. It is therefore impossible to create something generic. Within some modules, this trick is used to invoke a private cmdlet with matching parameter sets with a very simple code. Depending on your intentions, you might be able to achieve the same by control and limitation.
1

The problem with your code is that you are checking the $PSBoundParameters value of the Function itself, which has no parameters.

You could make the function work by sending the $PSBoundParameters variable from the script in to the function via a differently named parameter.

For example:

TestParam.psm1:

function Test-ScriptParameter ($BoundParameters) {
    return $BoundParameters.ContainsKey('MyParam')
}

Export-ModuleMember -Function *

TestParam.ps1:

[CmdletBinding()]
param (
    $MyParam = "Default"
)

$path = Join-Path (Split-Path -Path $PSCommandPath -Parent) 'TestParam.psm1'
Import-Module $path -ErrorAction Stop -Force


Test-ScriptParameter $PSBoundParameters

1 Comment

Thank you for the suggestion, but this was a simplified example just to illustrate the problem. The real function has its own parameters, so I do not want to introduce additional parameter, since it's not something the caller would need to know anything about (it's only needed for internal logic, as I explained in the comment above).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.