前面我们讲了一些参数的属性,我们可以通过 validateSet 来限制参数值的范围。但有些情况下,参数的值的范围是动态的,这个时候,我们就需要用到动态参数了。
下面我们来看一些具体代码:
Function Test-Net {
[CmdletBinding(DefaultParameterSetName="Computer")]
Param(
[ValidateSet(443,80,22)]
[int]$port
)
# 动态参数代码块,动态生成参数值的取值范围
DynamicParam {
# 设置动态参数名称
$ParameterName = "ComputerName"
# 创建一个字典
$RuntimeParameterDirectionary = 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)
# 生成 validateSet(动态)
$arrSet = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
# 添加 validateSet 到属性集合
$AttributeCollection.Add($ValidateSetAttribute)
# 生成并返回动态属性
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName,[string],$AttributeCollection)
$RuntimeParameterDirectionary.Add($ParameterName,$RuntimeParameter)
return $RuntimeParameterDirectionary
}
Begin{
# 帮助这个动态参数到一个友好的名称
$ComputerName = $PSBoundParameters[$ParameterName]
}
# 实现实际功能的代码
Process{
ForEach ($computer in $ComputerName) {
Write-Verbose "Now testing $computer."
if ($port -eq "")
{
$ping = Test-NetConnection -ComputerName $computer -InformationLevel Quiet -WarningAction SilentlyContinue
} else {
$ping = Test-NetConnection -ComputerName $computer -InformationLevel Quiet -WarningAction SilentlyContinue -Port $port
}
if ($ping){
Write-Output $ping
} else {
Write-Verbose "Ping failed on $computer. Check the network connection."
Write-Output $ping
}
}
}
}
运行时,我们可以看到此时有 ComputerName 的参数值有两个
我们现在新建一个 AD computer:
PS C:\Users\Administrator> New-ADComputer testsvr2
再来看看 ComputerName 参数的值: