Question
Hi, I'd like to dynamically create functions from a hashtable in Powershell. But the created functions are supposed to be able to receive parameters.
The Code I have so far:
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
foreach($funcName in $functions.PSBase.Keys){
New-Item function:\ -Name $funcName -Value $([scriptblock]::Create($functions[$funcName])) | Out-Null
}
The problem is, that whatever I type behind the function is not considered a parameter:

Can you help me out?
CodePudding user response:
Here is a possible solution:
$functions = @{
ws = { winget search $args }
# ... and so on
}
foreach($funcName in $functions.PSBase.Keys){
New-Item function:\ -Name $funcName -Value $functions.$funcName | Out-Null
}
- Define script blocks
{…}directly in the hashtable, so you don't need to convert anything for theNew-Itemarguments. - Use the automatic variable
$argsto forward arguments of the script block to the command. Note that for native commands, the$argsarray is unrolled automatically. For PowerShell commands you'd have to use splatting (@args).
CodePudding user response:
Append @args to your CLI calls, so that PowerShell passes all arguments passed to the function itself through:
foreach($funcName in $functions.PSBase.Keys){
$null = New-Item function:$funcName -Value "$($functions[$funcName]) @args"
}
Note:
@argis the splatted form of the automatic$argsvariable. Given that you're calling external programs,$argswould be sufficient in this case (either form results in the (stringified) array elements being passed as individual arguments), but if you were to call PowerShell commands,@argsis required in order to pass named arguments through properly.As shown above, you can pass the function body as a string to
New-Item- it'll be converted to a script block automatically.The above assumes that all pass-through arguments go at the end of each of the CLI command lines that make up your functions. If you need more fine-grained control, use the technique shown in zett42's helpful answer, which allows you to control for each CLI call where
@args/$argsgoes or alternatively allows you to declare parameters explicitly with aparam(...)block.
