首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PSCustomObject阵列与ValueFromPipelineByPropertyName

PSCustomObject阵列与ValueFromPipelineByPropertyName
EN

Stack Overflow用户
提问于 2013-12-04 20:44:17
回答 2查看 2.3K关注 0票数 4

背景:我有一些地方,我想有更方便的访问。我不想要mklink,因为有东西可能会将路径保存为链接路径,然后失败。

建议的解决方案:创建一些PSDrives。从一个静态的哈希表数组开始,这样以后就可以很容易地导入/导出/过滤它们。

准备-步骤:

代码语言:javascript
复制
# Clear out existing drives, empty error stack
Get-PSDrive -name "*-test-*" | Remove-PSDrive 
$Error.Clear()

解决方案1失败:使用参数KVPs创建散列数组

代码语言:javascript
复制
@(
    @{ Name='hasharray-test-control'; Root='C:\Windows\Temp' },
    @{ Name='hasharray-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem

“输入对象不能绑定到命令的任何参数.”

失败的解决方案2: Web显示项目必须是PSCustomObject,而不是散列。

代码语言:javascript
复制
@(
    [PSCustomObject]@{ Name='array-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='array-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem

在第二项上失败

代码语言:javascript
复制
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传递,使其隐式化

代码语言:javascript
复制
[PSCustomObject]@{ Name='implicitarray-test-control'; Root='C:\Windows\Temp' },
[PSCustomObject]@{ Name='implicitarray-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" } |
    New-PSDrive -PSProvider FileSystem

在第二项上失败,错误相同。

失败的解决方案4:插入中间变量

代码语言:javascript
复制
$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失败:插入选择以提取属性

代码语言:javascript
复制
@(
    [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来强制每个项目解析

代码语言:javascript
复制
$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中显式地选择每个属性。

代码语言:javascript
复制
@(
    [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

在第二项上失败,错误相同。

为了更好地衡量,让我们只尝试静态值:

代码语言:javascript
复制
@(
    [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 }

解决方案:哇,我说不出话来.让我们把一切都逼得头破血流吧

代码语言:javascript
复制
@(
    [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对象,而不是能够使用管道,因为New-PSDrive同时支持NameRoot

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-04 22:08:58

这是New-PSDrive cmdlet的一个问题,因为atm。它一次只支持一个对象。Remove-PSDrive确实支持数组输入,这表明它也应该包含在New-PSDrive中(就像PS应该工作的那样)。要验证它是否是cmdlet的错误,您可以运行以下命令,查看它如何正确地绑定第一个对象的属性,而它在第二个对象的开头处取消。

代码语言:javascript
复制
Trace-Command -Expression { 
@(
    [PSCustomObject]@{ Name='array-test-control'; Root='C:\Windows\Temp' },
    [PSCustomObject]@{ Name='array-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem
} -Name ParameterBinding -PSHost

产出:

代码语言:javascript
复制
#First object
 BIND PIPELINE object to parameters: [New-PSDrive]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.PSCustomObject]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [Name] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [hasharray-test-interp-brace] to parameter [Name]
DEBUG: ParameterBinding Information: 0 :         BIND arg [hasharray-test-interp-brace] to param [Name] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     Parameter [Root] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [C:\Windows\Temp] to parameter [Root]
DEBUG: ParameterBinding Information: 0 :         BIND arg [C:\Windows\Temp] to param [Root] SUCCESSFUL


#Second object
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [New-PSDrive]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.PSCustomObject]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
#It now skips right to the result(error) without trying to bind the parameters.
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Out-Default]
票数 2
EN

Stack Overflow用户

发布于 2013-12-04 21:49:27

在New的实现中,您碰到了一个bug。

名称/Root/PSDrive参数的属性设置程序没有正确地编写以支持管道中的多个对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20385515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档