我遇到了使用PowerShell在文件系统上移动和复制某些项目的问题。
我通过实验了解到,即使使用PowerShell v3,cmdlet Copy-Item
,Move-Item
和Delete-Item
也无法正确处理重新分析点,如符号链接,如果与开关-Recurse
一起使用,可能会导致灾难。
我想阻止这种情况。我必须每次运行两个或更多文件夹,所以我想到这样的事情。
$Strings = @{ ... }
$ori = Get-ChildItem $OriginPath -Recurse
$dri = Get-ChildItem $DestinationPath -Recurse
$items = ($ori + $dri) | where { $_.Attributes -match 'ReparsePoint' }
if ($items.Length -gt 0)
{
Write-Verbose ($Strings.LogExistingReparsePoint -f $items.Length)
$items | foreach { Write-Verbose " $($_.FullName)" }
throw ($Strings.ErrorExistingReparsePoint -f $items.Length)
}
这不起作用,因为$ori
和$dri
也可以是单个项而不是数组:op-Addition
将失败。改为
$items = @(@($ori) + @($dri)) | where { $_.Attributes -match 'ReparsePoint' }
带来了另一个问题,因为$ori
和$dri
也可能是$null
,我可以用包含$null
的数组结束。将连接结果重新连接到Where-Object
时,我可以再次使用$null
,单个项目或数组。
唯一显而易见的解决方案是遵循更复杂的代码
$items = $()
if ($ori -ne $null) { $items += @($ori) }
if ($dri -ne $null) { $items += @($dri) }
$items = $items | where { $_.Attributes -match 'ReparsePoint' }
if ($items -ne $null)
{
Write-Verbose ($Strings.LogExistingReparsePoint -f @($items).Length)
$items | foreach { Write-Verbose " $($_.FullName)" }
throw ($Strings.ErrorExistingReparsePoint -f @($items).Length)
}
有一些更好的approch?
我很有兴趣确定是否有办法以正确的方式处理PowerShell cmdlet的重新分析点,但我更有兴趣知道如何加入和过滤两个或更多“PowerShell集合”
我总结观察到,目前,PowerShell的这个“多态数组”的特性对我来说并没有这么大的好处。
感谢阅读。
答案 0 :(得分:1)
只需添加一个过滤器即可抛出空值。你走在正确的轨道上。
$items = @(@($ori) + @($dri)) | ? { $_ -ne $null }
答案 1 :(得分:0)
我已经在Powershell 3上工作了一段时间,但从我能说的这个也应该在2.0中工作:
$items = @($ori, $dri) | %{ $_ } | ? { $_.Attributes -match 'ReparsePoint' }
基本上%{ $_ }
是一个foreach循环,它通过迭代内部数组并将每个内部元素($_
)传递到管道中来展开内部数组。 Null将自动从管道中排除。