Как пройти ввод чтения хоста, прежде чем будет предложено? - PullRequest
0 голосов
/ 16 мая 2019

предположим, у меня есть этот командлет

[CmdletBinding(DefaultParameterSetName='View')]
Param(
    [Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
    [Switch]$ChangeOne,

    [Parameter(ParameterSetName='ChangeAll', Mandatory=$true)]
    [Switch]$ChangeAll,

    [Parameter(ParameterSetName='View', Mandatory=$false)]
    [Switch]$View
)

Теперь у меня есть несколько условных выражений следующим образом:

if ($ChangeOne)
{
    $input = (Read-Host -prompt "Database")

    if (!$input) 
    { 
        Write-Host "`r`n`You MUST enter a DB Name! 1 more try...`r`n" -foregroundcolor cyan -backgroundcolor black

        $input = (Read-Host -prompt "Database")

        if (!$input) 
        { 
            Write-Host "`r`nNo DB Name entered...exiting script`r`n" -foregroundcolor magenta -backgroundcolor black    
            Write-host "----------------------------END of Script------------------------------"
            exit 1
        }
    }
}

Это прекрасно работает, за исключением того, что сейчас я пытаюсь вызвать этот скрипт с помощью WinRM изTFS и TFS не будут взаимодействовать с Read-Host ... вместо этого он будет принимать только прямые аргументы, такие как:

script1.ps1 -ChangeOne databaseinput1

У меня вопрос, как я могу разрешить ввод Read-Host в командной строке без запроса?Я просто пытаюсь придумать, как TFS будет принимать предопределенный ввод для узла чтения

Я бы подумал о чем-то подобном, но это не сработает, потому что param требует, чтобы он был на вершинесценарий ...

if ($ChangeOne)
{
    param([string]$input)

    if (!$input) 
    { 
        Write-Host "`r`n`You MUST enter a DB Name! 1 more try...`r`n" -foregroundcolor cyan -backgroundcolor black

        $input = param([string]$input)

        if (!$input) 
        { 
            Write-Host "`r`nNo DB Name entered...exiting script`r`n" -foregroundcolor magenta -backgroundcolor black    
            Write-host "----------------------------END of Script------------------------------"
            exit 1
        }
    }
}

Ответы [ 2 ]

1 голос
/ 16 мая 2019

Вы можете сделать это, используя наборы параметров и проверку.

Это будет выглядеть примерно так:

[CmdletBinding(DefaultParameterSetName='View')]
Param(


    [Parameter(ParameterSetName='ChangeAll', Mandatory=$false)]
    [Switch]$ChangeAll,

    [Parameter(ParameterSetName='View', Mandatory=$false)]
    [Switch]$View,

    [Parameter(ParameterSetName='ChangeOne', Mandatory=$false)]
    [Switch]$ChangeOne,

    [Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
    [ValidateScript({![string]::IsNullOrEmpty($_.Trim())})]
    [string]$Database = ${if ($ChangeOne)`{Read-Host -Prompt "Database"`} else `{""`}}
)

С другой стороны, если вы знаете сценарии, которые ожидаете увидеть, проверка может выглядеть следующим образом:

[ValidateSet("Database1","Database2","Database3")]

Проверка выполнит проверку того, что ввод является приемлемым, коммутатор выполнит требование параметра базы данных, и если вы попытаетесь передать параметр базы данных без флага -ChangeOne, это также приведет к прерыванию сценария с ошибка.

1 голос
/ 16 мая 2019

Чтобы добавить DynamicParam, вам нужно пошагово построить объект.Я использую шаблон ниже, чтобы создать мой. Основные биты, которые нужно отметить, это $ParameterName, [String], которые вы можете изменить при необходимости.

function MyFunction
{
    [CmdletBinding(DefaultParameterSetName='View')]
    Param(
        [Parameter(ParameterSetName='ChangeOne', Mandatory=$true)]
        [Switch]$ChangeOne,

        [Parameter(ParameterSetName='ChangeAll', Mandatory=$true)]
        [Switch]$ChangeAll,

        [Parameter(ParameterSetName='View', Mandatory=$false)]
        [Switch]$View
    )

    DynamicParam
    {
        if($ChangeOne)
        {
            #OutputObject
            $ParameterName = 'DatabaseInput'
            $RuntimeParameterDictionary = 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
            $AttributeCollection.Add($ParameterAttribute)
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
        }
    }
}

Если вы хотите проверить входные данные по некоторым предопределенным значениям,Вы можете создать массив (который может быть жестко закодирован или динамически сгенерирован).

Обратите внимание, что были добавлены следующие строки

 $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
 $AttributeCollection.Add($ValidateSetAttribute)

и

$ValidationArray = 1..9

Полный блок DynamicParam находится ниже

   DynamicParam
    {
        if($ChangeOne)
        {
            #Array of values to validate against
            $ValidationArray = 1..9

            #OutputObject
            $ParameterName = 'DatabaseInput'
            $RuntimeParameterDictionary = 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
            $AttributeCollection.Add($ParameterAttribute)
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
            $AttributeCollection.Add($ValidateSetAttribute)
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
        }
    }

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

Возможно, эти "шаблоны" можно немного почистить, поэтому здесь могут быть и лучшие примеры.

Редактировать

Вы можете вручную указать позиции для аргументов, нам нужно установить атрибут позиции для нашего параметра с помощью $ParameterAttribute.Position = 1.Я также установил для наших переключателей положение 0, я бы предложил вручную установить положение всех параметров для спокойствия.

Я также не упомянул ранее, что вам нужно получить доступ к значениям через$PsBoundParameters.В этом примере я назначил их переменным в блоке begin.Это облегчает обращение к ним по всей функции, но вы можете просто использовать $PsBoundParameters["DatabaseInput"].

function MyFunction
{
    [CmdletBinding(DefaultParameterSetName='View',PositionalBinding=$false)]
    Param(
        [Parameter(ParameterSetName='ChangeOne', Mandatory=$true, Position=0)]
        [Switch]$ChangeOne,

        [Parameter(ParameterSetName='ChangeAll', Mandatory=$true, Position=0)]
        [Switch]$ChangeAll,

        [Parameter(ParameterSetName='View', Mandatory=$false, Position=0)]
        [Switch]$View
    )

    DynamicParam
    {
        if($ChangeOne)
        {
            #Array of values to validate against
            $ValidationArray = 1..9

            #OutputObject
            $ParameterName = 'DatabaseInput'
            $RuntimeParameterDictionary = 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)


            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
            $AttributeCollection.Add($ValidateSetAttribute)

            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
        }
    }

    begin
    {
        $ChangeOne = $PsBoundParameters["ChangeOne"]
        $ChangeAll = $PsBoundParameters["ChangeAll"]
        $View = $PsBoundParameters["ChangeAll"]
        $DatabaseInput = $PsBoundParameters["DatabaseInput"]
    }

    process
    {
        if($databaseInput)
        {
            return $databaseInput
        }
        else
        {
            return $False
        }
    }
}

Итак, запуск:

MyFunction -ChangeAll
MyFunction -ChangeOne -DatabaseInput 3
MyFunction -ChangeOne 6

Дает:

False
3
6

Редактировать 2

Чтобы создать больше параметров, вам нужно добавить больше объектов в $RuntimeParameterDictionary

function MyFunction
{
    [CmdletBinding(DefaultParameterSetName='View',PositionalBinding=$false)]
    Param(
        [Parameter(ParameterSetName='ChangeOne', Mandatory=$true, Position=0)]
        [Switch]$ChangeOne,

        [Parameter(ParameterSetName='ChangeAll', Mandatory=$true, Position=0)]
        [Switch]$ChangeAll,

        [Parameter(ParameterSetName='View', Mandatory=$false, Position=0)]
        [Switch]$View
    )

    DynamicParam
    {
        if($ChangeOne)
        {


            #Create a dictionary of parameters
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

            ####Parameter 1
            $ParameterName = "databaseInput"

            #Array of values to validate against
            $ValidationArray = 1..9

            #Create parameter attributes
            $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)

            #Add validation (omit if not needed)
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
            $AttributeCollection.Add($ValidateSetAttribute)

            #Create the parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)

            #Add the parameter to the dictionary
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)

            ###Parameter 2
            $ParameterName = "Server"

            #Array of values to validate against
            $ValidationArray = "One","Two","Three"

            #Create parameter attributes
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $true
            $ParameterAttribute.Position = 2
            $AttributeCollection.Add($ParameterAttribute)

            #Add validation (omit if not needed)
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidationArray)
            $AttributeCollection.Add($ValidateSetAttribute)

            #Create the parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)

            #Add the parameter to the dictionary
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)

            #Return parameters
            Return $RuntimeParameterDictionary
        }
    }

    begin
    {
        $ChangeOne = $PsBoundParameters["ChangeOne"]
        $ChangeAll = $PsBoundParameters["ChangeAll"]
        $View = $PsBoundParameters["ChangeAll"]
        $DatabaseInput = $PsBoundParameters["DatabaseInput"]
        $Server = $PsBoundParameters["Server"]
    }

    process
    {
        if($databaseInput)
        {
            Return $DatabaseInput,$Server
        }
        else
        {
            Return $False
        }
    }
}

Итак, запустите следующее:

MyFunction -ChangeOne -databaseInput 3 -Server Two
MyFunction -ChangeOne 7 Two

Возвращает:

3
Two
7
Two

Ссылки: https://blogs.technet.microsoft.com/poshchap/2017/09/01/scripting-tips-tricks-dynamic-parameters/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...