背景:我有一些我想更容易访问的位置。我不想 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
两个Name
和 Root
?为什么每个数组中的第一项工作,而所有后续项目都失败了?
最佳答案
您在 New-PSDrive 的实现中遇到了一个错误。
Name/Root/PSDrive 参数的属性 setter 未正确编写以支持管道中的多个对象。
关于powershell - PSCustomObject 数组和 ValueFromPipelineByPropertyName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20385515/