使用Powershell将新文件从外部HD复制到桌面

使用Powershell将新文件从外部HD复制到桌面,powershell,synchronization,copy,compareobject,Powershell,Synchronization,Copy,Compareobject,感谢您阅读我的帖子和您的建议:) 情况是,我在我的桌面上内置了一个HD,在那里我收集了很多年的文件。所以有一天我做了一个外部高清的备份,然后我去旅行,继续从我的手机上收集照片等等 从那时起,我改变了我桌面上的文件夹结构很多,所以我不能比较文件夹/文件1 很明显,我的目标是将外部硬盘上的所有新文件复制到我的内部硬盘上,所有文件都放在一个名为“2SORT”的文件夹中 我发现了一个更快的compare object版本(参见注释),但结果并不正确,它会复制很多已经存在的文件 下面是我在Powershe

感谢您阅读我的帖子和您的建议:) 情况是,我在我的桌面上内置了一个HD,在那里我收集了很多年的文件。所以有一天我做了一个外部高清的备份,然后我去旅行,继续从我的手机上收集照片等等

从那时起,我改变了我桌面上的文件夹结构很多,所以我不能比较文件夹/文件1

很明显,我的目标是将外部硬盘上的所有新文件复制到我的内部硬盘上,所有文件都放在一个名为“2SORT”的文件夹中

我发现了一个更快的compare object版本(参见注释),但结果并不正确,它会复制很多已经存在的文件

下面是我在Powershell中得到的:

cls
$path\u desktop='C:\Files\Media\Bilder'
$path_external='E:\Bilder'
$path\u destination='C:\Files\Media\Bilder\2SORT'
$ref=Get ChildItem-path$path\u desktop-Recurse-File
$com=Get ChildItem-path$path\u external-Recurse-File
$file_Diffs=Compare Object-ReferenceObject$ref-DifferenceObject$com |其中{$\ SideIndicator-eq'=>'}
$file_diff|
弗雷奇{
$copyParams=@{}
$copyParams.Path=$\u.InputObject.FullName
$copyParams.Destination=“$path\u Destination\”+$\u.InputObject.Name
复制项@copyParams-force-PassThru |写入主机

}
如果这是您经常做的事情,我建议您使用
robocopy
进行重构。在第一次运行之后,任何后续运行都会快得多,因为
robocopy
设计用于执行这些任务。无论您使用什么工具,第一次运行都会很慢

比较对象
将比较属性值。通过在其中传递一组值,将有更多的工作要做。此外,在该函数运行时,您实际上没有移动任何文件,因此,如果取消此操作,则脚本没有移动任何内容。如果您只想比较每个中的文件名列表,并复制它们是否存在于
$ref
中,而不是
$com
,则可以限制所获得的属性,并像下面我所做的那样手动迭代/移动每个$ref中的文件名

如果要继续使用
比较对象
请查看其
-Property
参数,以限制其比较的属性数

$path_desktop = 'C:\Files\Media\Bilder'
$path_external = 'E:\Bilder'
$path_destination = 'C:\Files\Media\Bilder\2SORT'

$ref = Get-ChildItem -path $path_desktop -Recurse -File | select name, fullname
$com = Get-ChildItem -path $path_external -Recurse -File | select name, fullname

$ref | 
foreach {
    if ($_.name -in $com | select -ExpandProperty name)
        continue;

    --Copy file
}

您还可以根据需要获取其他文件属性,然后在进行比较时使用这些属性(可以“手动”或使用
compare object
并在差异上迭代)

要查看Get-ChildItem返回的属性,请将其传递到`Get-Member-Type属性中

Get-ChildItem -path $path_desktop -Recurse -File | Get-Member -Type Properties

最后,我不得不按MD5哈希值比较这些文件,因为我得到了许多重复的文件,只是“lastwritetime”不同:

cls
$path\u desktop='C:\Files\Media\Bilder'
$path\u external='C:\Files\Media\ext'
$path\u destination='C:\Files\Media\Bilder\2SORT'
$path\u intcsv='C:\Files\Media\Bilder\inthash2.csv'
$path\u extcsv='C:\Files\Media\Bilder\exthash2.csv'
$count=0
$res=@()
Get ChildItem-path$path_desktop-Recurse-File |%{
写入主机($count++)
$hash=Get FileHash$\ux.FullName-算法MD5
$res+=新对象PSObject-Property@{Hash=$Hash.Hash;FullName=$\ux.FullName}
}
$res | epcsv-路径$path|intcsv-非类型信息
$count=0
$res=@()
Get ChildItem-path$path_external-Recurse-File |%{
写入主机($count++)
$hash=Get FileHash$\ux.FullName-算法MD5
$res+=新对象PSObject-Property@{Hash=$Hash.Hash;FullName=$\ux.FullName}
}
$res | epcsv-path$path_extcsv-notype信息
$int=导入Csv$path\u intcsv
$ext=导入Csv$path\u extcsv
$IntHash=@{}
$ExtHash=@{}
$DifHash=@{}
$int | ForEach对象{
$newKey=$\u0.Hash
if(!$IntHash.ContainsKey($newKey)){
$IntHash.Add($newKey,$null)
}
}               
$ext | ForEach对象{
$newKey=$\u0.Hash
if(!$ExtHash.ContainsKey($newKey)){
$ExtHash.Add($newKey,$\ux.FullName)
}
}  
ForEach($ExtHash.Keys中的key){
如果(!$IntHash.ContainsKey($key)){
$DifHash.Add($key,$ExtHash[$key])
}    
}     
#检查文件夹是否存在
if(-not(测试路径$path_destination)){
$make=新项目-项目类型目录-路径$Path\u目标
}      
#复制文件
ForEach($DifHash.Keys中的键){
$fullname=$DifHash[$key]
复制项目$fullname-目的地$path\U目的地-强制

}
我发现了使用哈希表的Compare Object的改进版本,速度快得多,但结果毫无意义。您是否考虑过
robocopy
?将所有原始文件复制到
2SORT
,然后
robocy/mir E:\Bilder C:\files\Media\Bilder\2SORT
只会将新文件复制到
2SORT
目录。感谢Glenn,这可能是一个选项,但遗憾的是,我们谈论的文件量(100gb+)太大了!比较一些文件名不会这么难吧?:)谢谢你的回复!问题是,当我扩展属性时,我丢失了“发现”为新/不存在的文件的文件路径。。遗憾的是-in/-notin操作符不能在对象中“找到”文件名,因为它会比较所有文件名properties@silboney,我更新了答案,以使用这两个属性执行迭代/逻辑。我还添加了一点关于使用
Compare Object
通过限制它正在比较的属性来实现这一点的内容
Get-ChildItem -path $path_desktop -Recurse -File | Get-Member -Type Properties