Powershell 有没有更好的方法来声明多个参数集?
我正在编写一个cmdlet(在PowerShell中),负责将记录写入数据库。使用条件命令行,我似乎必须定义四个不同的参数集 有没有更成功的方法 细节 cmdlet的参数包括:Powershell 有没有更好的方法来声明多个参数集?,powershell,Powershell,我正在编写一个cmdlet(在PowerShell中),负责将记录写入数据库。使用条件命令行,我似乎必须定义四个不同的参数集 有没有更成功的方法 细节 cmdlet的参数包括: ComputerName(要连接到的SQL server) 路径(数据的位置) Xml(原始数据本身) 用户名 密码 UseIntegratedSecurity(使用当前凭据而不是用户名/密码) Path和Xml是互斥的,而UserName/Password和useeintegratedsecurity是互斥的 为了
(要连接到的SQL server)ComputerName
- 路径(数据的位置)
(原始数据本身)Xml
用户名
密码
(使用当前凭据而不是用户名/密码)UseIntegratedSecurity
Path
和Xml
是互斥的,而UserName
/Password
和useeintegratedsecurity
是互斥的
为了正确连接,我似乎必须定义四个不同的参数集,例如:
function Install-WidgetData
{
[CmdletBinding()]
PARAM
(
[Parameter(ParameterSetName="Xml_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Xml_ManualConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Path_AutoConnect", Mandatory=$True, )]
[Parameter(ParameterSetName="Path_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string[]] $ComputerName,
[Parameter(ParameterSetName="Path_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Path_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Path,
[Parameter(ParameterSetName="Xml_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Xml_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string[]] $Xml,
[Parameter(ParameterSetName="Xml_AutoConnect")]
[Parameter(ParameterSetName="Path_AutoConnect")]
[switch] $UseIntegratedSecurity,
[Parameter(ParameterSetName="Xml_ManualConnect")]
[Parameter(ParameterSetName="Path_ManualConnect")]
[ValidateNotNullOrEmpty()]
[string] $UserName,
[Parameter(ParameterSetName="Xml_ManualConnect")]
[Parameter(ParameterSetName="Path_ManualConnect")]
[ValidateNotNullOrEmpty()]
[string] $Password,
)
嗯,这是最简洁的方式。比switch/case或if/then陷阱更简洁地解释了所有可能的参数集 但是,您的另一个选择是为互斥的参数集编写不同的commandest,例如
Install-WidgetDataFromPath
Install-WidgetDataFromXml
两者都可以调用
Install WidgetData
script commandlet,您可以将其隐藏在模块内部,如果您仅使用脚本文件,则可以使用范围修饰符将其从全局范围隐藏。内部commandlet可以为两个(或多个)面向用户的包装器实现共享代码。从您的代码判断,我认为不需要向您解释如何实现此功能。如果您希望对参数集进行快速的健全性检查,可以使用Show命令
这将显示一个具有多个选项卡的表单,每个参数集一个选项卡。例如:
Show命令Get ChildItem
将显示:
或;如果需要命令行替代方案,可以使用Get Command-Syntax
Get命令Get ChildItem-语法
将向您展示以下内容:
获取子项[[-Path]][[-Filter][-Include][Exclude][Recurse][Depth][Force][Name][UseTransaction][Attributes][Directory][File][Hidden][ReadOnly][System][]
Get ChildItem[[-Filter]]-LiteralPath[-Include][-Exclude][Recurse][Depth][Force][Name][-UseTransation][Attributes][Directory][File][Hidden][ReadOnly][System][]
不幸的是,根据about_函数和Advanced_参数,这是唯一的方法 以下是摘录: 有关参数集的详细信息,请参见
在MSDN库中。有一种更好的方法,但它是一种设计解决方案,而不是技术解决方案 问题实际上是你的函数做了太多的事情。有人可能会说这违反了单一责任原则。它执行的每个任务都有两个单独的参数集。任务及其参数集包括:
- 构建一个连接字符串
- 手册(用户名和密码)
- 自动(操作系统帐户身份验证)
- 向数据库发送查询
- XML数据
- 包含数据的XML文件的路径
newconnectionString
和Install WidgetData
,并且Install WidgetData
可以接受完整的连接字符串作为参数。这将删除从Install WidgetData
构建连接字符串的逻辑,将多个参数压缩为一个,并将所需的参数集数量减半
function New-ConnectionString(
[Parameter(Mandatory=$True, Position=0)] # Makes it mandatory for all parameter sets
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName,
[Parameter(ParameterSetName="AutoConnect", Mandatory=$True)]
[switch]$UseIntegratedSecurity,
[Parameter(ParameterSetName="ManualConnect", Mandatory=$True, Position=1)]
[ValidateNotNullOrEmpty()]
[string]$UserName,
[Parameter(ParameterSetName="ManualConnect", Mandatory=$True, Position=2)]
[ValidateNotNullOrEmpty()]
[string]$Password
) {
# ... Build connection string up
return $connString
}
function Install-WidgetData(
[Parameter(Mandatory=$True, Position=0)]
[ValidateNotNullOrEmpty()]
[string]$ConnectionString,
[Parameter(ParameterSetName="Path", Mandatory=$True, Position=1)]
[ValidateNotNullOrEmpty()]
[string]$Path,
[Parameter(ParameterSetName="Xml", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string[]]$Xml
) {
# Do installation
}
通过调用命令上的help
,您可以看到这是您想要的:
PS C:\> help New-ConnectionString
NAME
New-ConnectionString
SYNTAX
New-ConnectionString [-ComputerName] <string[]> -UseIntegratedSecurity [<CommonParameters>]
New-ConnectionString [-ComputerName] <string[]> [-UserName] <string> [-Password] <string> [<CommonParameters>]
...
PS C:\> help Install-WidgetData
NAME
Install-WidgetData
SYNTAX
Install-WidgetData [-ConnectionString] <string> [-Path] <string> [<CommonParameters>]
Install-WidgetData [-ConnectionString] <string> -Xml <string[]> [<CommonParameters>]
...
当然,如果需要,可以将newconnectionString
的结果存储在变量中。执行此重构还可以获得一些附加功能:
的返回值可用于需要连接字符串的任意数量的函数新连接字符串
- 如果调用者愿意,他们可以从其他来源获取连接字符串
- 如果呼叫者需要使用您未提供访问权限的功能,他们可以放弃您的
,转而自己使用新连接字符串
$ComputerName
可以不使用参数setname
。据我所知,你唯一可以最小化的就是@C.B.所说的内容。让我们只说,#region
存在的原因是有原因的,这对于非技术人员来说非常方便。非常棒。Get命令Install WidgetData-Syntax
同样有用这可能对某些用户很有帮助,但似乎并没有真正回答问题。这是正确的解决方案,即使它不是真正的PowerShell
方法。它使使用更加复杂(调用两个函数而不是一个函数)。不过,这需要一些很好的解释/文档/示例。@oɔɯǝɹ我不会说这不是PowerShell的做事方式。在我看来,这与在传入文件路径之前调用joinpath
建立文件路径没有太大区别。您只需添加一个函数,从几个不同的部分构建一个内聚参数。
PS C:\> help New-ConnectionString
NAME
New-ConnectionString
SYNTAX
New-ConnectionString [-ComputerName] <string[]> -UseIntegratedSecurity [<CommonParameters>]
New-ConnectionString [-ComputerName] <string[]> [-UserName] <string> [-Password] <string> [<CommonParameters>]
...
PS C:\> help Install-WidgetData
NAME
Install-WidgetData
SYNTAX
Install-WidgetData [-ConnectionString] <string> [-Path] <string> [<CommonParameters>]
Install-WidgetData [-ConnectionString] <string> -Xml <string[]> [<CommonParameters>]
...
Install-WidgetData (New-ConnectionString 'myserver.example.com' -UseIntegratedSecurity) `
-Path '.\my-widget-data.xml'