简体   繁体   English

使用 Powershell 复制保留文件夹结构的文件子集

[英]Copy subset of files keeping folder structure using Powershell

Looking for some Powershell help with a copying challenge.寻找一些 Powershell 帮助解决复制挑战。

I need to copy all MS Office files from a fairly large NAS (over 4 million of them and a little over 5tb) to another drive, retaining the existing folder structure where a file is copied.我需要将所有 MS Office 文件从一个相当大的 NAS(超过 400 万个,略超过 5tb)复制到另一个驱动器,保留复制文件的现有文件夹结构。

I have a text file of all the common Office file types (about 40 of them) - extns.txt我有一个包含所有常见 Office 文件类型(大约 40 种)的文本文件 - extns.txt

At this stage, being a good StackExchanger, I'd post the script I've got so far, but I've spent best part of a day on this and, not only is what I've got embarrassingly awful, I suspect that even the basic algorithm is wrong.在这个阶段,作为一个优秀的 StackExchanger,我会发布到目前为止的脚本,但我已经花了一天中最好的时间在这上面,而且,不仅我得到的东西非常糟糕,我怀疑即使是基本算法也是错误的。

I started to gci the entire tree on the old NAS, once for each file type Then I thought it would be better to traverse once and compare every file to the list of valid types.我开始对旧NAS上的整个树进行gci,每种文件类型一次然后我认为最好遍历一次并将每个文件与有效类型列表进行比较。 Then I got into a complete mess about rebuilding the folder structure.然后我对重建文件夹结构一团糟。 I started by splitting on '\' and iterating through the path then wasted an hour of searching because I thought I remembered reading about a simple way to duplicate a path if it doesn't exist.我首先在“\”上拆分并遍历路径,然后浪费了一个小时的搜索,因为我想我记得读过有关复制路径的简单方法(如果它不存在)。

Another alternative is that I dump out a 4 million line text file of all the files (with full path) I want to copy (this is easy as I imported the entire structure into SQL Server to analyse what was there) and use that as a list of sources另一种选择是我转储出我想要复制的所有文件(带有完整路径)的 400 万行文本文件(这很容易,因为我将整个结构导入 SQL 服务器以分析那里的内容)并将其用作来源清单

I'm not expecting a 'please write the codez for me' answer but some pointers/thoughts on the best way to approach this would be appreciated.我并不期待“请为我编写 codez”的答案,但对于解决此问题的最佳方法的一些指示/想法将不胜感激。

I'm not sure if this is the best approach, but the below script is a passable solution to the least.我不确定这是否是最好的方法,但下面的脚本至少是一个可以接受的解决方案。

$sourceRootPath = "D:\Source"
$DestFolderPath = "E:\Dest"

$extensions = Get-Content "D:\extns.txt"

# Prefix "*." to items in $extensions if it doesn't already have it
$extensions = $extensions -replace "^\*.|^","*."

$copiedItemsList = New-Object System.Collections.ArrayList

foreach ( $ext in $extensions ) {
    $copiedItems = Copy-Item -Path $sourceRootPath -Filter $ext -Destination $DestFolderPath -Container -Recurse -PassThru
    $copiedItems | % { $copiedItemsList.Add($_) | Out-Null }
}

$copiedItemsList = $copiedItemsList | select -Unique

# Remove Empty 'Deletable' folders that get created while maintaining the folder structure with Copy-Item cmdlet's Container switch
While ( $DeletableFolders = $copiedItemsList | ? { ((Test-Path $_) -and $_.PSIsContainer -eq $true -and ((gci $_ | select -first 1).Count -eq 0)) } ) {
    $DeletableFolders | Remove-Item -Confirm:$false
}

The Copy-Item 's -Container switch is going to preserve the folder structure for us. Copy-Item-Container开关将为我们保留文件夹结构。 However, we may encounter empty folders with this approach.但是,使用这种方法我们可能会遇到空文件夹。

So, I'm using an arraylist named $copiedItemsList to add the copied objects into, which I will later use to determine empty 'Deletable' folders which are then removed at the end of the script.因此,我使用名为$copiedItemsListarraylist将复制的对象添加到其中,稍后我将使用它来确定空的“可删除”文件夹,然后在脚本末尾删除这些文件夹。

Hope this helps!希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM