powershell - PSCustomObject 数组和 ValueFromPipelineByPropertyName

标签 powershell powershell-3.0

背景:我有一些我想更容易访问的位置。我不想 mklink,因为那样的话可能会将路径保存为链接路径并在以后失败。

建议的解决方案:创建一些 PSDrive。从一个静态的哈希表数组开始,以便将来可以轻松地导入/导出/过滤它们。

准备步骤:

# Clear out existing drives, empty error stack
Get-PSDrive -name "*-test-*" | Remove-PSDrive 
$Error.Clear()

失败的解决方案 1:创建带有参数 KVPs 的哈希数组
@(
    @{ Name='hasharray-test-control'; Root='C:\Windows\Temp' },
    @{ Name='hasharray-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem

令人困惑的错误“输入对象不能绑定(bind)到命令的任何参数......”

失败的解决方案 2:Web-grokking 显示项目必须是 PSCustomObject,而不是哈希
@(
    [PSCustomObject]@{ Name='array-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='array-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem

第二项失败
New-PSDrive : Cannot bind parameter 'Name' to the target. 
Exception setting "Name": 
    "Cannot process argument because the value of argument "value" is null.

失败的解决方案 3:好的,也许 powershell 将数组作为一个大 blob 传递,使其隐含
[PSCustomObject]@{ Name='implicitarray-test-control'; Root='C:\Windows\Temp' },
[PSCustomObject]@{ Name='implicitarray-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" } |
    New-PSDrive -PSProvider FileSystem

第二项失败,错误相同

失败的解决方案 4:插入中间变量
$TestDrives = @(
    [PSCustomObject]@{ Name='foreach-test-control'; Root='C:\Windows\Temp' }
    [PSCustomObject]@{ Name='foreach-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) 
$TestDrives | New-PSDrive -PSProvider FileSystem

第二项失败,错误相同

失败的解决方案 5:插入选择以提取属性
@(
    [PSCustomObject]@{ Name='select-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='select-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | Select Name, Root | New-PSDrive -PSProvider FileSystem

第二项失败,错误相同

失败的解决方案 6:否?好的,我将添加一个 foreach 来强制每个项目解决
$TestDrives = @(
    [PSCustomObject]@{ Name='foreachpipe-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='foreachpipe-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) 
$TestDrives | ForEach-Object { $_ } | New-PSDrive -PSProvider FileSystem 

第二项失败,错误相同

失败的解决方案 7:仍然没有?很好,在 foreach 中明确选择每个属性
@(
    [PSCustomObject]@{ Name='foreachselect-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='foreachselect-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | ForEach-Object { $_ | Select Name, Root } | New-PSDrive -PSProvider FileSystem

第二项失败,错误相同

为了更好地衡量,让我们只尝试静态值:
@(
    [PSCustomObject]@{ Name='foreachstatic-test-control'; Root='C:\Windows\Temp' }
    [PSCustomObject]@{ Name='foreachstatic-test-control-2'; Root='C:\Windows\Temp' }
) | New-PSDrive -PSProvider FileSystem

第二项失败,错误相同

额外说明:
  • 我尝试了在数组声明中使用和不使用逗号,结果是相同的
  • 我还尝试了以下作为第二项,结果相同
  • [PSCustomObject]@{ Name='test-interp'; Root="$HOME\Temp" }
  • [PSCustomObject]@{ Name='test-interp-command'; Root="$($HOME)\Temp" }
  • [PSCustomObject]@{ Name='test-format'; Root=('{0}\Temp' -f $HOME) }
  • [PSCustomObject]@{ Name='test-format-resolve'; Root=$('{0}\Temp' -f $HOME) }
  • 设置 $tRoot外部哈希,并使用 [PSCustomObject]@{ Name='test-format-resolve'; Root=$tRoot }

  • 工作解决方案:哇,我无语了......让我们在所有事情上强制一个 foreach
    @(
        [PSCustomObject]@{ Name='foreach-test-control'; Root='C:\Windows\Temp' },
        [PSCustomObject]@{ Name='foreach-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
    ) | ForEach-Object { $_ | New-PSDrive -PSProvider FileSystem }
    

    现在它可以工作了,但感觉不对,因为它已经在准备中了。

    现在,问题:
    为什么在这种情况下我必须显式 ForEach-Object 而不是能够使用管道,当 New-PSDrive支持ValueFromPipelineByPropertyName两个NameRoot ?

    为什么每个数组中的第一项工作,而所有后续项目都失败了?

    最佳答案

    您在 New-PSDrive 的实现中遇到了一个错误。

    Name/Root/PSDrive 参数的属性 setter 未正确编写以支持管道中的多个对象。

    关于powershell - PSCustomObject 数组和 ValueFromPipelineByPropertyName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20385515/

    相关文章:

    windows - 在 cmd 中将 powershell 脚本作为自定义命令运行

    powershell - 在 Windows Powershell 中获取小时和分钟

    powershell - 如何使用Powershell脚本中的参数调用可执行文件

    powershell - TPM 和私钥保护

    powershell - 从Powershell启动Elevated CMD.exe

    Powershell Copy-Item 远程计算机复制到错误位置

    powershell - 接收作业输出到文件

    search - 使用 NTFS 备用数据流标记脚本是否可以接受?

    正则表达式将组与 PowerShell 中的字符串匹配

    Powershell - 分批循环遍历对象 3