{"id":8657,"date":"2021-10-26T10:23:59","date_gmt":"2021-10-26T14:23:59","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=8657"},"modified":"2022-10-20T09:25:41","modified_gmt":"2022-10-20T13:25:41","slug":"generate-powershell-dynamic-parameter-code","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/","title":{"rendered":"Generate PowerShell Dynamic Parameter Code"},"content":{"rendered":"\n<p class=\"has-text-align-left\">One of the topics we've discussed in the PowerShell Cmdlet Working Group is a request to make it easier to insert dynamic parameters. I am a bit torn on this. On one hand, I see the value in dynamic parameters. These are parameters that only exist if some condition is met, such as if the current location is in the Windows registry. The downside is that these parameters are difficult to discover and awkward to document. On top of that, the PowerShell code necessary to define a dynamic parameter is complicated and definitely not beginner-level. This is what I think the issue is really all about. So I decided to write my own tooling to make it easier to insert dynamic parameters.<\/p>\n\n\n\n<h2 class=\"has-text-align-left wp-block-heading\">Defining a Need<\/h2>\n\n\n\n<p class=\"has-text-align-left\">The first step is to decide why you need a dynamic parameter.  Many times, I think a parameter set might solve the problem. But let's say you need a parameter based on some condition. Here's an example. This is a demonstration function that displays drive usage using Out-Gridview.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-DriveGridView {\n    [cmdletbinding(DefaultParameterSetName = \"computer\")]\n    [OutputType(\"none\",\"object\")]\n    Param(\n        [parameter(Position = 0, ValueFromPipeline, ParameterSetName = \"computer\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Computername = $env:COMPUTERNAME,\n\n        [parameter(ValueFromPipeline, ParameterSetName = \"session\")]\n        [ValidateNotNullOrEmpty()]\n        [Microsoft.Management.Infrastructure.CimSession]$CimSession,\n\n        [Parameter(HelpMessage = \"Enter a title to use for the GridView\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Title = \"Drive Report\",\n\n        [Parameter(HelpMessage = \"pass results to the pipeline in addition to the grid view\")]\n        [switch]$Passthru\n    )\n\n    Begin {\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)\"\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Collecting drive information...please wait\"\n\n        #initialize a list to hold the results\n        $results = [System.Collections.Generic.list[object]]::new()\n\n        #hashtable of Get-CimInstance parameters for splatting\n        $splat = @{\n            Classname   = \"win32_logicaldisk\"\n            Filter      = \"drivetype=3\"\n            ErrorAction = \"Stop\"\n            Property    = \"SystemName\", \"DeviceID\", \"Size\", \"Freespace\"\n        }\n    } #begin\n\n    Process {\n        If ($pscmdlet.ParameterSetName -eq 'computer') {\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Getting data from computer $($computername.toUpper())\"\n            $splat[\"Computername\"] = $Computername\n            $remote = $Computername.ToUpper()\n        }\n        else {\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Getting data from cimsession $($cimsession.computername.toUpper())\"\n            $splat[\"CimSession\"] = $cimSession\n            $remote = $cimSession.computername.toUpper()\n        }\n\n        Try {\n            Get-CimInstance @splat | Select-Object -Property @{Name = \"Computername\"; Expression = { $_.Systemname } },\n            @{Name = \"Drive\"; Expression = { $_.DeviceID } },\n            @{Name = \"SizeGB\"; Expression = { [int]($_.Size \/ 1GB) } },\n            @{Name = \"FreeGB\"; Expression = { [int]($_.Freespace \/ 1GB) } },\n            @{Name = \"UsedGB\"; Expression = { [math]::round(($_.size - $_.Freespace) \/ 1GB, 2) } },\n            @{Name = \"Free%\"; Expression = { [math]::round(($_.Freespace \/ $_.Size) * 100, 2) } },\n            @{Name = \"FreeGraph\"; Expression = {\n            [int]$per = (($_.Freespace \/ $_.Size) * 100\/2)\n            \"|\" * $per }\n            } | ForEach-Object { $results.Add($_) }\n        } #try\n        Catch {\n            Write-Warning \"Failed to get drive data from $remote. $($_.exception.message)\"\n        }\n    } #process\n\n    End {\n        #send the results to Out-Gridview\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Found $($results.count) total items\"\n        if ($results.count -gt 1) {\n               $Results | Sort-Object -Property Computername | Out-GridView -Title $Title\n               if ($passthru) {\n                $results\n               }\n        }\n        else {\n            Write-Warning \"No drive data found to report.\"\n        }\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)\"\n    } #end\n}<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">This works fine.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png\"><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"215\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png\" alt=\"\" class=\"wp-image-8658\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png 592w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview-300x109.png 300w\" sizes=\"auto, (max-width: 592px) 100vw, 592px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-text-align-left\">But, PowerShell 7 has a new command called Out-ConsoleGridView. Install the <code>Microsoft.PowerShell.ConsoleGuiTools<\/code> module from the PowerShell Gallery to get this command. I would like to include a dynamic parameter to use this command instead of Out-Gridview if it is available. This means I will have to write PowerShell code to define this parameter.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">    [cmdletbinding(DefaultParameterSetName = \"computer\")]\n    [OutputType(\"none\",\"object\")]\n    Param(\n        [parameter(Position = 0, ValueFromPipeline, ParameterSetName = \"computer\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Computername = $env:COMPUTERNAME,\n\n        [parameter(ValueFromPipeline, ParameterSetName = \"session\")]\n        [ValidateNotNullOrEmpty()]\n        [Microsoft.Management.Infrastructure.CimSession]$CimSession,\n\n        [Parameter(HelpMessage = \"Enter a title to use for the GridView\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Title = \"Drive Report\",\n\n        [Parameter(HelpMessage = \"pass results to the pipeline in addition to the grid view\")]\n        [switch]$Passthru\n    )\n    DynamicParam {\n        #offer to use Out-ConsoleGridView if installed in PowerShell 7\n        ...<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">This is the tedious part. <\/p>\n\n\n\n<h2 class=\"has-text-align-left wp-block-heading\">New-PSDynamicParameter<\/h2>\n\n\n\n<p class=\"has-text-align-left\">Instead, I'm going to use this function to auto-generate the PowerShell code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function New-PSDynamicParameter {\n&lt;#\n.Synopsis\nCreate a PowerShell dynamic parameter\n.Description\nThis command will create the code for a dynamic parameter that you can insert into your PowerShell script file.\n.Link\nabout_Functions_Advanced_Parameters\n\n#&gt;\n\n    [cmdletbinding()]\n    [alias(\"ndp\")]\n    [outputtype([System.String[]])]\n    Param(\n        [Parameter(Position = 0, Mandatory, HelpMessage = \"Enter the name of your dynamic parameter.`nThis is a required value.\")]\n        [ValidateNotNullOrEmpty()]\n        [alias(\"Name\")]\n        [string[]]$ParameterName,\n        [Parameter(Mandatory, HelpMessage = \"Enter an expression that evaluates to True or False.`nThis is code that will go inside an IF statement.`nIf using variables, wrap this in single quotes.`nYou can also enter a placeholder like '`$True' and edit it later.`nThis is a required value.\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Condition,\n        [Parameter(HelpMessage = \"Is this dynamic parameter mandatory?\")]\n        [switch]$Mandatory,\n        [Parameter(HelpMessage = \"Enter an optional default value.\")]\n        [object[]]$DefaultValue,\n        [Parameter(HelpMessage = \"Enter an optional parameter alias.`nSpecify multiple aliases separated by commas.\")]\n        [string[]]$Alias,\n        [Parameter(HelpMessage = \"Enter the parameter value type such as String or Int32.`nUse a value like string[] to indicate an array.\")]\n        [type]$ParameterType = \"string\",\n        [Parameter(HelpMessage = \"Enter an optional help message.\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$HelpMessage,\n        [Parameter(HelpMessage = \"Does this dynamic parameter take pipeline input by property name?\")]\n        [switch]$ValueFromPipelineByPropertyName,\n        [Parameter(HelpMessage = \"Enter an optional parameter set name.\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$ParameterSetName,\n        [Parameter(HelpMessage = \"Enter an optional comment for your dynamic parameter.`nIt will be inserted into your code as a comment.\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Comment,\n        [Parameter(HelpMessage = \"Validate that the parameter is not NULL or empty.\")]\n        [switch]$ValidateNotNullOrEmpty,\n        [Parameter(HelpMessage = \"Enter a minimum and maximum string length for this parameter value`nas an array of comma-separated set values.\")]\n        [ValidateNotNullOrEmpty()]\n        [int[]]$ValidateLength,\n        [Parameter(HelpMessage = \"Enter a set of parameter validations values\")]\n        [ValidateNotNullOrEmpty()]\n        [object[]]$ValidateSet,\n        [Parameter(HelpMessage = \"Enter a set of parameter range validations values as a`ncomma-separated list from minimum to maximum\")]\n        [ValidateNotNullOrEmpty()]\n        [int[]]$ValidateRange,\n        [Parameter(HelpMessage = \"Enter a set of parameter count validations values as a`ncomma-separated list from minimum to maximum\")]\n        [ValidateNotNullOrEmpty()]\n        [int[]]$ValidateCount,\n        [Parameter(HelpMessage = \"Enter a parameter validation regular expression pattern\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$ValidatePattern,\n        [Parameter(HelpMessage = \"Enter a parameter validation scriptblock.`nIf using the form, enter the scriptblock text.\")]\n        [ValidateNotNullOrEmpty()]\n        [scriptblock]$ValidateScript\n    )\n\n    Begin {\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)\"\n        $out = @\"\n    DynamicParam {\n    $(If ($comment) { \"$([char]35) $comment\"})\n        If ($Condition) {\n\n        `$paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary\n\n\"@\n\n    } #begin\n\n    Process {\n        if (-Not $($PSBoundParameters.ContainsKey(\"ParameterSetName\"))) {\n            $PSBoundParameters.Add(\"ParameterSetName\", \"__AllParameterSets\")\n        }\n\n        #get validation tests\n        $Validations = $PSBoundParameters.GetEnumerator().Where({ $_.key -match \"^Validate\" })\n\n        #this is structured for future development where you might need to create\n        #multiple dynamic parameters. This feature is incomplete at this time\n        Foreach ($Name in $ParameterName) {\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Defining dynamic parameter $Name [$($parametertype.name)]\"\n            $out += \"`n        # Defining parameter attributes`n\"\n            $out += \"        `$attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]`n\"\n            $out += \"        `$attributes = New-Object System.Management.Automation.ParameterAttribute`n\"\n            #add attributes\n            $attributeProperties = 'ParameterSetName', 'Mandatory', 'ValueFromPipeline', 'ValueFromPipelineByPropertyName', 'ValueFromRemainingArguments', 'HelpMessage'\n            foreach ($item in $attributeProperties) {\n                if ($PSBoundParameters.ContainsKey($item)) {\n                    Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Defining $item\"\n                    if ( $PSBoundParameters[$item] -is [string]) {\n                        $value = \"'$($PSBoundParameters[$item])'\"\n                    }\n                    else {\n                        $value = \"`$$($PSBoundParameters[$item])\"\n                    }\n\n                    $out += \"        `$attributes.$item = $value`n\"\n                }\n            }\n\n            #add parameter validations\n            if ($validations) {\n                Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Processing validations\"\n                foreach ($validation in $Validations) {\n                    Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] ... $($validation.key)\"\n                    $out += \"`n        # Adding $($validation.key) parameter validation`n\"\n                    Switch ($Validation.key) {\n                        \"ValidateNotNullOrEmpty\" {\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidateLength\" {\n                            $out += \"        `$value = @($($Validation.Value[0]),$($Validation.Value[1]))`n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateLengthAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidateSet\" {\n                            $join = \"'$($Validation.Value -join \"','\")'\"\n                            $out += \"        `$value = @($join) `n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateSetAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidateRange\" {\n                            $out += \"        `$value = @($($Validation.Value[0]),$($Validation.Value[1]))`n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateRangeAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidatePattern\" {\n                            $out += \"        `$value = '$($Validation.value)'`n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidatePatternAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidateScript\" {\n                            $out += \"        `$value = {$($Validation.value)}`n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateScriptAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                        \"ValidateCount\" {\n                            $out += \"        `$value = @($($Validation.Value[0]),$($Validation.Value[1]))`n\"\n                            $out += \"        `$v = New-Object System.Management.Automation.ValidateCountAttribute(`$value)`n\"\n                            $out += \"        `$AttributeCollection.Add(`$v)`n\"\n                        }\n                    } #close switch\n                } #foreach validation\n            } #validations\n\n            $out += \"        `$attributeCollection.Add(`$attributes)`n\"\n\n            if ($Alias) {\n                Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Adding parameter alias $($alias -join ',')\"\n                Foreach ($item in $alias) {\n                    $out += \"`n        # Adding a parameter alias`n\"\n                    $out += \"        `$dynalias = New-Object System.Management.Automation.AliasAttribute -ArgumentList '$Item'`n\"\n                    $out += \"        `$attributeCollection.Add(`$dynalias)`n\"\n                }\n            }\n\n            $out += \"`n        # Defining the runtime parameter`n\"\n\n            #handle the Switch parameter since it uses a slightly different name\n            if ($ParameterType.Name -match \"Switch\") {\n                $paramType = \"Switch\"\n            }\n            else {\n                $paramType = $ParameterType.Name\n            }\n\n            $out += \"        `$dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('$Name', [$paramType], `$attributeCollection)`n\"\n            if ($DefaultValue) {\n                Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Using default value $($DefaultValue)\"\n                if ( $DefaultValue[0] -is [string]) {\n                    $value = \"'$($DefaultValue)'\"\n                }\n                else {\n                    $value = \"`$$($DefaultValue)\"\n                }\n                $out += \"        `$dynParam1.Value = $value`n\"\n            }\n            $Out += @\"\n        `$paramDictionary.Add('$Name', `$dynParam1)\n\n\n\"@\n        } #foreach dynamic parameter name\n\n    }\n    End {\n        $out += @\"\n        return `$paramDictionary\n    } # end if\n} #end DynamicParam\n\"@\n        $out\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)\"\n    } #end\n}<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">This function parameterizes the information you might want to use in your dynamic parameter. I'm not going to focus on how the function work but rather on using it. The parameter name and condition are required. The condition should be code that runs inside an IF statement. If you know you'll need something more complex, use a parameter value like $True. You can edit the generated code later.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$splat = @{\n ParameterName = \"ConsoleGridView\"\n Condition = \"Get-Command -Name Out-ConsoleGridview -ErrorAction SilentlyContinue\"\n Alias = \"ocgv\"\n HelpMessage = \"Use the Out-ConsoleGridView command in PowerShell 7\"\n Comment = \"Offer to use Out-ConsoleGridView if installed in PowerShell 7\"\n ParameterType = \"switch\"\n}\nNew-PSDynamicParameter @splat | Set-Clipboard<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">The function writes a here-string of PowerShell code to the pipeline. I'm copying it to the clipboard. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">    DynamicParam {\n    # Offer to use Out-ConsoleGridView if installed in PowerShell 7\n        If (Get-Command -Name Out-ConsoleGridview -ErrorAction SilentlyContinue) {\n\n        $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary\n\n        # Defining parameter attributes\n        $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]\n        $attributes = New-Object System.Management.Automation.ParameterAttribute\n        $attributes.ParameterSetName = '__AllParameterSets'\n        $attributes.HelpMessage = 'Use the Out-ConsoleGridView command in PowerShell 7'\n        $attributeCollection.Add($attributes)\n\n        # Adding a parameter alias\n        $dynalias = New-Object System.Management.Automation.AliasAttribute -ArgumentList 'ocgv'\n        $attributeCollection.Add($dynalias)\n\n        # Defining the runtime parameter\n        $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('ConsoleGridView', [Switch], $attributeCollection)\n        $paramDictionary.Add('ConsoleGridView', $dynParam1)\n\n        return $paramDictionary\n    } # end if\n} #end DynamicParam<\/code><\/pre>\n\n\n\n<p>I can insert this after the Param() section.  I didn't have to write any of this code. When I dot source my function in PowerShell 7, I have an additional parameter.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp.png\"><img loading=\"lazy\" decoding=\"async\" width=\"977\" height=\"298\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp.png\" alt=\"\" class=\"wp-image-8660\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp.png 977w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp-300x92.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp-768x234.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/dynamic-paramhelp-850x259.png 850w\" sizes=\"auto, (max-width: 977px) 100vw, 977px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-text-align-left\">Because the dynamic parameter doesn't depend on any other parameters, and I'm letting PowerShell generate the help, this isn't too bad. But in a module with external help, this becomes a bit more difficult to document. But it works, even using the dynamic parameter alias.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Get-DriveGridView -Computername thinkp1 -ocgv<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"636\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview-1024x636.png\" alt=\"\" class=\"wp-image-8661\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview-1024x636.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview-300x186.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview-768x477.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview-850x528.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/driveconsolegridview.png 1089w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"has-text-align-left wp-block-heading\">Getting GUI<\/h2>\n\n\n\n<p class=\"has-text-align-left\">But since I'm likely to use this function to generate a dynamic parameter in a scripting editor, a GUI might be nicer. This function generates a WPF front end to the first function.<\/p>\n\n\n\n<pre title=\"New-PSDynamicParameterForm\" class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function New-PSDynamicParameterForm {\n    [cmdletbinding()]\n    [alias(\"dpf\")]\n    [Outputtype(\"None\")]\n    Param()\n\n    Add-Type -AssemblyName PresentationFramework\n    Add-Type -AssemblyName PresentationCore\n\n    $list = [System.Collections.Generic.list[object]]::new()\n    [xml]$xaml = @\"\n    &lt;Window xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\n    xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\n    xmlns:d=\"http:\/\/schemas.microsoft.com\/expression\/blend\/2008\"\n    xmlns:local=\"clr-namespace:New_DynamicParamForm\"\n    Title=\"New Dynamic Parameter\" Height=\"475\" Width=\"650\" WindowStartupLocation = \"CenterScreen\" &gt;\n    &lt;Grid HorizontalAlignment=\"Center\" Width=\"650\" Margin=\"0,0,0,0\"&gt;\n        &lt;Grid.ColumnDefinitions&gt;\n            &lt;ColumnDefinition Width=\"0*\"\/&gt;\n            &lt;ColumnDefinition\/&gt;\n        &lt;\/Grid.ColumnDefinitions&gt;\n        &lt;Label x:Name=\"label\" Content=\"Parameter Name*\" HorizontalAlignment=\"Left\" Height=\"25\" Margin=\"9,22,0,0\" VerticalAlignment=\"Top\" Width=\"116\" Grid.Column=\"1\"\/&gt;\n        &lt;TextBox x:Name=\"ParameterName\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"120,25,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"153\"\/&gt;\n        &lt;CheckBox x:Name=\"Mandatory\" Content=\"Mandatory\" HorizontalAlignment=\"Center\" Margin=\"0,27,0,0\" VerticalAlignment=\"Top\" Grid.Column=\"1\"\/&gt;\n        &lt;Label x:Name=\"label_Copy\" Content=\"Parameter Set Name\" HorizontalAlignment=\"Left\" Height=\"25\" Margin=\"307,44,0,0\" VerticalAlignment=\"Top\" Width=\"121\" Grid.Column=\"1\"\/&gt;\n        &lt;TextBox x:Name=\"ParameterSetName\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"443,46,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"153\"\/&gt;\n        &lt;Label x:Name=\"label1\" Content=\"Comment\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"18,392,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"Comment\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"87,396,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"345\"\/&gt;\n        &lt;Label x:Name=\"label2\" Content=\"Parameter Alias\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"11,51,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"Alias\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"121,54,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"153\"\/&gt;\n        &lt;Label x:Name=\"label2_Copy\" Content=\"Default Value\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"11,78,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"DefaultValue\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"121,81,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"153\"\/&gt;\n        &lt;Button x:Name=\"OK\" Content=\"_Create\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"448,394,0,0\" VerticalAlignment=\"Top\" Width=\"75\"\/&gt;\n        &lt;Button x:Name=\"Quit\" Content=\"Close\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"536,394,0,0\" VerticalAlignment=\"Top\" Width=\"75\"\/&gt;\n        &lt;Label x:Name=\"label2_Copy1\" Content=\"Help Message\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"281,78,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"HelpMessage\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"376,81,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"222\" Grid.Column=\"1\"\/&gt;\n        &lt;Label x:Name=\"label2_Copy2\" Content=\"Parameter Type\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"11,105,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ParameterType\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"20\" Margin=\"121,108,0,0\" Text=\"string\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"153\"\/&gt;\n        &lt;Label x:Name=\"label3\" Content=\"Condition*\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"13,132,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"Condition\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"123,137,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"282\"\/&gt;\n        &lt;Border BorderThickness=\"1\" BorderBrush=\"Black\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"1\" Margin=\"10,162,0,0\" VerticalAlignment=\"Top\" Width=\"634\"\/&gt;\n        &lt;Label x:Name=\"label4\" Content=\"Parameter Validations\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"7,166,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;CheckBox x:Name=\"ValidateNotNullOrEmpty\" Content=\"ValidateNotNullorEmpty\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"39,196,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;Label x:Name=\"label5\" Content=\"ValidateCount\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"35,212,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ValidateCount\" HorizontalAlignment=\"Left\" Margin=\"124,216,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"60\" Grid.Column=\"1\"\/&gt;\n        &lt;Label x:Name=\"label5_Copy\" Content=\"ValidateLength\" HorizontalAlignment=\"Left\" Margin=\"210,212,0,0\" VerticalAlignment=\"Top\" Grid.Column=\"1\"\/&gt;\n        &lt;TextBox x:Name=\"ValidateLength\" HorizontalAlignment=\"Left\" Margin=\"303,216,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"60\" Grid.Column=\"1\"\/&gt;\n        &lt;CheckBox x:Name=\"ValueFromPipelineByPropertyName\" Content=\"ValueFromPipelineByPropertyName\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"201,195,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;Label x:Name=\"label6\" Content=\"ValidateRange\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"394,212,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ValidateRange\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"481,216,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"120\"\/&gt;\n        &lt;Label x:Name=\"label5_Copy1\" Content=\"ValidatePattern\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"35,242,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ValidatePattern\" HorizontalAlignment=\"Left\" Margin=\"125,245,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"150\" Grid.Column=\"1\"\/&gt;\n        &lt;Label x:Name=\"label5_Copy2\" Content=\"ValidateScript\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"35,270,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ValidateScript\" AcceptsReturn = \"True\" VerticalScrollBarVisibility=\"Auto\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"121,274,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"250\" Height=\"70\"\/&gt;\n        &lt;Label x:Name=\"label7\" Content=\"ValidateSet\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Margin=\"34,351,0,0\" VerticalAlignment=\"Top\"\/&gt;\n        &lt;TextBox x:Name=\"ValidateSet\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" Height=\"16\" Margin=\"117,356,0,0\" Text=\"\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" Width=\"328\"\/&gt;\n     &lt;\/Grid&gt;\n  &lt;\/Window&gt;\n\"@\n\n    $reader = New-Object System.Xml.XmlNodeReader $xaml\n    $Window = [Windows.Markup.XamlReader]::Load($reader)\n\n    #get all parameters\n    $all = (Get-Command New-PSDynamicParameter).parameters\n    #filter out common parameters\n    $common = [System.Management.Automation.Cmdlet]::CommonParameters\n    $paramList = $all.GetEnumerator().where({$common -notcontains $_.key}).key\n\n    #get controls\n    foreach ($item in $paramList) {\n    Write-Verbose \"Processing control $item\"\n        Try {\n            $tmp = New-Variable -Name $item -Value ($Window.FindName($item)) -ErrorAction Stop -PassThru\n            #add a help tool tip\n            $tip = $all[$item].attributes.where({$_.typeid.name -eq 'parameterattribute'}).helpMessage\n            write-Verbose \"Found help $tip\"\n            $tmp.Value.ToolTip = $tip\n            $list.Add((Get-Variable -Name $item))\n        }\n        Catch {\n            Write-Verbose \"Skipping $item\"\n        }\n    }\n\n    #hook up code to buttons\n    $OK = $Window.FindName(\"OK\")\n    $OK.ToolTip = \"Create the dynamic parameter code and copy to the clipboard.`nThis will NOT close the form.\"\n\n    $OK.Add_Click({\n        Write-Verbose \"Defining dynamic parameter $($ParameterName.text)\"\n\n        $splat = @{}\n        $list | where-object {$_.value.text} | foreach-object {\n        $splat.Add($_.Name,$_.value.Text)\n         }\n         #add switches\n        $list | where-object {$_.value.IsChecked} | foreach-object {\n         $splat.Add($_.Name,$True)\n        }\n\n        #turn values into arrays as needed\n        $Names = \"ValidateSet\",\"ValidateCount\",\"ValidateRange\",\"ValidateLength\"\n        foreach ($n in $names) {\n            if ($splat[$n]) {\n                $splat[$n] = $splat[$n].split(\",\")\n            }\n        }\n\n        #convert ValidateScript text into a scriptblock\n        if ($splat[\"ValidateScript\"]) {\n            $splat[\"ValidateScript\"] = [scriptblock]::Create($splat[\"ValidateScript\"])\n        }\n        New-PSDynamicParameter @splat | Set-Clipboard\n        Write-Host \"Your dynamic parameter code has been copied to the clipboard. Paste it into your script file.\" -ForegroundColor Green\n    })\n    $Quit = $Window.FindName(\"Quit\")\n    $Quit.Add_Click({$window.close()})\n\n    [void]$window.Activate()\n    [void]$window.ShowDialog()\n}<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">In the .ps1 file that defines these functions, I'm also using this code to generate shortcuts if you dot source the file in VS Code or the PowerShell ISE.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">#add scripting editor shortcuts or you can run the functions in the editor's console window.\nif ($host.name -eq 'Visual Studio Code Host') {\n    Register-EditorCommand -Name \"DynamicParameterForm\" -DisplayName \"Define a dynamic parameter\" -ScriptBlock (Get-Item -path Function:\\New-PSDynamicParameterForm).scriptblock -SuppressOutput\n}\nelseif ($host.name -match \"PowerShell ISE\") {\n    if ($psise.CurrentPowerShellTab.AddOnsMenu.Submenus.DisplayName -notcontains \"New Dynamic Parameter\") {\n        $action = {New-PSDynamicParameterForm}\n        [void]($Psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add(\"New Dynamic Parameter\", $action, \"Ctrl+Alt+D\"))\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-left\">Running the command will generate this WPF form.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/new-dynamicparameterform.png\"><img loading=\"lazy\" decoding=\"async\" width=\"636\" height=\"468\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/new-dynamicparameterform.png\" alt=\"\" class=\"wp-image-8662\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/new-dynamicparameterform.png 636w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/new-dynamicparameterform-300x221.png 300w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/a><\/figure>\n\n\n\n<p class=\"has-text-align-left\">I've dynamically generated tooltip information for each item based on the help message of the New-PSDynamicParameterForm. Mandatory values are indicated with an asterisk. I can see I might need to tweak the Condition text box.<\/p>\n\n\n\n<p class=\"has-text-align-left\">Regardless, when you click Create, the function generates the dynamic parameter code and copies it to the clipboard. You can then paste it into your function. The form will remain open until you click Close. This allows you to fine-tune your parameter without having to re-enter everything.<\/p>\n\n\n\n<p class=\"has-text-align-left\">By the way, if you were interested, here's the updated Get-DriveGridView function.<\/p>\n\n\n\n<pre title=\"Get-DriveGridView\" class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-DriveGridView {\n\n    [cmdletbinding(DefaultParameterSetName = \"computer\")]\n    [OutputType(\"none\",\"object\")]\n    Param(\n        [parameter(Position = 0, ValueFromPipeline, ParameterSetName = \"computer\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Computername = $env:COMPUTERNAME,\n\n        [parameter(ValueFromPipeline, ParameterSetName = \"session\")]\n        [ValidateNotNullOrEmpty()]\n        [Microsoft.Management.Infrastructure.CimSession]$CimSession,\n\n        [Parameter(HelpMessage = \"Enter a title to use for the GridView\")]\n        [ValidateNotNullOrEmpty()]\n        [string]$Title = \"Drive Report\",\n\n        [Parameter(HelpMessage = \"pass results to the pipeline in addition to the grid view\")]\n        [switch]$Passthru\n    )\n\n    DynamicParam {\n    # Offer to use Out-ConsoleGridView if installed in PowerShell 7\n        If (Get-Command -Name Out-ConsoleGridview -ErrorAction SilentlyContinue) {\n\n        $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary\n\n        # Defining parameter attributes\n        $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]\n        $attributes = New-Object System.Management.Automation.ParameterAttribute\n        $attributes.ParameterSetName = '__AllParameterSets'\n        $attributes.HelpMessage = 'Use the Out-ConsoleGridView command in PowerShell 7'\n        $attributeCollection.Add($attributes)\n\n        # Adding a parameter alias\n        $dynalias = New-Object System.Management.Automation.AliasAttribute -ArgumentList 'ocgv'\n        $attributeCollection.Add($dynalias)\n\n        # Defining the runtime parameter\n        $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('ConsoleGridView', [Switch], $attributeCollection)\n        $paramDictionary.Add('ConsoleGridView', $dynParam1)\n\n        return $paramDictionary\n    } # end if\n} #end DynamicParam\n\n    Begin {\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)\"\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Collecting drive information...please wait\"\n\n        #initialize a list to hold the results\n        $results = [System.Collections.Generic.list[object]]::new()\n\n        #hashtable of Get-CimInstance parameters for splatting\n        $splat = @{\n            Classname   = \"win32_logicaldisk\"\n            Filter      = \"drivetype=3\"\n            ErrorAction = \"Stop\"\n            Property    = \"SystemName\", \"DeviceID\", \"Size\", \"Freespace\"\n        }\n\n    } #begin\n\n    Process {\n        If ($pscmdlet.ParameterSetName -eq 'computer') {\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Getting data from computer $($computername.toUpper())\"\n            $splat[\"Computername\"] = $Computername\n            $remote = $Computername.ToUpper()\n        }\n        else {\n            Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Getting data from cimsession $($cimsession.computername.toUpper())\"\n            $splat[\"CimSession\"] = $cimSession\n            $remote = $cimSession.computername.toUpper()\n        }\n\n        Try {\n            Get-CimInstance @splat | Select-Object -Property @{Name = \"Computername\"; Expression = { $_.Systemname } },\n            @{Name = \"Drive\"; Expression = { $_.DeviceID } },\n            @{Name = \"SizeGB\"; Expression = { [int]($_.Size \/ 1GB) } },\n            @{Name = \"FreeGB\"; Expression = { [int]($_.Freespace \/ 1GB) } },\n            @{Name = \"UsedGB\"; Expression = { [math]::round(($_.size - $_.Freespace) \/ 1GB, 2) } },\n            @{Name = \"Free%\"; Expression = { [math]::round(($_.Freespace \/ $_.Size) * 100, 2) } },\n            @{Name = \"FreeGraph\"; Expression = {\n            [int]$per = (($_.Freespace \/ $_.Size) * 100\/2)\n            \"|\" * $per }\n            } | ForEach-Object { $results.Add($_) }\n        } #try\n        Catch {\n            Write-Warning \"Failed to get drive data from $remote. $($_.exception.message)\"\n        }\n\n    } #process\n\n    End {\n        #send the results to Out-Gridview\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Found $($results.count) total items\"\n        if ($results.count -gt 1) {\n            if ($PSBoundParameters.ContainsKey(\"ConsoleGridView\")) {\n                $Results | Sort-Object -Property Computername | Out-ConsoleGridView -Title $Title\n            }\n            else {\n                $Results | Sort-Object -Property Computername | Out-GridView -Title $Title\n            }\n            if ($Passthru) {\n                $Results\n            }\n        }\n        else {\n            Write-Warning \"No drive data found to report.\"\n        }\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)\"\n\n    } #end\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Try It<\/h2>\n\n\n\n<p class=\"has-text-align-left\">Both functions and the scripting editor detection code are in a single .ps1 file which I dot source. I don't often need dynamic parameters, but when I do, I think this will save me a lot of time. I hope you'll give this a try and let me know what you think or how it works for you. I'm considering adding it to the PSScriptTools module, which seems like the ideal home, but I'd love some feedback before I take that step.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the topics we&#8217;ve discussed in the PowerShell Cmdlet Working Group is a request to make it easier to insert dynamic parameters. I am a bit torn on this. On one hand, I see the value in dynamic parameters. These are parameters that only exist if some condition is met, such as if the&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"New on the blog: Auto-Generate #PowerShell Dynamic Parameter Code","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[659,224,534,379],"class_list":["post-8657","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-dynamic-parameter","tag-function","tag-powershell","tag-wpf"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"Here&#039;s how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Here&#039;s how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2021-10-26T14:23:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-10-20T13:25:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Generate PowerShell Dynamic Parameter Code\",\"datePublished\":\"2021-10-26T14:23:59+00:00\",\"dateModified\":\"2022-10-20T13:25:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/\"},\"wordCount\":679,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/drive-gridview.png\",\"keywords\":[\"Dynamic Parameter\",\"Function\",\"PowerShell\",\"WPF\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/\",\"name\":\"Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/drive-gridview.png\",\"datePublished\":\"2021-10-26T14:23:59+00:00\",\"dateModified\":\"2022-10-20T13:25:41+00:00\",\"description\":\"Here's how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/drive-gridview.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/drive-gridview.png\",\"width\":592,\"height\":215},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8657\\\/generate-powershell-dynamic-parameter-code\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Generate PowerShell Dynamic Parameter Code\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator","description":"Here's how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/","og_locale":"en_US","og_type":"article","og_title":"Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator","og_description":"Here's how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/","og_site_name":"The Lonely Administrator","article_published_time":"2021-10-26T14:23:59+00:00","article_modified_time":"2022-10-20T13:25:41+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Generate PowerShell Dynamic Parameter Code","datePublished":"2021-10-26T14:23:59+00:00","dateModified":"2022-10-20T13:25:41+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/"},"wordCount":679,"commentCount":2,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png","keywords":["Dynamic Parameter","Function","PowerShell","WPF"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/","name":"Generate PowerShell Dynamic Parameter Code &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png","datePublished":"2021-10-26T14:23:59+00:00","dateModified":"2022-10-20T13:25:41+00:00","description":"Here's how I quickly and easily define dynamic parameters for my PowerShell functions. I even have a WPF front-end to make it super simple.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/10\/drive-gridview.png","width":592,"height":215},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8657\/generate-powershell-dynamic-parameter-code\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Generate PowerShell Dynamic Parameter Code"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":7604,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7604\/discovering-provider-specific-commands\/","url_meta":{"origin":8657,"position":0},"title":"Discovering Provider Specific Commands","author":"Jeffery Hicks","date":"July 22, 2020","format":false,"excerpt":"I've been diving into PowerShell help lately while preparing my next Pluralsight course. One of the sad things I have discovered is the loss of provider-aware help. As you may know, some commands have parameters that only exist when using a specific PSDrive.\u00a0 For example, the -File parameter for Get-ChildItem\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5806,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/5806\/a-powershell-countdown-timer\/","url_meta":{"origin":8657,"position":1},"title":"A PowerShell Countdown Timer","author":"Jeffery Hicks","date":"December 6, 2017","format":false,"excerpt":"The other day, during one of the monthly #PSTweetChat sessions, I exchanged some tweets with Joshua King. We got on the topic of countdown timers and he shared some code he uses for his YouTube channel. The command creates a progress bar and counts down, displaying some humorous messages along\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":7458,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7458\/a-powershell-remote-function-framework\/","url_meta":{"origin":8657,"position":2},"title":"A PowerShell Remote Function Framework","author":"Jeffery Hicks","date":"May 8, 2020","format":false,"excerpt":"The other day I shared a PowerShell function to query the registry on remote computers to find installed versions of PowerShell. The function leveraged PowerShell remoting with the flexibility of using a computer name with an optional credential or existing PSSessions. The more I thought about it, the more I\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/stop-remoteprocess.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7786,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/7786\/open-up-wide-with-powershell\/","url_meta":{"origin":8657,"position":3},"title":"Open Up Wide with PowerShell","author":"Jeffery Hicks","date":"October 19, 2020","format":false,"excerpt":"A few weeks ago, an Iron Scripter PowerShell scripting challenge was posted. The challenge involved wide directory listings. Which always makes me think \"open wide\", which leads me to \"Open Up Wide\" by Chase. (I used to play trumpet and Chase was THE band back in the day). Anyway, solving\u2026","rel":"","context":"In &quot;Scripting&quot;","block_context":{"text":"Scripting","link":"https:\/\/jdhitsolutions.com\/blog\/category\/scripting\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/10\/sw-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":8709,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8709\/converting-powershell-scripts-to-functions\/","url_meta":{"origin":8657,"position":4},"title":"Converting PowerShell Scripts to Functions","author":"Jeffery Hicks","date":"December 10, 2021","format":false,"excerpt":"Recently, I shared some PowerShell code to export a function to a file. It was a popular post. My friend Richard Hicks (no relation) thought we was joking when he asked about converting files to functions. His thought was to take a bunch of PowerShell scripts, turn them into a\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/poc-modulecommands.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/poc-modulecommands.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/poc-modulecommands.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/poc-modulecommands.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":9057,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/9057\/using-powershell-your-way\/","url_meta":{"origin":8657,"position":5},"title":"Using PowerShell Your Way","author":"Jeffery Hicks","date":"June 6, 2022","format":false,"excerpt":"I've often told people that I spend my day in a PowerShell prompt. I run almost my entire day with PowerShell. I've shared many of the tools I use daily on Github. Today, I want to share another way I have PowerShell work the way I need it, with minimal\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/06\/dl.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/06\/dl.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/06\/dl.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/06\/dl.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8657","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=8657"}],"version-history":[{"count":3,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8657\/revisions"}],"predecessor-version":[{"id":9160,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8657\/revisions\/9160"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}