You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何PowerShell的METHOD 01中不能用Write-Output {$_.FullName}而必须用ForEach-Object?

PowerShell管道用法疑问解答

一、为什么METHOD 01不能直接用Write-Output {$_.FullName}?

在PowerShell里:

  • $_(自动变量)只在特定的管道处理上下文里生效,比如ForEach-Object的脚本块、Where-Object的脚本块,或是支持管道输入的函数/cmdlet的参数绑定逻辑中。
  • Write-Output的作用是输出指定对象,如果你直接传{$_.FullName},它只会把这个未执行的脚本块对象原样输出,不会遍历管道里的每个目录对象、绑定$_并执行脚本块获取FullName。
  • ForEach-Object的核心作用就是遍历管道中的每个输入对象,将当前对象绑定到$_,执行你提供的脚本块后把结果输出到下一段管道——这就是必须借助它的原因。

你可以自己验证:如果写Get-ChildItem ... | Write-Output {$_.FullName},输出的会是System.Management.Automation.ScriptBlock类型的对象,根本不是目录路径。

二、用METHOD 01的管道方式运行自定义函数

方式1:在ForEach-Object脚本块中调用函数

如果你的自定义函数是针对单个对象处理的,直接在ForEach-Object里把$_作为参数传入即可:

# 自定义示例函数:接收目录对象,返回其全路径的大写形式
function Get-UpperCaseFullName {
    param(
        [Parameter(Mandatory)]
        [System.IO.DirectoryInfo]$Dir
    )
    return $Dir.FullName.ToUpper()
}

# 用METHOD 01的管道方式调用
Get-ChildItem -Path 'D:\' -Directory -Depth 0 | 
ForEach-Object { Get-UpperCaseFullName -Dir $_ } | 
Sort-Object

方式2:让函数支持管道输入(更优雅的写法)

给函数的参数添加[Parameter(ValueFromPipeline)]属性,让它能直接接收管道传来的对象,这样就不用ForEach-Object,直接接在管道后面即可:

# 支持管道输入的自定义函数
function Get-UpperCaseFullName {
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [System.IO.DirectoryInfo]$Dir
    )
    process {
        # 必须用process块,否则只会处理最后一个管道对象
        $Dir.FullName.ToUpper()
    }
}

# 直接通过管道调用
Get-ChildItem -Path 'D:\' -Directory -Depth 0 | 
Get-UpperCaseFullName | 
Sort-Object

注意:支持管道输入的函数必须包含process块,这样才能逐个处理管道中的每个对象;如果没有process块,函数会等所有管道对象接收完毕后,只处理最后一个。


内容的提问来源于stack exchange,提问作者LiquidMetal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:36:42