2

Я использую Powershell 4.0.

Я пытаюсь написать командлет, и в этом командлете я хотел бы использовать расширенные наборы параметров, чтобы были доступны определенные параметры в зависимости от того, какие параметры выбраны. Эта конкретная функция по сути и в конечном итоге будет Get-ADComputer, но с -SearchBase, предварительно запрограммированным для определенных опций.

У меня всего 6 параметров. 2 - строки ($ ComputerName или $ IpAddress), 1 - целое число ($ OULevel) и 3 переключателя ($ ComputerOU, $ AllCompany, $ List).

У меня есть набор параметров для ComputerName и IPAddress, я хотел бы, чтобы пользователь мог вводить один или другой - я думаю, что я понял это довольно просто. Тем не менее, я хотел бы, чтобы $ OULevel, $ ComputerOU и $ AllCompany были исключительными, если одно используется, другое не должно использоваться. Список $ должен оставаться доступным в каждом сценарии.

Я пробовал разные варианты наборов параметров безрезультатно. Вот как сейчас выглядит мой сценарий с некоторой обрезанной спиной:

    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
    )

Если вам интересно, что наша AD организована по местоположению, затем по категории (компьютер, пользователь, группы, контакты и т.д.), А затем она становится более детальной в каждом подразделении ниже. Этот скрипт обнаруживает OU вашего компьютера и начинает поиск там. Цель $ OULevel - если пользователь указывает другое число, поиск начинается в другом OU, а затем выполняется рекурсивный поиск. Цель $ ComputerOU состоит в том, чтобы поиск выполнялся в подразделении «Компьютеры по умолчанию» вместо всего домена или вашего местоположения. Целью $ AllCompany является использование поиска по умолчанию для всего домена вместо любого другого выбора или подразделения.

Любое руководство приветствуется. Кажется, я не смогу овладеть этим без того, чтобы мой сценарий не был полностью запутанным.

2 ответа2

2

Я спросил у дона Джонса гуру powershell на другом форуме, и он дал мне информацию, которая мне была нужна. Он объяснил мне это, сказав следующее:

Если я понимаю вопрос, то вам, в принципе, нужно учесть все возможные комбинации. Помните, что параметр может принадлежать 1+ наборам параметров. Таким образом, у вас может быть набор с Computername и OULevel, Computername и ComputerOU, а также Computername и AllCompany. Это три. Затем эти три снова для IP-адреса. Я знаю, что это не элегантно, но посмотрите на помощь для Where-Object - тоже не элегантно. Список тогда не принадлежал бы набору, а это значит, что он принадлежал бы всем.

Это поставило меня на правильный путь. Поэтому я фактически изменил способ работы моего командлета, поэтому мой ответ был переработан, но теперь, когда я понимаю, что делать, я обновлю свой существующий пример, чтобы быть последовательным и, надеюсь, помочь.

    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
)

Поскольку я не хотел, чтобы эти 3 параметра использовались друг с другом, они должны принадлежать их собственным наборам параметров, поэтому при попытке использовать один параметр другие не будут отображаться в качестве опции. Это очень помогает и упрощает сам процесс написания сценариев. Вместо того чтобы позволить самому сценарию учитывать пользовательский ввод, наборы параметров Powershell исключают эти параметры.

Параметр $ List не имеет имени набора параметров, потому что я хочу, чтобы этот параметр был доступен в каждом сценарии.

0

Вот код, который использует DynamicParameters и функцию New-DynamicParameter для их создания:

# 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...

        #>
    }

}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .