В отличие от других оболочек, PowerShell позволяет передавать команды и выражения как аргументы команды просто путем , заключая их в скобки (...)
.
При вызове PowerShell команд (командлетов, сценариев, функций) выходные данные передаются в качестве аргумента как есть, в качестве исходного типа вывода.
Следовательно, Theo *Решение 1015 * из комментария является правильным:
Write-Host -BackgroundColor Black -ForegroundColor Green `
("{0, -35}: {1}" -f "SUCCESS: Updated user $current/$total", $userCN)
То есть выполняется выражение -f
внутри (...)
, и его вывод - в данном случае, одна строка - передается как позиционныйаргумент Write-Host
(неявно привязывается к параметру -Object
).
Обратите внимание, что вам нужно не потребность, $(...)
, подвыражение оператор , в данном случае.
Фактически, в некоторых случаях $(...)
может непреднамеренно изменить ваш аргумент, поскольку он разворачивает одноэлементные массивы :
# Pass a single-element array to a script block (which acts like a function).
# (...) preserves the array as-is.
PS> & { param($array) $array.GetType().Name } -array ([array] 1)
Object[] # OK - single-element array was passed as-is
# $(...) unwraps it.
PS> & { param($array) $array.GetType().Name } -array $([array] 1)
Int32 # !! Single-element array was unwrapped.
Основное использование $(...)
:
расширение вывода из выражений или команд внутри расширяемые строки (интерполяция строк)
Для отправки вывода составные операторы , такие как foreach (...) { ... }
и if (...) { ... }
непосредственно через конвейер, после сбора выходных данных ;однако вы можете альтернативно обернуть такие операторы в . { ... }
(для выполнения в той же области) или . { ... }
(для выполнения в дочерней области), чтобы получить обычное поведение streaming (по одномупередача одного) в конвейере.
- Шаг назад: учитывая, что вы уже можете использовать составные операторы в качестве выражений в присваиваниях переменных -например,
$evenNums = foreach ($num in 1..3) { $num * 2 }
- и выражения обычно принимаются в качестве первого сегмента конвейера - например, 'hi' | Write-Host -Fore Yellow
- удивительно, что в настоящее время это не работает с составными операторами; эта проблема GitHub спрашивает, можно ли снять это ограничение.
В контексте передачи аргументов в команды :
Используйте $(...)
, оператор подвыражения только если выхотите передать выходные данные из нескольких команд или (одной или нескольких) составных операторов в качестве аргумента и / или , если выходные данные оказываются single object, вы хотите, чтобы этот объект использовался как есть, или, если это будет одноэлементный массив (перечисляемый), вы хотите, чтобы он был unrarapped (передать сам элемент, а не массив.
- Конечно, если вы создаете аргумент string ,
$(...)
может быть полезен внутри этой строки для строкиинтерполяция - например, Write-Host "1 + 1 = $(1 + 1)"
Использовать @(...)
, оператор подвыражения массива только если вы хотите передать выводиз нескольких команд в качестве аргумента и / или вы хотите гарантировать , что вывод становится массивом ;то есть выходные данные возвращаются в виде (обычного PowerShell) массива типа [object[]]
, даже если он содержит только один объект. В некотором смысле это обратное поведения $(...)
в случае вывода одного объекта: оно гарантирует, что вывод одного объекта тоже станет массивом.