如何在PowerShell 2中实现指定多文件夹的单Zip压缩?
PowerShell 2.0兼容的FolderName1系列文件夹压缩脚本
没问题,我帮你调整出PowerShell 2.0可用的压缩方案。因为PowerShell 2.0没有内置的Compress-Archive cmdlet,我们可以借助Windows系统自带的Shell COM对象来完成压缩——它能完美处理嵌套文件夹和文件,而且不需要额外安装工具。
完整脚本
# 获取用户输入的基础文件夹名 $baseName = Read-Host 'Enter the folder NAME' # 构建所有需要压缩的目标文件夹路径 $foldersToCompress = @( Join-Path -Path 'C:\Prod\' -ChildPath $baseName Join-Path -Path 'C:\Prod\' -ChildPath ($baseName + 'xx') Join-Path -Path 'C:\Prod\' -ChildPath ($baseName + 'yy') Join-Path -Path 'C:\Prod\' -ChildPath ($baseName + 'zz') ) # 预检查:确认文件夹存在,不存在则给出警告 foreach ($folder in $foldersToCompress) { if (-not (Test-Path -Path $folder -PathType Container)) { Write-Warning "文件夹未找到: $folder - 将跳过该项目" } } # 定义输出Zip文件路径(示例格式:C:\Prod\FolderName1_20240520.zip) $zipOutputPath = Join-Path -Path 'C:\Prod\' -ChildPath ("{0}_{1:yyyyMMdd}.zip" -f $baseName, (Get-Date)) # 先清理已存在的同名Zip文件(如果有) if (Test-Path -Path $zipOutputPath) { Remove-Item -Path $zipOutputPath -Force } # 创建空Zip文件并写入头部标识(Shell对象需要这个标识才能识别为有效Zip容器) $null = New-Item -Path $zipOutputPath -ItemType File -Force [System.IO.File]::WriteAllBytes($zipOutputPath, [byte[]]@(80, 75, 5, 6) + [byte[]]::CreateInstance([byte], 18)) # 初始化Shell.Application COM对象 $shell = New-Object -ComObject Shell.Application $zipContainer = $shell.NameSpace((Resolve-Path -Path $zipOutputPath).Path) # 逐个将文件夹添加到Zip中 foreach ($folder in $foldersToCompress) { if (Test-Path -Path $folder -PathType Container) { Write-Host "正在添加 $folder 到压缩包..." # 0x14 = 0x10(不显示进度窗口) + 0x4(递归复制子文件夹) $zipContainer.CopyHere((Resolve-Path -Path $folder).Path, 0x14) # 等待压缩完成(异步操作需要延迟,可根据文件夹大小调整时长) Start-Sleep -Seconds 2 while ($zipContainer.Items().Count -eq 0) { Start-Sleep -Milliseconds 500 } } } Write-Host "压缩完成!Zip文件已保存到: $zipOutputPath"
关键细节说明
- Shell.Application对象:这是Windows原生组件,PowerShell 2.0完全兼容,无需额外依赖。
- 空Zip文件初始化:必须写入
[byte[]]@(80, 75, 5, 6)这组Zip文件的头部标识,否则Shell对象无法识别该文件为有效的压缩容器。 - CopyHere参数:
0x14参数组合实现了后台递归压缩,不会弹出进度窗口,适合脚本自动化场景。 - 异步等待逻辑:
CopyHere是异步执行的,所以需要加等待步骤,避免因操作未完成导致Zip文件损坏。如果你的文件夹很大,可以适当延长Start-Sleep的时间。
内容的提问来源于stack exchange,提问作者silverbackbg




