Команда Powershell Pass переключается как переменная - PullRequest
2 голосов
/ 06 марта 2019

Я пытаюсь создать скрипт, который обрабатывает копии папок и файлов.Мне нужно передать ключи '-recures -container', если это папка, а ничего не файл.Есть ли способ создать переменную, которая будет содержать '-recurse -container' и передать ее команде следующим образом:

$copy_args = '-Recurse -container '
Copy-Item $tmptmp\$file -Destination \\$server\d$\$tmpprd\ $copy_args -Force

спасибо Мор

Ответы [ 2 ]

6 голосов
/ 06 марта 2019

Лучший способ сделать это с помощью техники под названием splatting .Вы создаете хеш-таблицу параметров, которые хотите передать, и затем используете @ с именем переменной (вместо $), чтобы указать, что вы хотите разделить его на требуемые параметры командлетов:

$copy_args = @{
     Recurse = $true
     Container = $true
}

Copy-Item $tmptmp\$file -Destination \\$server\d$\$tmpprd\ @copy_args -Force
1 голос
/ 06 марта 2019

Полезный ответ Марка Врагга рекомендует брызги , что дает вам наибольшую гибкость .

В сторону:

  • Установка -Recurse достаточна в вашем случае, поскольку подразумевает -Container
  • Фактически, вы даже можете безоговорочно использовать -Recurse , потому что он просто игнорируется , если исходный путь - файл .

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

Учитывая, что синтаксис - -SomeSwitch:$boolVar или -SomeSwitch:(<boolExpression>) (необязательно с пробелами после :) - неочевиден, позвольте мне продемонстрировать:

Использование логической переменной :

# The source path.
$sourcePath = $tmptmp\$file

# Set the Boolean value that will turn the -Recurse switch on / off.
$doRecurse = Test-Path -PathType Container $sourcePath # $true if $sourcePath is a dir.

# Use -Recurse:$doRecurse
Copy-Item -Recurse:$doRecurse $sourcePath -Destination \\$server\d$\$tmpprd\ -Force

В качестве альтернативы можно использовать логическое выражение :

Copy-Item -Recurse:(Test-Path -PathType Container $sourcePath) $sourcePath -Destination \\$server\d$\$tmpprd\ -Force

Обратите внимание, что : для отделения имени параметра от аргумента является необходимостью в случае параметра switch , чтобы указать, что аргумент предназначен для переключателя (которые обычно не принимают аргумент), а не являются отдельным позиционным аргументом.

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


Технически, командлет или расширенная функция могут различать переключатель , опущенный , и переключатель с аргументом $false с помощью автоматической переменной $PSBoundParameters, которая содержит словарь всех явно переданные параметры.

В случае общего -Confirm параметра это различие используется намеренно - что составляет нетипично .

Вот простая демонстрация:

# Sample advanced function that supports -Confirm with a medium impact level.
function foo { 
  [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Medium')]
  param() 

  if ($PSCmdlet.ShouldProcess('dummy')) { 'do it' }  
}

# Invocation *with -Confirm* prompts unconditionally.
foo -Confirm  # ditto with -Confirm:$true

# Invocation *without -Confirm*:
# Whether you'll be prompted depends on the value of the $ConfirmPreference
# variable: If the value is 'Medium' or 'Low', you'll be prompted.
foo

# Invocation with *-Confirm:$false* NEVER prompts,
# irrespective of the $ConfirmPreference value.
foo -Confirm:$false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...