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

PowerShell 7.4中同时使用ValueFromPipeline与ValueFromPipelineByPropertyName的问题

解决PowerShell函数同时支持管道字符串与结构化对象输入的问题

问题分析

你遇到的核心问题有两个:

  1. 管道输入的数组未展开:测试输入中('c:\temp\songB.mp3', 'c:\temp\songC.mp3')是作为单个数组对象传入管道的,而非两个独立的字符串元素,导致函数一次接收整个数组而非逐个处理。
  2. 参数绑定与输入类型判断逻辑错误:同时启用ValueFromPipeline和ValueFromPipelineByPropertyName时,若输入是数组,$path会被赋值为整个数组;若输入是带匹配属性的对象,直接判断类型为非字符串后取Fullname的逻辑,无法覆盖数组内的字符串元素。

正确实现方式

以下函数可同时支持管道传入单个/多个字符串路径、带FullName(或别名fullname)属性的结构化对象,以及两种类型的混合输入:

function Set-FooBarPlayer {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('Fullname')]
        $Path
    )

    process {
        # 处理集合类型输入(如数组),逐个展开元素处理
        if ($Path -is [System.Collections.IEnumerable] -and $Path -isnot [string]) {
            foreach ($item in $Path) {
                $item | Set-FooBarPlayer
            }
            return
        }

        # 提取路径:存在FullName属性则取属性值,否则直接返回输入值
        if ($Path.PSObject.Properties['FullName']) {
            $Path.FullName
        } else {
            $Path
        }
    }
}

测试验证

使用你提供的输入(函数会自动处理数组展开):

[pscustomobject]@{fullname = 'c:\temp\songA.mp3' ; length = '00:03:30:070'}, ('c:\temp\songB.mp3', 'c:\temp\songC.mp3') | Set-FooBarPlayer

输出结果完全符合预期:

c:\temp\songA.mp3
c:\temp\songB.mp3
c:\temp\songC.mp3

关键逻辑说明

  1. 集合展开:通过判断输入是否为非字符串的可枚举对象,递归调用函数处理每个元素,确保数组内的每个路径都被单独解析。
  2. 安全提取属性:使用PSObject.Properties检查对象是否包含FullName属性,避免直接访问属性导致的空值错误,同时兼容字符串直接返回的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:22:37