Невозможно изменить аргумент функции в Powershell - PullRequest
1 голос
/ 10 ноября 2011

У меня есть функция, которая похожа на это:

function A-Function{
  [CmdletBinding(SupportsShouldProcess=$True)]
param (
    [Parameter(Position=0, HelpMessage="A Test string", Mandatory=$true)]
    [string]$Path,

    [Parameter(Position=1, HelpMessage="The list of file names to download.", ValueFromPipeline=$True)]
    [string[]]$testVar,

    [Parameter(HelpMessage= "The username")]
    [string]$User,

    [Parameter(HelpMessage= "The password")]
    [string]$Password,

    [Parameter(HelpMessage= "The credentials used.")]
    [Net.NetworkCredential]$Credential = (New-Object Net.NetworkCredential("Anonymous", ""))
)

Begin {         
    $Path = "TEST_" + $Path

    if ($User) {
        if ($Password) {
            $Credential = New-Object Net.NetworkCredential($User, $Password)
        }
    }
}

Process {
    $Path
    $Credential
}

End {

}

}

Если я запускаю "A-Function test -User test -Password -test", я получаю вывод:

TEST_test

Имя пользователя Пароль Пароль SecurePassword
-------- -------- -------------- ------
test test System.Security.SecureString

Это то, что я ожидал получить.Однако, если я запущу эту команду вместо:

"Тест" |A-Function test -User test -Password -test

Вместо этого я получаю этот вывод:

TEST_test

Имя пользователя Пароль SecurePassword Домен
-------- -------- -------------- ------
Anonymous System.Security.SecureString

Другими словамиво втором сценарии он не изменил значение аргумента Credential в разделе Begin, но в первом он изменился.Я не понимаю, почему это так, кто-то может это объяснить?

С уважением

Ответы [ 2 ]

3 голосов
/ 11 ноября 2011

Если вы сделаете

trace-command parameterbinding {"Test" | A-Function test -User test -Password test} -pshost

, вы увидите, что $ credential, поскольку он не передается в качестве аргумента функции, он связывается со значением по умолчанию каждый раз во время process.Path, с другой стороны, привязывается только один раз, поскольку вы передаете его функции, и, следовательно, изменения, которые вы делаете в начале, доступны в процессе.

Это определенно ошибка / что-то не совсем оптимальное, так какэто не воспроизводится в Powershell v3.В v3 вы получаете желаемый результат проверки учетных данных, а не анонимных.

Пока вы можете это исправить, конечно, используя локальную переменную в начале или определяя существующие с помощью $script:Path и т. Д .:

function A-Function{
  [CmdletBinding(SupportsShouldProcess=$True)]
param (
    [Parameter(Position=0, HelpMessage="A Test string", Mandatory=$true)]
    [string]$Path,

    [Parameter(Position=1, HelpMessage="The list of file names to download.", ValueFromPipeline=$True)]
    [string[]]$testVar,

    [Parameter(HelpMessage= "The username")]
    [string]$User,

    [Parameter(HelpMessage= "The password")]
    [string]$Password,

    [Parameter(HelpMessage= "The credentials used.")]
    [Net.NetworkCredential]$Credential = (New-Object Net.NetworkCredential("Anonymous", ""))
)

Begin {         
    $script:Path = "TEST_" + $Path

    if ($User) {
        if ($Password) {
            $script:Credential = New-Object Net.NetworkCredential($User, $Password)
        }
    }
}

Process {
    $script:Path
    $script:Credential
}

End {

}
}

"Test" | A-Function test -User test -Password test
1 голос
/ 10 ноября 2011

Да, меня это укусило. Параметры функции сбрасываются при каждой итерации блока процесса. Просто установите локальную переменную в своем блоке Begin и затем используйте эту локальную переменную в блоке Process вместо использования переменной параметра.

Edit:

Я должен признаться, что я не очень внимательно смотрел на ваш пример кода, поскольку сразу же обнаружил проблему по комбинации заголовка вашего вопроса и того факта, что вы устанавливали $ Path в блоке Begin. Глядя на вашу функцию немного сложнее, я удивляюсь, почему у вас есть блок Process, когда вы не обрабатываете входные данные конвейера.

Насколько я помню, изменения, которые вы вносите в параметры функции в блоке Begin, сохранятся на первой итерации блока Process. Они будут сброшены только на последующих итерациях (или, возможно, в конце первой итерации).

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