Retrieve the input value of the dynamic parameter

This topic contains 4 replies, has 3 voices, and was last updated by  Rohn Edwards 1 day, 10 hours ago.

  • Author
    Posts
  • #100758

    Michael
    Participant

    Hi!

    I have a function that uses a parameter along with some dynamic parameters which are defined depending on the parameter value passed in. However I need to be able to add 1 more additional dynamic parameter only if the value for one of the dynamic parameter are specific values.

    I have tried utilizing the RuntimeDefinedParameter class in hoping I could retrieve the passed in value, but I have only been able to retrieve the value of the dynamic parameter and not the value the user inputted.

    HELP!

    
    Function Get-something  {
        Param(
            [string]
            $OS
        )
        dynamicParam{
            if($OS -ieq "Windows"){
                ...
                setup a dynamic parameter
                setup a dynamic parameter
                setup a dynamic parameter
                ...
                # what I am trying to do is if the param value passed in by the user equals foo
                # then add one more additional dynamic parameter
                # but I do not know how to retrieve the passed-in value for the dynamic parameter
            }
        }
    }
    
  • #100762

    Curtis Smith
    Participant
  • #100833

    Rohn Edwards
    Participant

    I love dynamic parameters, but I generally try everything within my power to not use them for anything that I release to other people. I would personally try extra, extra hard if I needed to create a second level dynamic parameter. That being said, I took your problem here as a fun little exercise to see if I could come up with anything (I really do love dynamic parameters). I came up with this (for real, please don't use this in a production level tool):

    That will create a dumb little function named Test-DynamicParamCreation that lets you pass strings to the -OtherDynamicParameterName parameter (which is itself a dynamic parameter), and it will create any number of other dynamic parameters based off of that. Here's what it looks like in action (it just returns the bound parameter dictionary):

    # Example: Test-DynamicParamCreation -OtherDynamicParamName dynparam1, dynparam2 -dyn
    
    PS C:\> Test-DynamicParamCreation -OtherDynamicParamName dynparam1, dynparam2 -dynparam2 value
    
    Key                   Value
    ---                   -----
    OtherDynamicParamName {dynparam1, dynparam2}
    dynparam2             value
    

    While I think it's neat, I have to repeat that I wouldn't personally use this for anything other than playing around. That's because it's violating the PowerShell engine's contract, since it's peeking into private member data. The way the binder stuff works could change at any given time, then your command wouldn't work as expected (depending on how you're trying to use the data, it might not work at all). I guess I should mention this was only tested in PS 5.1, so I have no idea how far back it will work, and whether or not it will work in PS 6.

    It works by getting access to the command's 'CmdletParameterBinderController' instance, which, when DynamicParam is being invoked, hasn't actually bound any of the parameters. That's why everything's in the 'UnboundArguments' property. Next, each of those (private) arguments are walked through to try to figure out if the user provided named or unnamed parameters. The code that does that hasn't been tested very well, but it should work for switches, too. You could rewrite it to know what parameters to expect, and it would probably do even better (you're on your own when trying to figure out partial parameter names).

    Give it a shot and let me know what you think.

    By the way, have you looked into argument completers? Normally when people want to know the value of a dynamic parameter during runtime, they're looking for argument completion. I don't really know what you're trying to do with your command, so I'm not sure if that would work for you or not (the way the problem is described, that wouldn't work, but I figured I'd mention it).

  • #100959

    Michael
    Participant

    Hi Rohn,

    Wow! This is really cool. How did you learn to do this? I would like to gain a similar understanding of knowing where to look and/or just have an idea of how to do something you created.

    Ill play around with this as well and give you some feedback.

    Thanks again!
    -Michael

    • #100981

      Rohn Edwards
      Participant

      Lots of reading, watching others, and playing around. You used to have to go peeking around with a .NET decompiler to see what was going on under the covers, but now you can go look directly at the PowerShell source code on GitHub (for now, the PowerShell source is similar enough to Windows PowerShell that you can still use it to answer questions for both editions...that might not always be the case, though).

      I originally saw Garrett Serack use the 'CmdletParameterBinderController' class a while back.

      The PowerShell.org and PowerShell Conference EU videos on YouTube have a ton of great information on them, too.

You must be logged in to reply to this topic.