PowerShell使用Compress-Archive归档文件夹时的结构异常及失效问题求助
解决PowerShell Compress-Archive保留指定目录结构并排除文件夹的问题
问题分析
你遇到的核心问题是:使用Copy-Item -PassThru配合Compress-Archive时,要么无法递归包含子文件夹,要么丢失子文件夹结构;同时出现依赖“先压缩单个文件夹再删除重试”的奇怪现象,这是因为旧版Windows Server的PowerShell中,Compress-Archive对管道传递的文件对象处理存在逻辑缺陷,无法正确保留相对目录结构。
正确实现方案
方案1:直接获取目标子项并压缩(无需临时目录)
通过Get-ChildItem获取源目录下需要保留的直接子项(排除目标文件夹),再传递给Compress-Archive,能完美保留目录结构:
# 获取C:\Temp\Folder下所有直接子项,排除Folder2 $targetItems = Get-ChildItem -Path "C:\Temp\Folder" -Exclude "Folder2" # 压缩这些子项到目标zip文件,-Force覆盖已存在的归档 Compress-Archive -Path $targetItems.FullName -DestinationPath "C:\Temp1\archive.zip" -Force
生成的归档结构完全符合需求:
log1.log log1_1.txt Folder1\ log2.log log2_1.log
方案2:通过临时目录中转(适合处理被占用的文件)
如果部分文件被其他进程占用,Copy-Item -Force可强制复制(前提是文件未被排他锁占用),先复制出完整目录结构再压缩,彻底避免管道传递的结构丢失问题:
# 创建临时目录(自动覆盖已存在的同名目录) $tempDir = New-Item -Path "C:\Temp\Temp_Archive_Temp" -ItemType Directory -Force # 复制源目录内容到临时目录,排除Folder2并递归复制 Copy-Item -Path "C:\Temp\Folder\*" -Destination $tempDir.FullName -Exclude "Folder2" -Recurse -Force # 压缩临时目录下的所有内容 Compress-Archive -Path "$($tempDir.FullName)\*" -DestinationPath "C:\Temp1\archive.zip" -Force # 删除临时目录 Remove-Item $tempDir.FullName -Recurse -Force
为什么之前的方法失效?
- 无
-Recurse的Copy-Item只会复制根目录文件,不会递归处理子文件夹,所以归档中缺少Folder1; - 添加
-Recurse后,Copy-Item -PassThru会把所有子文件夹内的文件单独传递给管道,Compress-Archive会将这些文件直接放到归档根目录,丢失父文件夹结构; - 你遇到的“先压缩单个文件夹再重试”能生效,是因为旧版PowerShell的
Compress-Archive存在缓存或逻辑漏洞,偶然保留了目录结构,但这不是可靠方案,重命名文件夹后缓存失效,问题就会重现。
内容的提问来源于stack exchange,提问作者Norman
相关产品推荐
相关产品推荐

