Usando os Conjuntos de Parâmetros Avançados em uma Função com Múltiplos Comutadores Exclusivos

2

Estou usando o Powershell 4.0.

Eu estou tentando gravar um cmdlet e neste cmdlet eu gostaria de usar os conjuntos de parâmetros avançados para ter certas opções disponíveis com base em quais parâmetros são / são escolhidos. Esta função em particular será essencialmente e eventualmente o Get-ADComputer, mas com o -SearchBase pré-programado para certas opções.

Eu tenho 6 parâmetros no total. 2 são strings ($ ComputerName ou $ IpAddress), 1 é um inteiro ($ OULevel) e 3 opções ($ ComputerOU, $ AllCompany, $ List).

Eu tenho um conjunto de parâmetros para ComputerName e IPAddress, eu gostaria que o usuário pudesse inserir um ou outro - acho que descobri que é bem simples. No entanto, eu gostaria que $ OULevel, $ ComputerOU e $ AllCompany tivessem um significado exclusivo, se um fosse usado, o outro não deveria poder ser usado. $ List deve permanecer disponível em cada cenário.

Eu tentei diferentes variações dos conjuntos de parâmetros sem sucesso. É assim que meu script se parece agora, com alguns recortes:

    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
    )

Se você está curioso, nosso anúncio é organizado por local, categoria (computador, usuário, grupos, contatos etc.) e, em seguida, fica mais detalhado em cada UO abaixo. Esse script detecta a UO do seu computador e inicia a pesquisa lá. A finalidade de $ OULevel é se o usuário especificar um número diferente, a pesquisa será iniciada em uma unidade organizacional diferente e, em seguida, pesquisar recursivamente. O objetivo do $ ComputerOU é fazer com que sua pesquisa vá para a OU padrão de computadores, em vez de todo o domínio ou sua localização. O objetivo de $ AllCompany é ter o padrão de pesquisa para todo o domínio em vez de qualquer outra opção ou UO.

Qualquer orientação é apreciada. Eu não consigo pegar o jeito dessa sem que meu roteiro fique todo complicado.

    
por cyborgcommando0 19.06.2015 / 01:38

2 respostas

2

Eu pedi a Don Jones o guru do powershell em outro fórum e ele me deu a informação que eu precisava. Ele me explicou isso dizendo:

If I'm understanding the question, then you basically have to factor out all the possible combinations. Remember that a param can belong to 1+ param sets. So, you might have a set with Computername and OULevel, Computername and ComputerOU, and Computername and AllCompany. That's three. Then those three again for IPAddress. I know it's not elegant, but look at the help for Where-Object – not elegant, either, by far. List would then not belong to a set, which means it would belong to all.

Isso me colocou no caminho certo. Então, na verdade, acabei mudando a maneira como meu cmdlet funcionava, então minha resposta foi reformulada, mas agora que entendi o que fazer, atualizarei meu exemplo existente para que possa ser consistente e, espero, ajudar.

    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
)

Como eu não queria que esses 3 parâmetros fossem usados um com o outro, eles precisavam pertencer aos seus próprios Conjuntos de Parâmetros, então quando você tentar usar um parâmetro, os outros não aparecerão como uma opção. Isso ajuda muito e simplifica o próprio processo de script. Em vez de permitir que o próprio script contabilize a entrada do usuário, os conjuntos de parâmetros do Powershell eliminam essas opções.

O parâmetro $ List não tem um nome de conjunto de parâmetros porque eu quero que esse parâmetro esteja disponível em todos os cenários.

    
por 23.06.2015 / 18:53
0

Aqui está o código que usa DynamicParameters e New-DynamicParameter para criá-los:

# 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 = '{0}_{1}' -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-Object -TypeName psobject -Property $_} | 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...

        #>
    }

}
    
por 14.07.2015 / 15:38