如何在PowerShell管道函数外部访问管道变量$_?
$_的访问限制与可行方案 你没遗漏任何关键技巧——在PowerShell中,必须借助Foreach-Object(或其简写%)才能在管道中访问当前对象变量$_,直接在管道后接普通命令并引用$_的写法(如Get-ChildItem | Write-Host $_.FullName)无法生效,原因如下:
PowerShell的管道执行逻辑是将前一命令的输出逐个传递给后一命令,但$_仅在脚本块({})或支持延迟绑定的cmdlet参数中才会被绑定为当前管道对象。直接执行Write-Host $_.FullName时,PowerShell会在启动Write-Host前就尝试解析$_.FullName,此时$_未绑定任何管道对象,自然无法获取有效属性值。
可行的替代写法
使用
Foreach-Object(或简写%)
这是最通用的解决方案,通过脚本块包裹操作,让$_正确绑定到当前管道对象:Get-ChildItem | Foreach-Object { Write-Host $_.FullName } # 简写形式 Get-ChildItem | % { Write-Host $_.FullName }利用支持延迟绑定的cmdlet参数
部分cmdlet的参数设计支持直接引用$_,无需包裹脚本块,例如Copy-Item的-Destination参数:# 直接引用$_,无需Foreach-Object Get-ChildItem *.txt | Copy-Item -Destination "C:\Backup\$($_.Name)"注意:这种特性是特定cmdlet的参数实现,并非所有命令都支持,
Write-Host这类基础命令不具备该能力。通过
Select-Object提取属性(针对输出场景)
如果仅需输出对象属性,可先用Select-Object -ExpandProperty提取属性值,再传递给后续命令:Get-ChildItem | Select-Object -ExpandProperty FullName | Write-Host
总结
除了少数支持延迟绑定的cmdlet参数场景外,通用的管道内访问$_的方式必须依赖Foreach-Object或其等效写法,没有其他通用的绕过技巧。
内容的提问来源于stack exchange,提问作者Neil Barnwell

