Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Краткое описание
Автоматическая переменная, содержащая текущий объект в объекте конвейера.
Длинное описание
PowerShell включает две автоматические переменные и "$PSItem", $_ которые ссылаются на текущий объект в конвейере.
$PSItem Был добавлен в PowerShell в попытке указать более четкое значение имени переменной. Однако на практике чаще всего используется форма $_.
Хотя эта статья используется $PSItem в примерах, $PSItem их можно заменить $_ на каждый пример.
$_ — предпочтительное использование.
Существует несколько распространенных вариантов использования для $PSItem:
- В скриптовом блоке для параметра процесса командлета
ForEach-Object - В блоке скрипта FilterScript для параметра командлета
Where-Object - В интегрированных методах ForEach и Where
- с параметрами блоков скрипта с задержкой привязки
-
switchУсловные значения инструкции и связанные операторы - В блоке
processинструкций функции - В определении
filter - В скриптовом блоке атрибута ValidateScript
- В блоке инструкций a
catch - В блоке кода подстановки оператора
-replace
Остальная часть этой статьи содержит примеры использования $PSItem для этих вариантов использования.
параметр ForEach-Object Process
Командлет ForEach-Object предназначен для работы с объектами в конвейере, выполняя блок кода параметра Process для каждого объекта в конвейере.
Вы можете использовать $PSItem в параметрических скриптоблоках Begin или End, значение равно $null, поскольку эти скриптоблоки не работают с каждым объектом в конвейере.
$parameters = @{
Begin = { Write-Host "PSItem in Begin is: $PSItem" }
Process = {
Write-Host "PSItem in Process is: $PSItem"
$PSItem + 1
}
End = { Write-Host "PSItem in End is: $PSItem" }
}
$result = 1, 2, 3 | ForEach-Object @parameters
Write-Host "Result is: $result"
PSItem in Begin is:
PSItem in Process is: 1
PSItem in Process is: 2
PSItem in Process is: 3
PSItem in End is:
Result is: 2 3 4
FilterScript Where-Object
Командлет Where-Object предназначен для фильтрации объектов в конвейере.
Вы можете использовать $PSItem в блоке скрипта параметра FilterScript, который выполняется один раз для каждого входного объекта в конвейере.
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
В этом примере FilterScript проверяет, является ли текущий объект четным, фильтруя нечетные значения, и возвращает только 2 из исходного списка.
Методы ForEach и Where
Методы ForEach и Where для массивов принимают скриптблок в качестве входного параметра. Для доступа к текущему объекту можно использовать $PSItem в этих скриптах.
@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B
В этом примере блок скрипта метода ForEach преобразует текущий объект в верхний регистр. Затем блок скрипта метода Where возвращает только B.
Блоки скриптов с задержкой привязки
Блоки скриптов с задержкой привязки предоставляют возможность использовать $PSItem для задания параметров конвейерного командлета перед его выполнением.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Инструкции Switch
В инструкции switchможно использовать $PSItem как в сценариях действий, так и в сценариях условий инструкций.
$numbers = 1, 2, 3
switch ($numbers) {
{ ($PSItem % 2) -eq 0 } { "$PSItem is even" }
default { "$PSItem is odd" }
}
1 is odd
2 is even
3 is odd
В этом примере блок инструкций условия проверяет, является ли текущий объект даже. Если это даже, связанный оператор действия блокирует вывод сообщения, указывающее, что текущий объект даже.
Блок инструкции default действия для условия выводит сообщение, указывающее, что текущий объект нечетен.
Блоки инструкций процесса функции
При определении функции можно использовать $PSItem в определении блока process, но не в определениях блоков begin или end. Если вы ссылаетесь на $PSItem в блоках begin или end, значение будет $null, поскольку эти блоки не обрабатывают каждый объект в конвейере.
При использовании $PSItem в process определении блока инструкций значение является текущим объектом, если функция вызывается в конвейере и в противном случае $null.
function Add-One {
process { $PSItem + 1 }
}
1, 2, 3 | Add-One
2
3
4
Совет
Хотя вы можете использовать $PSItem в расширенных функциях , мало причин делать это. Если вы планируете получать входные данные из конвейера, рекомендуется определить параметры с помощью ValueFromPipeline атрибута ValueFromPipelineByPropertyName или аргументов.
Использование параметра , атрибута и связывания командлетов для сложных функций делает реализацию более явной и предсказуемой, чем обработка текущего объекта для получения необходимых значений.
Одним из хороших способов использования $PSItem в расширенных функциях является проверка текущего объекта для отладки или ведения журнала при наличии нескольких параметров, которые принимают входные данные из конвейера.
function Write-JsonLog {
[CmdletBinding()]
param(
[Parameter(ValueFromPipelineByPropertyName)]
[string]$Message
)
begin {
$entries = @()
}
process {
$entries += [pscustomobject]@{
Message = $Message
TimeStamp = [datetime]::Now
}
if ($PSItem) {
$props = $PSItem | ConvertTo-Json
$number = $entries.Length
Write-Verbose "Input object $number is:`n$props"
}
}
end {
ConvertTo-Json -InputObject $entries
}
}
В этом примере функция выводит массив объектов JSON с сообщением и меткой времени. При вызове в конвейере используется свойство Message текущего объекта для каждой записи. Он также записывает представление JSON текущего объекта в подробный поток, чтобы увидеть фактические входные данные по сравнению с выходными журналами.
$Items = @(
[pscustomobject]@{
Name = 'First Item'
Message = 'A simple note'
}
[pscustomobject]@{
Name = 'Item with extra properties'
Message = 'Missing message, has info instead'
Info = 'Some metadata'
Source = 'Where this came from'
}
[pscustomobject]@{
Name = 'Last Item'
Message = 'This also gets logged'
}
)
$Items | Write-JsonLog -Verbose
VERBOSE: Input object 1 is:
{
"Name": "First Item",
"Message": "A simple note"
}
VERBOSE: Input object 2 is:
{
"Name": "Item with extra properties",
"Message": "Missing message, has info instead",
"Info": "Some metadata",
"Source": "Where this came from"
}
VERBOSE: Input object 3 is:
{
"Name": "Last Item",
"Message": "This also gets logged"
}
[
{
"Message": "A simple note",
"TimeStamp": "\/Date(1670344068257)\/"
},
{
"Message": "Missing message, has info instead",
"TimeStamp": "\/Date(1670344068259)\/"
},
{
"Message": "This also gets logged",
"TimeStamp": "\/Date(1670344068261)\/"
}
]
Определения фильтров
Вы можете использовать
При использовании $PSItem в определении filter, значение является текущим объектом, если фильтр вызывается в рамках процесса, а в противном случае - $null.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
В этом примере фильтр Test-IsEven выводит $true, если текущий объект является четным числом и $false, если это не так.
Атрибут ValidateScript ScriptBlock
Вы можете использовать $PSItem в блоке скриптов атрибута ValidateScript.
При использовании с ValidateScript$PSItem является значением объекта, который проверяется в данный момент. Если переменная или значение параметра является массивом, блок скрипта вызывается один раз для каждого объекта в массиве с $PSItem в качестве текущего объекта.
function Add-EvenNumber {
param(
[ValidateScript({ 0 -eq ($PSItem % 2) })]
[int[]]$Number
)
begin {
[int]$total = 0
}
process {
foreach ($n in $Number) {
$total += $n
}
}
end {
$total
}
}
Add-EvenNumber -Number 2, 4, 6
Add-EvenNumber -Number 1, 2
12
Add-EvenNumber:
Line |
24 | Add-EvenNumber -Number 1, 2
| ~~~~
| Cannot validate argument on parameter 'Number'. The
" 0 -eq ($PSItem % 2) " validation script for the argument
with value "1" did not return a result of True. Determine
why the validation script failed, and then try the command
again.
В этом примере блок скрипта атрибута ValidateScript выполняется для каждого значения, переданного параметру Number, и возникает ошибка, если какое-либо значение не является четным.
Функция Add-EvenNumber добавляет допустимые входные номера и возвращает общее значение.
Блок инструкций catch
В блоке catch инструкций $PSItem содержит текущую ошибку. Объект имеет тип ErrorRecord.
try { NonsenseString }
catch {
Write-Host "An error occurred:"
Write-Host $PSItem
}
Выполнение этого скрипта возвращает следующий результат:
An error occurred:
The term 'NonsenseString' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
Дополнительные примеры см. в разделе Доступ к сведениям об исключении в about_Try_Catch_Finally.
Блок -replace скрипта подстановки оператора
Начиная с PowerShell 6, можно использовать $PSItem при вызове оператора -replace и определения скрипта подстановки. При этом значение $PSItem является значением текущего совпадения.
$datePattern = '\d{4}-\d{2}-\d{2}'
'Today is 1999-12-31' -replace $datePattern, { [datetime]$PSItem.Value }
Today is 12/31/1999 00:00:00
В этом примере блок скрипта замены заменяет оригинальную строку даты форматом по умолчанию для текущей культуры путем приведения значения в тип datetime.
Изменение значения $PSItem
Вы можете изменить значение $PSItem , назначив ему новое значение. Однако это может изменить ожидаемое поведение любого кода, который зависит $PSItemот .
Рассмотрим следующий пример. Как правило, switch оператор обрабатывает все значения в массиве $names. Так как значение изменено внутри блока инструкций $PSItem действия, switch оператор обрабатывает только первое значение.
$names = 'Alice', 'Charlie'
switch ($names) {
Alice { "$PSItem says 'Hello!'"; $PSItem = 'Bob' }
Bob { "$PSItem says 'Goodbye.'"; $PSItem = 'Charlie'; break }
Charlie { "$PSItem says 'How are you?'" }
}
switch Когда оператор оценивает первое значение, Aliceон соответствует первому условию и выполняет связанный блок инструкций действия. Внутри этого блока значение $PSItem изменяется Bobна , которое также влияет на оценку инструкции switch .
Alice says 'Hello!'
Bob says 'Goodbye.'
Следует избегать изменения значения $PSItem.
См. также
PowerShell