我正在开发一个比较两个对象的函数,以便检测它们是否相同。但是我希望它也可以与其他类型一起使用,例如字符串或整数。
C++ 允许您声明具有相同名称的不同函数,以不同的方式处理具有不同输入类型的函数调用。我知道参数集的存在,但据我所知,用户必须指定他正在使用哪个参数集。
我正在尝试做这样的事情
function Compare-Objects{
Param(
[Parameter(Mandatory=$true,
Position=0,
ParameterSetName = "Hashtables")]
[ValidateNotNullOrEmpty()]
[Hashtable]$Item1Hash,
[Parameter(Mandatory=$true,
Position=0,
ParameterSetName = "Integers")]
[ValidateNotNullOrEmpty()]
[int]$Item1int,
[Parameter(Mandatory=$true,
Position=1,
ParameterSetName = "Hashtables")]
[ValidateNotNullOrEmpty()]
[Hashtable]$Item2Hash,
[Parameter(Mandatory=$true,
Position=1,
ParameterSetName = "Integers")]
[ValidateNotNullOrEmpty()]
[Hashtable]$Item2Int
)
if($PSCmdlet.ParameterSetNamePositionv -match "Integers"){ Return ($Item1Int -eq $Item2Int)}
else{
#do some other stuff with $Item1Hash and $Item2Hash
}
}
Run Code Online (Sandbox Code Playgroud)
如果我也可以将变量命名为相同,则额外加分(因此$Item1Hash
并$Item1Int
成为$Item1
分配了适当类型的变量)
我正在编写一个函数,它的两个参数应该是互斥的和可选的。
以下是有效输入:
new-event -Title sometitle -Text sometext -TimestampHappened 1234567 -SomeOtherOptionalParam somestring
new-event -Title sometitle -Text sometext -DateHappened (get-date) -SomeOtherOptionalParam somestring
new-event -Title sometitle -Text sometext -SomeOtherOptionalParam somestring
new-event -Title sometitle -Text sometext
Run Code Online (Sandbox Code Playgroud)
这是一个无效的输入:
new-event -Title sometitle -Text sometext -DateHappened (get-date) -TimestampHappened 1234567 -SomeOtherOptionalParam somestring
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我的代码:
[CmdletBinding()]
# Most parameters belong to Default, New-Event:ByDate and New-Event:ByTimestamp parameter sets
param (
[Parameter(
Position=0,
Mandatory=$True,
ParameterSetName="Default"
)]
[Parameter(
Position=0,
Mandatory=$True,
ParameterSetName="New-Event:ByDate"
)]
[Parameter(
Position=0,
Mandatory=$True,
ParameterSetName="New-Event:ByTimestamp"
)]
[ValidateNotNullOrEmpty()]
[String]$Title, …
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个Set-MyRef
使用 ParameterSets 来公开其可用参数的 PowerShell 函数。我希望该函数具有类似于以下内容的参数集:
Set-MyRef -Latest
Set-MyRef -LocalBranch
Set-MyRef [-Tag] <string>
Set-MyRef [-Env] <string> -LocalBranch
Set-MyRef [-Env] <string> -Latest
Set-MyRef [-Env] <string> [-Tag] <string>
Run Code Online (Sandbox Code Playgroud)
也就是说,恰好有一个 options -Latest
,-LocalBranch
或者-Tag
可以给出一个可选的-Env
作为第一个位置参数。
重要的是,我希望Set-MyRef 'foo'
被解析为-Tag 'foo'
,并被Set-MyRef 'foo' 'bar'
解析为-Env 'foo' -Tag 'bar'
.
我尝试使用 ParameterSets 来实现它:
function Set-MyRef {
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true, ParameterSetName = 'EnvTag')]
[Parameter(Position = 0, Mandatory = $true, ParameterSetName = 'EnvLatest')] …
Run Code Online (Sandbox Code Playgroud) 我为库模块编写了一些相当复杂的函数,可以使用许多不同的方法来调用它。但是,实际上可以将它们全部默认设置,但是当我尝试不带参数调用函数时,由于无法确定参数集,因此调用失败。
我想定义一个不包含任何参数的参数集,以使没有参数的调用成功。由于ParameterSetName是Parameter属性的属性,因此很难做到这一点,并且不可能一无所获。
我尝试了放在param块上的CmdletBinding属性的DefaultParameterSet属性,但是似乎没有任何效果。似乎那里定义的参数集名称实际上必须存在,以便Powershell默认使用它。
目前,我对该用例的最佳近似方法是将其中一个参数集定义为没有强制性参数,但是当输入空字符串或null时,这些参数将失败,我希望情况并非如此。
这可能吗?
假设我有一个类似的函数:
function Authenticate
{
param
(
[ValidateSet('WindowsAuthentication','UsernameAndPassword')]
[string]$AuthenticationType,
[Parameter(ParameterSetName='ParamSet1')]
[string]$Username,
[Parameter(ParameterSetName='ParamSet1')]
[string]$Password
)
..
}
Run Code Online (Sandbox Code Playgroud)
我想执行这些规则:
ParamSet1
如果出现以下情况,则强制设置参数$AuthenticationType = 'UsernameAndPassword'
ParamSet1
如果$AuthenticationType = 'WindowsAuthentication'
这可能吗?
我在我编写的自定义函数中看到了一些奇怪的行为,因此我编写了一些具有不同特征的快速测试函数来展示这些行为。当参数集足够相似以至于唯一的区别因素是通过管道接收的对象的类型时,就会出现问题。
首先,我创建了一个简单的类型,它只与字符串不同。
Add-Type @"
public class TestType {
public string Prop1;
}
"@
Run Code Online (Sandbox Code Playgroud)
接下来,我创建了一个测试函数并使用字符串和 TestType 输入运行它。
function Test-ParameterSets1
{
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Str")] [string] $StringInput,
[Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Test")] [TestType] $TestInput
)
begin {
$result = New-Object Object | Select-Object –Property @{n='FunctionName';e={$PSCmdlet.MyInvocation.InvocationName}},@{n='ParameterSetName';e={$PSCmdlet.ParameterSetName}}
}
process {
$result | Add-Member -MemberType NoteProperty -Name StringInput -Value $StringInput -PassThru | Add-Member -MemberType NoteProperty -Name TestInput -Value $TestInput
}
end {
$result
}
}
'string' | Test-ParameterSets1
New-Object TestType | Test-ParameterSets1
FunctionName ParameterSetName StringInput …
Run Code Online (Sandbox Code Playgroud) 我编写了一个使用四个参数和四个参数集的函数。第一个参数$Path
未分配给集合,因此属于所有集合。它也是强制性的,并且是唯一可以从管道传递的参数。但是,当我在管道末尾调用函数时使用其他三个参数的某些组合(所有这些参数都属于四组的某些组合)执行此操作时,我收到一条错误,指示该组不明确。
这是我的功能:
function Foo-Bar {
[CmdletBinding(DefaultParameterSetName = 'A')]
param (
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[string[]] $Path,
[Parameter(ParameterSetName = 'A')]
[Parameter(ParameterSetName = 'A-Secure')]
[Switch] $OutputToConsole,
[Parameter(Mandatory = $true,
ParameterSetName = 'B')]
[Parameter(Mandatory = $true,
ParameterSetName = 'B-Secure')]
[int] $OutputMode,
[Parameter(Mandatory = $true,
ParameterSetName = 'A-Secure')]
[Parameter(Mandatory = $true,
ParameterSetName = 'B-Secure')]
[Switch] $Login
)
$PSCmdlet.ParameterSetName
}
Run Code Online (Sandbox Code Playgroud)
所有可能的参数组合如下:
PS C:\> Foo-Bar -Path "C:\Test.jpg"
A
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputToConsole
A
PS C:\> Foo-Bar -Path "C:\Test.jpg" -OutputToConsole …
Run Code Online (Sandbox Code Playgroud) 我必须编写一个脚本来获取 Thing 的实例。每个事物都包含一个事件时间戳。我需要允许用户指定时间戳范围。
如何使用 ParameterSet 禁用 $Since 和 $StartTimestamp 的使用并禁用 $Until 和 $EndTimestamp 的使用?
关于使用多个参数集的帖子似乎随着参数数量呈指数增长。真的是这样吗?
有关于使用 DynamicParam 的帖子。我还没有看到 DynamicParam 适合于此。是吗?
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string] $ThingName
,[ValidateSet('Today', 'Yesterday', 'LastWeek')]
[string] $Since
,[datetime] $StartTimestamp
,[ValidateSet('Today', 'Now', 'Yesterday', 'LastWeek')]
[string] $Until
,[datetime] $EndTimestamp
)
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用参数集并使用默认参数集。但是默认参数集似乎不适用于我。任何帮助深表感谢。我可以轻松地使用带有默认操作的验证集,但我想知道我在这里做错了什么。
Param([cmdletbinding(DefaultParametersetname="Directory")]
[Parameter(Mandatory=$false,ParameterSetName="File")]
[switch]$file,
[Parameter(Mandatory=$false,ParameterSetName="Directory")]
[switch]$directory,
[Parameter(Mandatory=$false,ParameterSetName="File")]
[Parameter(Mandatory=$false,ParameterSetName="Directory")]
[string]$Source,
[Parameter(Mandatory=$true,ParameterSetName="File")]
[Parameter(Mandatory=$true,ParameterSetName="Directory")]
[string]$DestinationPath,
[Parameter(Mandatory=$false,ParameterSetName="Directory")]
[Parameter(Mandatory=$false,ParameterSetName="File")]
[array]$Servers
PS C:\> Test-Script -Source "c:\somedirectory" -DestinationPath "c:\someotherdirectory"
Run Code Online (Sandbox Code Playgroud)
测试脚本:无法使用指定的命名参数来解析参数集。
在第1行:char:1
+测试脚本-Source“ c:\ somedirectory” -DestinationPath“ c:\ someotherdirectory”
+ ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~
+ CategoryInfo:InvalidArgument:(:) [测试脚本],ParameterBindingException
+ FullyQualifiedErrorId:AmbiguousParameterSet,测试脚本