我正在尝试为脚本模块创建一个函数,该函数在显示下一个参数之前验证前一个参数是否已设置。
我需要的参数是Identity、Share 和Quota。 我总是希望显示身份,在设置身份之前我不想显示共享,并且在设置共享之前我不想显示配额。
我能够轻松访问 $Identity,但无法从 DynamicParam{} 中访问 $Share。 我使用 PowerGUI 单步执行脚本,当我点击 Begin{} 时我只能看到 $Share。
如果设置了身份,我有一种方法可以通过仅显示共享/配额来解决此问题,但最终我想了解如何根据先前设置的参数继续添加其他参数。
该函数的副本如下。 personfileutility.exe 只是我们用来与各种系统交互以配置和收集用户信息的可执行文件。
function New-PersonalFiles
{
[CmdletBinding()]
Param
(
# Param1 help description
[Parameter(Mandatory=$true)]
$Identity
)
DynamicParam
{
$paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
if (($Identity -notlike "") -or ($Identity -notlike $null)){
$attributes = new-object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = "__AllParameterSets"
$attributes.Mandatory = $true
$lookup = [xml](\\servername\personalfiles\personfileutility.exe -a $Identity)
$type = $lookup.User.user_directory.type.type
if ($type -like "other" -or $type -like "staff") {
$arguments = @()
$arguments += "\\fileserver\sharename"
}
elseif ($type -like "faculty") {
$arguments = @()
$arguments += "\\fileserver\sharename"
$arguments += "\\fileserver\sharename2"
}
elseif ($type -like "student") {
$arguments = @()
$arguments += "\\fileserver2\sharename"
}
$ParamOptions = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $arguments
$attributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection.Add($attributes)
$attributeCollection.Add($ParamOptions)
$dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter("Share", [String], $attributeCollection)
$paramDictionary.Add("Share", $dynParam1)
}
if (($Share -like "\\fileserver\*"))
{
$attributes2 = new-object System.Management.Automation.ParameterAttribute
$attributes2.ParameterSetName = "__AllParameterSets"
$attributes2.Mandatory = $true
$lookup = [xml](\\servername\personalfiles\personfileutility.exe -a $Identity)
$type = $lookup.User.user_directory.type.type
if ($type -like "other" -or $type -like "staff") {
$arguments = @()
$arguments += "15GB"
$arguments += "20GB"
}
elseif ($type -like "faculty") {
$arguments = @()
$arguments += "10GB"
$arguments += "15GB"
}
elseif ($type -like "student") {
$arguments = @()
$arguments += "5GB"
$arguments += "10GB"
}
$ParamOptions2 = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $arguments2
$attributeCollection2 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection2.Add($attributes2)
$attributeCollection2.Add($ParamOptions2)
$dynParam2 = new-object -Type System.Management.Automation.RuntimeDefinedParameter("Quota", [String], $attributeCollection2)
$paramDictionary.Add("Quota", $dynParam2)
}
return $paramDictionary
}
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
#>
Begin
{
}
Process
{
\\servername\personalfiles\personfileutility.exe -a $Identity -c -q ((Invoke-Expression $PSBoundParameters.Quota) / 1KB) -s $Share
}
End
{
}
}
我正在尝试复制您正在使用的“解决方法”,但我只看到我可以访问动态参数
Share
(而不是Quota
)。为了重现您的设置,由于我无法访问 personfileutility.exe,我注释掉了两行并添加了第三行,其中我将 $type
硬编码为“faculty”。例如,在两个地方我将代码更新为:
#$lookup = [xml](\\servername\personalfiles\personfileutility.exe -a $Identity)
#$type = $lookup.User.user_directory.type.type
$type = "faculty"
完成这些更改后,我可以在指定
Share
后访问 Identity
参数。 但是,我无法访问Quota
。您期望 Quota
可用吗?
如果我理解您所问的问题,那么您不希望
Share
可以访问,直到 Identity
可以访问(您目前正在工作)。但除此之外,您不希望 Quota
可供访问,直到 Identity
和 Share
都已填写,并且您不知道如何实现该功能。这是正确的吗?
如果我正确理解了这个问题,我不相信 PowerShell 提供了一种通过 Commandlet 绑定来实现这一目标的机制。我认为您可以通过使用 GUI 应用程序或交互式提示用户输入来实现此目的。
大家好消息!我自己也面临这样的问题,不知道该怎么办。我搜索了几个论坛但没有找到。
但好消息是:它可以在 PowerShell 中运行。您可以根据值(而不是参数本身)定义多个动态参数。您只需退后两步并重新思考实际问题是什么。
所以我的函数有三个参数:Team、Channel和Message。 Team 参数是第一个参数,直接在函数中声明。 Channel 和 Message 参数是在运行时添加到函数的动态参数。
Team参数仅接受可以使用 [TAB] 完成的预定义值(来自哈希表)。只有设置了这个值,函数才会添加第二个参数Channel,它也只接受有效值(也可以用[TAB]完成)。最后,如果第二个参数也有有效值,则将第三个参数Message添加到函数中。
参数列表理论上可以永远持续下去,但三个对我来说就足够了:-)所以这里是代码:
$hashtable = @{
"Team 1" = @{
"Channel T1-1" = "123"
"Channel T1-2" = "456"
"Channel T1-3" = "789"
}
"Team 2" = @{
"Channel T2-1" = "123"
"Channel T2-2" = "456"
}
"Team 3" = @{
"Channel T3-1" = "123"
"Channel T3-2" = "456"
}
}
function Send-MessageToMSTeams
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string]$Team
)
dynamicparam
{
$paramDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
if ($PSBoundParameters.ContainsKey('Team') -and $MSTeamsWebhooks.ContainsKey($PSBoundParameters['Team']))
{
$selectedTeam = $PSBoundParameters['Team']
$teamChannels = $MSTeamsWebhooks[$selectedTeam].Keys
$channelAttribute = New-Object -TypeName System.Management.Automation.ParameterAttribute
$channelAttribute.Mandatory = $true
$channelParameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter('Channel', [string], $channelAttribute)
$channelParameter.Attributes.Add((New-Object System.Management.Automation.ValidateSetAttribute($teamChannels)))
$paramDictionary.Add('Channel', $channelParameter)
}
if ($paramDictionary.ContainsKey('Channel'))
{
$messageAttr = New-Object -TypeName System.Management.Automation.ParameterAttribute
$messageAttr.Mandatory = $true
$messageParam = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter('Message', [string], $messageAttr)
$paramDictionary.Add('Message', $messageParam)
}
return $paramDictionary
}
process
{
Write-Host $PSBoundParameters
}
}
因此,诀窍是不要使用
$PSBoundParameters
或参数名称本身(就像您在代码中使用 $Share
所做的那样),而是在之前将其添加到 if 块中时使用 $paramDictionary
。
祝你好运!