2

我面临着使用 PowerShell 在文件系统上移动和复制某些项目的问题。

我通过实验知道,即使使用 PowerShell v3, cmdletCopy-ItemMove-Item无法Delete-Item 正确处理像联结和符号链接这样的重解析点,并且如果与 switch 一起使用可能会导致灾难-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' }

提出了另一个问题,因为$oriand$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)
}

有更好的方法吗?

我很确定是否有办法以正确的方式使用 PowerShell cmdlet 处理重解析点,但我更想知道如何加入和过滤两个或多个“PowerShell 集合”

我总结观察到,目前,PowerShell 的这个特性,“多态数组”,对我来说似乎没有这么大的好处。

谢谢阅读。

4

2 回答 2

1

只需添加一个过滤器即可丢弃空值。你在正确的轨道上。

$items = @(@($ori) + @($dri)) | ? { $_ -ne $null }

于 2012-12-24T05:00:45.790 回答
0

我在 Powershell 3 上已经有一段时间了,但据我所知,这也应该在 2.0 中工作:

$items = @($ori, $dri) | %{ $_ } | ? { $_.Attributes -match 'ReparsePoint' }

基本上%{ $_ }是一个 foreach 循环,它通过迭代内部数组并将每个内部元素 ( $_) 传递到管道中来展开内部数组。Null 将自动从管道中排除。

于 2013-02-18T07:29:54.653 回答