假设我想编写一个包装的辅助函数Read-Host.此函数将通过更改提示颜色,调用读取主机,然后更改颜色来增强读取主机(简单示例用于说明目的 - 实际上并未尝试解决此问题).
由于这是Read-Host的包装器,我不想在函数头中重复Read-Host的所有参数(即Prompt和AsSecureString).有没有办法让函数获取一组未指定的参数,然后将这些参数直接传递给函数中的cmdlet调用?我不确定Powershell是否有这样的设施.
例如...
function MyFunc( [string] $MyFuncParam1, [int] $MyFuncParam2 , Some Thing Here For Cmdlet Params that I want to pass to Cmdlet )
{
# ...Do some work...
Read-Host Passthru Parameters Here
# ...Do some work...
}
Run Code Online (Sandbox Code Playgroud)
Roh*_*rds 10
听起来您对'ValueFromRemainingArguments'参数属性感兴趣.要使用它,您需要创建一个高级功能.有关详细信息,请参阅about_Functions_Advanced和about_Functions_Advanced_Parameters帮助主题.
使用该属性时,任何额外的未绑定参数都将分配给该参数.我不认为它们可以原样使用,所以我做了一个小函数来解析它们(见下文).解析它们之后,返回两个变量:一个用于任何未命名的位置参数,另一个用于命名参数.然后可以将这两个变量splat到您要运行的命令.这是可以解析参数的辅助函数:
function ParseExtraParameters {
[CmdletBinding()]
param(
[Parameter(ValueFromRemainingArguments=$true)]
$ExtraParameters
)
$ParamHashTable = @{}
$UnnamedParams = @()
$CurrentParamName = $null
$ExtraParameters | ForEach-Object -Process {
if ($_ -match "^-") {
# Parameter names start with '-'
if ($CurrentParamName) {
# Have a param name w/o a value; assume it's a switch
# If a value had been found, $CurrentParamName would have
# been nulled out again
$ParamHashTable.$CurrentParamName = $true
}
$CurrentParamName = $_ -replace "^-|:$"
}
else {
# Parameter value
if ($CurrentParamName) {
$ParamHashTable.$CurrentParamName += $_
$CurrentParamName = $null
}
else {
$UnnamedParams += $_
}
}
} -End {
if ($CurrentParamName) {
$ParamHashTable.$CurrentParamName = $true
}
}
,$UnnamedParams
$ParamHashTable
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
PS C:\> ParseExtraParameters -NamedParam1 1,2,3 -switchparam -switchparam2:$false UnnamedParam1
UnnamedParam1
Name Value
---- -----
switchparam True
switchparam2 False
NamedParam1 {1, 2, 3}
Run Code Online (Sandbox Code Playgroud)
这里有两个可以使用辅助函数的函数(一个是你的例子):
function MyFunc {
[CmdletBinding()]
param(
[string] $MyFuncParam1,
[int] $MyFuncParam2,
[Parameter(Position=0, ValueFromRemainingArguments=$true)]
$ExtraParameters
)
# ...Do some work...
$UnnamedParams, $NamedParams = ParseExtraParameters @ExtraParameters
Read-Host @UnnamedParams @NamedParams
# ...Do some work...
}
function Invoke-Something {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, Position=0)]
[string] $CommandName,
[Parameter(ValueFromRemainingArguments=$true)]
$ExtraParameters
)
$UnnamedParameters, $NamedParameters = ParseExtraParameters @ExtraParameters
&$CommandName @UnnamedParameters @NamedParameters
}
Run Code Online (Sandbox Code Playgroud)
导入所有三个函数后,请尝试以下命令:
MyFunc -MyFuncParam1 Param1Here "PromptText" -assecure
Invoke-Something -CommandName Write-Host -Fore Green "Some text" -Back Red
Run Code Online (Sandbox Code Playgroud)
一个字:喷。
再多说几句:您可以使用 of$PSBoundParameters和 splatting 的组合将参数从外部命令传递到内部命令(假设名称匹配)。您首先需要删除您不想使用的任何参数$PSBoundParameters:
$PSBoundParameters.Remove('MyFuncParam1')
$PSBoundParameters.Remove('MyFuncParam2')
Read-Host @PSBoundParameters
Run Code Online (Sandbox Code Playgroud)
编辑
示例函数体:
function Read-Data {
param (
[string]$First,
[string]$Second,
[string]$Prompt,
[switch]$AsSecureString
)
$PSBoundParameters.Remove('First') | Out-Null
$PSBoundParameters.Remove('Second') | Out-Null
$Result = Read-Host @PSBoundParameters
"First: $First Second: $Second Result: $Result"
}
Read-Data -First Test -Prompt This-is-my-prompt-for-read-host
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1135 次 |
| 最近记录: |