使用 Compress-Archive 压缩与 Powershell 多线程的多个文件夹

Using Compress-Archive to compress multiple folders multithreadded with Powershell

每天我都需要创建以下内容的档案

C:.
└───1.Jan
    ├───20000
    │       img1.bmp
    │       img2.bmp
    │       img3.bmp
    │
    ├───20001
    │       img1.bmp
    │       img2.bmp
    │       img3.bmp
    │
    ├───20002
    │       img1.bmp
    │       img2.bmp
    │       img3.bmp
    │
    ├───20003
    │       img1.bmp
    │       img2.bmp
    │       img3.bmp
    │
    ├───20004
    │       img1.bmp
    │       img2.bmp
    │       img3.bmp
    │
    ├───20005
    │        img1.bmp
    │        img2.bmp
    │        img3.bmp
    │
    └───Entered

我目前使用脚本一次创建一个 zip 文件,但是有时我可以压缩 200 多个文件夹,而且它们的大小不同,所以我想让这个工作多线程。

function Zip-Folders([String] $FolderPath) {
if ($FolderPath -eq '') {
    return
} 
else {
    $FolderNames = Get-ChildItem -Path $FolderPath -Name -Directory -Exclude Enter*
        foreach ($i in $FolderNames) {
            $TempPath = "$FolderPath$i"
            $TempFileName = "$i Photos"
            if (-Not(Get-ChildItem -Path $TempPath | Where-Object {$_.Name -like '*.zip'})) {
                Write-Host "[$TempPath] has been compressed to [$TempFileName]."
                Compress-Archive -Path $tempPath\* -DestinationPath $tempPath$TempFileName
            }
            Else {
                Write-Host "[$i] has already been compressed."
            }
        }
}
}

代码通过文件夹浏览器对话框请求文件夹。

如果有人可以帮助我编写代码或指出我可以找到相关信息的方向,我是 PowerShell 的初学者,但已经完成了一些编程工作。

如果需要任何其他信息,请告诉我。

这是使用 Runspace 的方法,使用 -Threshold 参数取决于您要同时压缩的文件夹数量。

如评论所述,如果您有能力在您的环境中安装模块,强烈建议使用 ThreadJob Module

function Zip-Folders {
    [cmdletbinding()]
    param(
        [ValidateScript({ Test-Path $_ -PathType Container })]
        [Parameter(Mandatory)]
        [String] $FolderPath,

        [int] $Threshold = 10
    )

    begin {
        $RunspacePool = [runspacefactory]::CreateRunspacePool(1, $Threshold)
        $RunspacePool.Open()
        $subFolders = Get-ChildItem -Path $FolderPath -Directory -Exclude Enter*
    }
    
    process {
        try {
            $runspaces = foreach ($folder in $subFolders) {
                $instance = [powershell]::Create().AddScript({
                    param($thisFolder)

                    $fileName = "{0} Photos.zip" -f $thisFolder.Name
                    $absolutePath = $thisFolder.FullName
                    $zipPath = Join-Path $absolutePath -ChildPath $fileName

                    if(-not (Get-ChildItem -Path $absolutePath -Filter *.zip)) {
                        Compress-Archive -Path $absolutePath\* -DestinationPath $zipPath
                        return "[$absolutePath] has been compressed to [$zipPath]."
                    }

                    "[$absolutePath] has already been compressed."
                }).AddParameter('thisFolder', $folder)

                $instance.RunspacePool = $RunspacePool

                [pscustomobject]@{
                    Instance = $instance
                    Handle   = $instance.BeginInvoke()
                }
            }

            foreach($r in $runspaces) {
                $r.Instance.EndInvoke($r.Handle)
                $r.Instance.ForEach('Dispose')
            }
        }
        catch {
            $PSCmdlet.WriteError($_)
        }
        finally {
            $runspaces.ForEach('Clear')
            $RunspacePool.ForEach('Dispose')
        }
    }
}