背景:我有一些我希望更容易访问的位置。我不想mklink,因为这样可能会将路径保存为链接路径并稍后失败。
建议的解决方案:创建一些PSDrives。从静态的哈希表数组开始,以便将来可以轻松导入/导出/过滤它们。
准备步骤:
# Clear out existing drives, empty error stack
Get-PSDrive -name "*-test-*" | Remove-PSDrive
$Error.Clear()
解决方案1失败:使用参数KVP
创建哈希数组@(
@{ Name='hasharray-test-control'; Root='C:\Windows\Temp' },
@{ Name='hasharray-test-interp-brace'; Root="${ENV:SystemRoot}\Temp" }
) | New-PSDrive -PSProvider FileSystem
混淆错误"输入对象无法绑定到命令的任何参数..."
解决方案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 }
工作解决方案:哇,我说不出话来......让我们围绕着所有事情强行推进
@(
[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 }
现在它有效,但感觉不对,因为它已经在管道上了。
现在,问题是:
当New-PSDrive
支持ValueFromPipelineByPropertyName
和Name
的{{1}}时,为什么我必须在这种情况下显式地使用ForEach-Object而不是能够使用管道?
为什么每个数组中的第一项都有效,而所有后续项目都失败了?
答案 0 :(得分:3)
你在实施New-PSDrive时遇到了一个错误。
Name / Root / PSDrive参数的属性设置器未正确编写以支持管道中的多个对象。
答案 1 :(得分:2)
这是New-PSDrive
cmdlet的问题,因为atm。它一次只支持一个对象。 Remove-PSDrive
确实支持数组输入,这表明它也应该包含在New-PSDrive
中(就像PS-cmdlet应该可以工作一样)。要验证它是否是cmdlet的错误,您可以运行以下命令来查看它是如何正确绑定第一个对象的属性的,而它在第二个对象的开头取消。
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
输出部分:
#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]