Tho*_*ten 1 parameters powershell wrapper
我正在编写一个使用 ValueFromRemainingArguments 包装 cmdlet 的函数(如此处所述)。
下面的简单代码演示了这个问题:
function Test-WrapperArgs {
Set-Location @args
}
Run Code Online (Sandbox Code Playgroud)
Test-WrapperArgs -Path C:\
Run Code Online (Sandbox Code Playgroud)
Test-WrapperArgs -Path C:\
Run Code Online (Sandbox Code Playgroud)
Test-WrapperUnbound -Path C:\
Set-Location: F:\cygwin\home\thorsten\.config\powershell\test.ps1:69
Line |
69 | Set-Location @UnboundArgs
| ~~~~~~~~~~~~~~~~~~~~~~~~~
| A positional parameter cannot be found that accepts argument 'C:\'.
Run Code Online (Sandbox Code Playgroud)
我尝试通过 PowerShell 社区扩展来解决该问题,GetType但EchoArgs没有成功。目前我几乎正在考虑一个错误(可能与这张票有关??)。
高级函数(使用属性和/或属性的函数)的最佳解决方案是通过PowerShell SDK 构建代理(包装器)函数,如本答案所示。这本质上涉及复制目标命令的参数声明(尽管以自动但静态的方式)。[CmdletBinding()][Parameter()]
如果您不想使用这种方法,您唯一的选择是执行您自己的数组解析($UnboundArgs从技术上讲,它是 的实例[System.Collections.Generic.List[object]]),但这很麻烦,而且并非万无一失:
function Test-WrapperUnbound {
Param(
[Parameter(ValueFromRemainingArguments)] $UnboundArgs
)
# (Incompletely) emulate PowerShell's own argument parsing by
# building a hashtable of parameter-argument pairs to pass through
# to Set-Location via splatting.
$htPassThruArgs = @{}; $key = $null
switch -regex ($UnboundArgs) {
'^-(.+)' { if ($key) { $htPassThruArgs[$key] = $true } $key = $Matches[1] }
default { $htPassThruArgs[$key] = $_; $key = $null }
}
if ($key) { $htPassThruArgs[$key] = $true } # trailing switch param.
# Pass the resulting hashtable via splatting.
Set-Location @htPassThruArgs
}
Run Code Online (Sandbox Code Playgroud)
笔记:
这并不是万无一失的,因为您的函数将无法区分实际参数名称(例如,-Path)和恰好看起来像参数名称的字符串文字(例如,'-Path')
此外,与顶部提到的基于脚手架的代理函数方法不同,您不会获得任何传递参数的制表符补全,并且传递参数不会用-?//列出。Get-HelpGet-Command -Syntax
如果您不介意既没有制表符完成也没有语法帮助和/或您的包装函数必须支持传递到多个或预先未知的目标命令,请使用一个简单的(非高级)函数@args(如在您的工作示例中;另见下文)是最简单的选项,假设您的函数本身不需要支持通用参数(这需要高级函数)。
使用简单函数还意味着公共参数仅传递给包装的命令(而高级函数会将它们解释为本身的意思,尽管它们的效果通常传播到函数内部的调用;但是-OutVariable,使用公共参数,例如区别很重要)。
至于你尝试过的:
虽然PowerShell[System.Collections.Generic.List[object]]原则上确实支持通过数组(或类似数组的集合,例如)进行展开,但只有当所有元素都作为位置参数传递和/或目标命令是外部程序(关于其参数结构)时,这才按预期工作。 PowerShell 一无所知,并且始终将参数作为标记列表/数组传递)。
为了将带有命名参数的参数传递给其他 PowerShell 命令,您必须使用基于哈希表的 splatting,其中每个条目的键标识目标参数,值标识参数值(参数)。
尽管自动$args变量在技术上也是一个数组( [object[]]),但 PowerShell 具有内置的魔法,允许 splatting with@args也可以使用命名参数- 这不适用于任何自定义数组或集合。
请注意,自动$args变量收集未声明参数的所有参数 -仅在简单(非高级)函数和脚本中可用;高级函数和脚本- 使用[CmdletBinding()]属性和/或 属性的函数[Parameter()]和脚本 - 要求声明所有潜在参数。
| 归档时间: |
|
| 查看次数: |
1057 次 |
| 最近记录: |