假设我有此cmdlet
[CmdletBinding(DefaultParameterSetName='View')]
Param(
[Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
[Switch]$ChangeOne,
[Parameter(ParameterSetName='ChangeAll', Mandatory=$true)]
[Switch]$ChangeAll,
[Parameter(ParameterSetName='View', Mandatory=$false)]
[Switch]$View
)
现在我有一些条件语句,如下:
if ($ChangeOne)
{
$input = (Read-Host -prompt "Database")
if (!$input)
{
Write-Host "`r`n`You MUST enter a DB Name! 1 more try...`r`n" -foregroundcolor cyan -backgroundcolor black
$input = (Read-Host -prompt "Database")
if (!$input)
{
Write-Host "`r`nNo DB Name entered...exiting script`r`n" -foregroundcolor magenta -backgroundcolor black
Write-host "----------------------------END of Script------------------------------"
exit 1
}
}
}
这很好用,除了现在我正尝试使用TFS中的WinRM调用此脚本,并且TFS将不会与Read-Host交互...相反,它将仅接受诸如:
的直接参数。script1.ps1 -ChangeOne数据库输入1
我的问题是,如何允许在没有提示的情况下在命令行中输入Read-Host?我只是想一种让TFS接受读取主机预定义输入的方法
我会想到这样的东西,但这不会起作用,因为param
要求它必须位于脚本的顶部...
if ($ChangeOne)
{
param([string]$input)
if (!$input)
{
Write-Host "`r`n`You MUST enter a DB Name! 1 more try...`r`n" -foregroundcolor cyan -backgroundcolor black
$input = param([string]$input)
if (!$input)
{
Write-Host "`r`nNo DB Name entered...exiting script`r`n" -foregroundcolor magenta -backgroundcolor black
Write-host "----------------------------END of Script------------------------------"
exit 1
}
}
}
答案 0 :(得分:1)
要添加DynamicParam
,您需要逐步构建对象。我使用以下模板创建我的模板,需要注意的主要地方是$ParameterName
,[String]
,您可以根据需要进行更改。
function MyFunction
{
[CmdletBinding(DefaultParameterSetName='View')]
Param(
[Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
[Switch]$ChangeOne,
[Parameter(ParameterSetName='ChangeAll', Mandatory=$true)]
[Switch]$ChangeAll,
[Parameter(ParameterSetName='View', Mandatory=$false)]
[Switch]$View
)
DynamicParam
{
if($ChangeOne)
{
#OutputObject
$ParameterName = 'DatabaseInput'
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$AttributeCollection.Add($ParameterAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
}
}
如果要根据某些预定义值验证输入,则可以创建一个数组(可以硬编码或动态生成)。
请注意,添加了以下几行
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
$AttributeCollection.Add($ValidateSetAttribute)
和
$ValidationArray = 1..9
下面是完整的DynamicParam
块
DynamicParam
{
if($ChangeOne)
{
#Array of values to validate against
$ValidationArray = 1..9
#OutputObject
$ParameterName = 'DatabaseInput'
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$AttributeCollection.Add($ParameterAttribute)
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
$AttributeCollection.Add($ValidateSetAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
}
这是我重复使用的两个模板。使用intellisense在PowerShell ISE中进行测试。
这些“模板”可能会被清理掉,所以那里可能会有更好的例子。
修改
您可以手动指定参数的位置,我们需要使用$ParameterAttribute.Position = 1
在参数上设置position属性。我还在开关上将位置设置为0
,建议您手动设置所有参数的位置,以使您安心。
我之前也没有提到您需要通过$PsBoundParameters
访问值。在此示例中,我将它们分配给了begin
块中的变量。这使它们在整个函数中更易于引用,但是您可以只使用$PsBoundParameters["DatabaseInput"]
。
function MyFunction
{
[CmdletBinding(DefaultParameterSetName='View',PositionalBinding=$false)]
Param(
[Parameter(ParameterSetName='ChangeOne', Mandatory=$true, Position=0)]
[Switch]$ChangeOne,
[Parameter(ParameterSetName='ChangeAll', Mandatory=$true, Position=0)]
[Switch]$ChangeAll,
[Parameter(ParameterSetName='View', Mandatory=$false, Position=0)]
[Switch]$View
)
DynamicParam
{
if($ChangeOne)
{
#Array of values to validate against
$ValidationArray = 1..9
#OutputObject
$ParameterName = 'DatabaseInput'
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 1
$AttributeCollection.Add($ParameterAttribute)
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
$AttributeCollection.Add($ValidateSetAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
}
begin
{
$ChangeOne = $PsBoundParameters["ChangeOne"]
$ChangeAll = $PsBoundParameters["ChangeAll"]
$View = $PsBoundParameters["ChangeAll"]
$DatabaseInput = $PsBoundParameters["DatabaseInput"]
}
process
{
if($databaseInput)
{
return $databaseInput
}
else
{
return $False
}
}
}
正在运行:
MyFunction -ChangeAll
MyFunction -ChangeOne -DatabaseInput 3
MyFunction -ChangeOne 6
礼物:
False
3
6
编辑2
要创建更多参数,您需要向$RuntimeParameterDictionary
function MyFunction
{
[CmdletBinding(DefaultParameterSetName='View',PositionalBinding=$false)]
Param(
[Parameter(ParameterSetName='ChangeOne', Mandatory=$true, Position=0)]
[Switch]$ChangeOne,
[Parameter(ParameterSetName='ChangeAll', Mandatory=$true, Position=0)]
[Switch]$ChangeAll,
[Parameter(ParameterSetName='View', Mandatory=$false, Position=0)]
[Switch]$View
)
DynamicParam
{
if($ChangeOne)
{
#Create a dictionary of parameters
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
####Parameter 1
$ParameterName = "databaseInput"
#Array of values to validate against
$ValidationArray = 1..9
#Create parameter attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 1
$AttributeCollection.Add($ParameterAttribute)
#Add validation (omit if not needed)
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
$AttributeCollection.Add($ValidateSetAttribute)
#Create the parameter
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
#Add the parameter to the dictionary
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
###Parameter 2
$ParameterName = "Server"
#Array of values to validate against
$ValidationArray = "One","Two","Three"
#Create parameter attributes
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 2
$AttributeCollection.Add($ParameterAttribute)
#Add validation (omit if not needed)
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
$AttributeCollection.Add($ValidateSetAttribute)
#Create the parameter
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
#Add the parameter to the dictionary
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
#Return parameters
Return $RuntimeParameterDictionary
}
}
begin
{
$ChangeOne = $PsBoundParameters["ChangeOne"]
$ChangeAll = $PsBoundParameters["ChangeAll"]
$View = $PsBoundParameters["ChangeAll"]
$DatabaseInput = $PsBoundParameters["DatabaseInput"]
$Server = $PsBoundParameters["Server"]
}
process
{
if($databaseInput)
{
Return $DatabaseInput,$Server
}
else
{
Return $False
}
}
}
因此,运行以下命令:
MyFunction -ChangeOne -databaseInput 3 -Server Two
MyFunction -ChangeOne 7 Two
返回:
3
Two
7
Two
参考:https://blogs.technet.microsoft.com/poshchap/2017/09/01/scripting-tips-tricks-dynamic-parameters/
答案 1 :(得分:1)
您可以使用“参数集和验证”来完成此操作。
它看起来像这样:
[CmdletBinding(DefaultParameterSetName='View')]
Param(
[Parameter(ParameterSetName='ChangeAll', Mandatory=$false)]
[Switch]$ChangeAll,
[Parameter(ParameterSetName='View', Mandatory=$false)]
[Switch]$View,
[Parameter(ParameterSetName='ChangeOne', Mandatory=$false)]
[Switch]$ChangeOne,
[Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
[ValidateScript({![string]::IsNullOrEmpty($_.Trim())})]
[string]$Database = ${if ($ChangeOne)`{Read-Host -Prompt "Database"`} else `{""`}}
)
或者,如果您知道希望看到的脚本,则验证可以如下所示:
[ValidateSet("Database1","Database2","Database3")]
验证将处理以确保输入是可接受的,该开关将驱动数据库参数的要求,并且如果您尝试传递不带-ChangeOne标志的数据库参数,它还将导致脚本中止并显示一个错误。