Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Краткое описание
Автоматическая переменная, содержащая текущий объект в объекте конвейера.
Длинное описание
PowerShell включает две автоматические переменные и "$PSItem", $_ которые ссылаются на текущий объект в конвейере.
$PSItem Был добавлен в PowerShell в попытке указать более четкое значение имени переменной. Однако на практике чаще всего используется форма $_.
Хотя эта статья используется $PSItem в примерах, $PSItem их можно заменить $_ на каждый пример.
$_ — предпочтительное использование.
Существует несколько распространенных вариантов использования:$PSItem
- В скриптовом блоке для параметра процесса командлета
ForEach-Object - В блоке скрипта FilterScript для параметра командлета
Where-Object - В интегрированных методах ForEach и Where
- с параметрами скрипта с задержкой привязки
-
switchУсловные значения инструкции и связанные операторы - В блоке
processинструкций функции - В определении
filter - В блоке скрипта атрибута ValidateScript
- В блоке инструкций a
catch
Остальная часть этой статьи содержит примеры использования $PSItem для этих вариантов использования.
параметр ForEach-Object Process
Командлет 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
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 содержит верхние регистры текущего объекта. Затем возвращается только блок скрипта метода 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 определении блока, но не в beginend определениях блоков. Если ссылаются $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 в списке инструкций определения фильтра.
При использовании $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 : 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.
At line:1 char:24
+ Add-EvenNumber -Number 1, 2
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Add-EvenNumber],
ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,
Add-EvenNumber
В этом примере блок скрипта для атрибута 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.
Изменение значения $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