about_PSItem
Краткое описание
Автоматическая переменная, содержащая текущий объект в объекте конвейера.
Подробное описание
PowerShell включает $PSItem
переменную и его псевдоним, $_
как автоматические переменные в скриптблоках, обрабатывающих текущий объект, например в конвейере. Эта статья используется $PSItem
в примерах, но $PSItem
может быть заменена $_
на каждый пример.
Эту переменную можно использовать в командах, выполняющих действие для каждого объекта в конвейере.
Существует несколько распространенных вариантов использования:$PSItem
- в файле scriptblock для параметра Process командлета
ForEach-Object
- в блоке скрипта для параметра FilterScript командлета
Where-Object
- в встроенных методах ForEach и Where
- с параметрами скрипта с задержкой привязки
switch
в условных значениях инструкции и связанных скриптахprocess
в блоке функции- в определении
filter
- в блоке скрипта атрибута ValidateScript
- в блоке скрипта подстановки оператора
-replace
Остальная часть этой статьи содержит примеры использования $PSItem
для этих вариантов использования.
Процесс forEach-Object
Командлет ForEach-Object предназначен для работы с объектами в конвейере, выполняя блок скрипта параметра Process один раз для каждого объекта в конвейере.
Вы можете использовать $PSItem
в блоке скриптов параметра Process, но не в блоках скриптов начального или конечного параметра. Если вы ссылаетесь $PSItem
на скрипты начального или конечного параметров, значение заключается $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
Where-Object FilterScript
Командлет 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 содержит верхние регистры текущего объекта. Затем возвращается только B
блок скрипта метода Where.
Параметры скрипта с задержкой привязки
Блоки скриптов с задержкой привязки позволяют определять $PSItem
параметры для конвейерного командлета перед его выполнением.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Переключение блоков скриптов инструкций
В инструкциях 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*
аргументов для атрибута Параметра .
Использование атрибута параметра и привязки командлета для расширенных функций делает реализацию более явной и прогнозируемой, чем обработка текущего объекта для получения необходимых значений.
Одним из хороших способов использования расширенных $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
в списке инструкций определения фильтра.
При использовании $PSItem
в filter
определении значение является текущим объектом, если фильтр вызывается в конвейере и в противном случае $null
.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
В этом примере Test-IsEven
фильтр выводит, $true
если текущий объект является четным числом, а $false
если это не так.
Блок скрипта атрибута ValidateScript
Вы можете использовать $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
добавляет допустимые входные числа и возвращает общее значение.
Блок скрипта подстановки оператора -replace
Начиная с PowerShell 6, можно использовать $PSItem
при вызове оператора замены и определении подстановки скрипта. При этом значение $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
В этом примере блок скрипта подстановки заменяет исходную строку даты форматом по умолчанию для текущего языка и региональных параметров путем приведения значения к дате.
См. также
PowerShell