Verwenden von erweiterten Parametersätzen in einer Funktion mit mehreren eindeutigen Schaltern

3417
cyborgcommando0

Ich benutze Powershell 4.0.

Ich versuche, ein Cmdlet zu schreiben, und in diesem Cmdlet möchte ich erweiterte Parametersätze verwenden, um bestimmte Optionen zur Verfügung zu haben, die auf den ausgewählten Parametern basieren. Diese spezielle Funktion wird im Wesentlichen und letztendlich Get-ADComputer sein, jedoch ist -SearchBase für bestimmte Optionen vorprogrammiert.

Ich habe insgesamt 6 Parameter. 2 sind Strings ($ ComputerName oder $ IpAddress), 1 ist eine ganze Zahl ($ OULevel) und 3 Schalter ($ ComputerOU, $ AllCompany, $ List).

Ich habe jeweils einen Parametersatz für ComputerName und IPAddress, ich möchte, dass der Benutzer das eine oder das andere eingeben kann - ich denke, ich habe dies herausgefunden, es ist ziemlich einfach. Ich möchte jedoch, dass $ OULevel, $ ComputerOU und $ AllCompany eine exklusive Bedeutung haben, wenn einer verwendet wird und der andere nicht verwendet werden kann. Die $ Liste sollte in jedem Szenario verfügbar bleiben.

Ich habe verschiedene Variationen der Parametersätze ohne Erfolg ausprobiert. So sieht mein Skript jetzt aus, mit ein paar Rückschnitten:

 function Get-CompanyADComputer{ [CmdletBinding(DefaultParametersetName="ComputerName")]  Param( [Parameter(Mandatory=$true, ParameterSetName="ComputerName", Position=0, ValueFromPipeline=$false, HelpMessage='Enter a computer name to search in ActiveDirectory.')] [Alias('Computer','CN')] [string]$ComputerName,  [Parameter(Mandatory=$true, ParameterSetName="IPAddress", Position=0, ValueFromPipeline=$false, HelpMessage='Enter an IP address to search in ActiveDirectory.')] [Alias('IPv4Address','IPv6Address')] [string]$IPAddress,  [Parameter(Mandatory=$false, HelpMessage='Enter a number between 0 and 8. 0 is your current OU Container.')] [ValidateRange(0,8)] [int]$OULevel = 0,  [Parameter()] [Switch]$ComputerOU,  [Parameter()] [Switch]$AllCompany,  [Parameter()] [Switch]$List ) 

Wenn Sie neugierig sind, ist unser AD nach Standort geordnet. Dann werden die Kategorien (Computer, Benutzer, Gruppen, Kontakte usw.) in den einzelnen Organisationseinheiten detaillierter dargestellt. Dieses Skript erkennt die Organisationseinheit Ihres Computers und startet die Suche dort. $ OULevel dient dazu, wenn der Benutzer eine andere Nummer angibt, die Suche in einer anderen Organisationseinheit gestartet wird und dann rekursiv durchsucht wird. Der Zweck von $ ComputerOU besteht darin, dass Ihre Suche in die Standard-Organisationseinheit "Computer" anstatt der gesamten Domäne oder Ihrem Standort verschoben wird. $ AllCompany dient dazu, die Suche standardmäßig auf die gesamte Domäne anstatt auf eine andere Auswahl oder Organisationseinheit zu beschränken.

Jede Anleitung wird geschätzt. Ich scheine den Dreh raus zu bekommen, ohne dass mein Skript sich verworren lässt.

2

2 Antworten auf die Frage

2
cyborgcommando0

Ich habe Don Jones den Powershell-Guru in einem anderen Forum gefragt und er gab mir die Informationen, die ich brauchte. Er erklärte es mir damit:

Wenn ich die Frage verstehe, müssen Sie grundsätzlich alle möglichen Kombinationen ausrechnen. Denken Sie daran, dass ein Parameter zu mehr als 1 Parametersätzen gehören kann. Möglicherweise haben Sie also einen Satz mit Computername und OULevel, Computername und ComputerOU sowie Computername und AllCompany. Das sind drei. Dann die drei nochmal für IPAddress. Ich weiß, dass es nicht elegant ist, aber schauen Sie sich die Hilfe für Where-Object an - auch nicht bei weitem. Liste würde dann nicht zu einer Menge gehören, was bedeutet, dass sie allen gehören würde.

Das brachte mich auf die richtige Spur. Also habe ich letztendlich die Funktionsweise meines Cmdlets geändert, sodass meine Antwort überarbeitet wurde. Jetzt, da ich verstehe, was zu tun ist, werde ich mein vorhandenes Beispiel aktualisieren, damit ich konsequent sein und hoffentlich helfen kann.

 function Get-CompanyADComputer{ [CmdletBinding(DefaultParametersetName="ComputerName")]  Param( [Parameter(Mandatory=$true, ParameterSetName="ComputerName", Position=0, ValueFromPipeline=$false, HelpMessage='Enter a computer name to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="ComputerNameOULevel", Position=0, ValueFromPipeline=$false, HelpMessage='Enter a computer name to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="ComputerNameComputerOU", Position=0, ValueFromPipeline=$false, HelpMessage='Enter a computer name to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="ComputerNameAllCompany", Position=0, ValueFromPipeline=$false, HelpMessage='Enter a computer name to search in ActiveDirectory.')] [Alias('Computer','CN')] [string]$ComputerName,  [Parameter(Mandatory=$true, ParameterSetName="IPAddress", Position=0, ValueFromPipeline=$false, HelpMessage='Enter an IP address to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="IPAddressOULevel", Position=0, ValueFromPipeline=$false, HelpMessage='Enter an IP address to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="IPAddressComputerOU", Position=0, ValueFromPipeline=$false, HelpMessage='Enter an IP address to search in ActiveDirectory.')] [Parameter(Mandatory=$true, ParameterSetName="IPAddressAllCompany", Position=0, ValueFromPipeline=$false, HelpMessage='Enter an IP address to search in ActiveDirectory.')] [Alias('IPv4Address','IPv6Address')] [string]$IPAddress,  [Parameter(Mandatory=$false, ParameterSetName="ComputerNameOULevel", HelpMessage='Enter a number between 0 and 8. 0 is your current OU Container.')] [Parameter(Mandatory=$false, ParameterSetName="IPAddressOULevel", HelpMessage='Enter a number between 0 and 8. 0 is your current OU Container.')] [ValidateRange(0,8)] [int]$OULevel = 0,  [Parameter(ParameterSetName="ComputerNameComputerOU")] [Parameter(ParameterSetName="IPAddressComputerOU")] [Switch]$ComputerOU,  [Parameter(ParameterSetName="ComputerNameAllCompany")] [Parameter(ParameterSetName="IPAddressAllCompany")] [Switch]$AllCompany,  [Parameter()] [Switch]$List ) 

Da ich nicht wollte, dass diese drei Parameter miteinander verwendet werden, mussten sie zu ihren eigenen Parametersätzen gehören. Wenn Sie also versuchen, einen Parameter zu verwenden, werden die anderen nicht als Option angezeigt. Dies erleichtert und vereinfacht den Skriptprozess selbst. Anstatt zuzulassen, dass das Skript selbst Benutzereingaben berücksichtigt, werden diese Optionen durch die Powershell-Parametersätze entfernt.

Der $ List-Parameter hat keinen Parametersatznamen, da dieser Parameter in jedem Szenario verfügbar sein soll.

0
beatcracker

Hier ist der Code, der die Funktionen DynamicParameters und New-DynamicParameter verwendet, um sie zu erstellen:

# DotSource New-DynamicParameter function . '.\New-DynamicParameter.ps1'  function Get-CompanyADComputer { [CmdletBinding(DefaultParametersetName = 'ComputerName_AllCompany')] Param() DynamicParam { $BaseParameters = @( @{ Name = 'ComputerName' Type = [string] Mandatory = $true ParameterSetName = 'ComputerName' HelpMessage = 'Enter a computer name to search in ActiveDirectory.' Alias = 'Computer', 'CN' }, @{ Name = 'IPAddress' Type = [System.Net.IPAddress] Mandatory = $true ParameterSetName = 'IPAddress' HelpMessage = 'Enter an IP address to search in ActiveDirectory.' Alias = 'IPv4Address', 'IPv6Address' } )  $MutuallyExclusiveParameters = @( @{ Name = 'OULevel' HelpMessage = 'Enter a number between 0 and 8. 0 is your current OU Container.' ValidateRange = 0, 8 Type = [int] } @{ Name = 'ComputerOU' Type = [switch] }, @{ Name = 'AllCompany' Type = [switch] } )  $AllParamSetParameters = @( @{ Name = 'List' Type = [switch] } )  $DynamicParameters = ( # For each base parameter $BaseParameters | ForEach-Object { # Iterate over mutually exclusive parameters $MutuallyExclusiveParameters | ForEach-Object -Begin {$BaseParam = $_} -Process { # Generate new ParameterSet name: Base parameter ParameterSetName + mutually exclusive parameter name $CurrParamSetName = '_' -f $BaseParam.ParameterSetName, $_.Name  # Clone base parameter, so we modify copy of it $NewBaseParam = $BaseParam.Clone() # Set its ParameterSetName $NewBaseParam.ParameterSetName = $CurrParamSetName  # Clone mutually exclusive parameter, so we modify copy of it $NewMEParam = $_.Clone() # Set its ParameterSetName $NewMEParam.ParameterSetName = $CurrParamSetName  # Output new base parameter and new mutually exclusive parameter $NewBaseParam $NewMEParam } } ) + $AllParamSetParameters # Add parameters that should exist in all parameter sets  # Create and output new dynamic parameters $DynamicParameters | ForEach-Object | New-DynamicParameter }  Process { # Dynamic parameters don't have corresponding variables created, # you need to call New-DynamicParameter with CreateVariables switch to fix that. New-DynamicParameter -CreateVariables -BoundParameters $PSBoundParameters  # Show all parameters $PSBoundParameters | Format-Table -AutoSize -HideTableHeaders | Out-String  <#  Your code here...  #> }  }