如何使用PowerShell归档文件夹并排除任意层级指定子文件和子文件夹
纯PowerShell无外部依赖的目录归档(支持任意层级排除)
你之前的脚本问题根源是Compress-Archive cmdlet接收递归获取的文件集合时,会丢失原始目录的层级关系,同时自带的-Exclude参数仅对当前查询层级生效,无法匹配深层目录中的目标项。以下是直接调用.NET内置压缩类库的实现,效果完全对齐7-Zip的-x!排除逻辑:
# 可直接修改的配置项 $sourceDir = "D:\Temp\WindowsFormsApp1" # 待归档的根目录 $outputZip = "D:\Temp\WindowsFormsApp1.zip" # 压缩包输出路径 $excludeRules = @("bin", "obj", ".vs", "*.suo", "*.user") # 排除规则,支持文件名通配 # 加载.NET内置压缩程序集 Add-Type -AssemblyName System.IO.Compression.FileSystem # 清理已存在的目标压缩包 if (Test-Path $outputZip) { Remove-Item $outputZip -Force } # 初始化压缩包写入对象 $zipFileStream = [System.IO.File]::Open($outputZip, [System.IO.FileMode]::Create) $zipArchive = [System.IO.Compression.ZipArchive]::new($zipFileStream, [System.IO.Compression.ZipArchiveMode]::Create) # 递归遍历所有文件并过滤排除项 Get-ChildItem -Path $sourceDir -Recurse -Force | Where-Object { # 跳过目录项,仅处理文件 if ($_.PSIsContainer) { return $false } # 计算当前文件相对于根目录的路径 $relativePath = $_.FullName.Substring($sourceDir.Length + 1) $pathSegments = $relativePath -split '[\\/]' $matchExclude = $false # 检查是否匹配任意排除规则 foreach ($rule in $excludeRules) { # 匹配全路径通配规则 if ($relativePath -like $rule) { $matchExclude = $true break } # 匹配任意层级的文件夹/文件名 foreach ($seg in $pathSegments) { if ($seg -like $rule) { $matchExclude = $true break } } if ($matchExclude) { break } } -not $matchExclude } | ForEach-Object { # 保持原目录结构写入压缩包 $entryPath = $_.FullName.Substring($sourceDir.Length + 1) $zipEntry = $zipArchive.CreateEntry($entryPath, [System.IO.Compression.CompressionLevel]::Optimal) # 写入文件内容 $fileReader = [System.IO.File]::OpenRead($_.FullName) $entryWriter = $zipEntry.Open() $fileReader.CopyTo($entryWriter) # 释放单文件流资源 $fileReader.Dispose() $entryWriter.Dispose() } # 释放压缩包资源 $zipArchive.Dispose() $zipFileStream.Dispose()
该实现支持任意层级的文件夹和文件排除,完全保留原始目录结构,兼容PowerShell 5.1及以上所有版本,不需要安装任何外部工具。
内容的提问来源于stack exchange,提问作者Tecman
相关产品推荐
相关产品推荐

