PowerShell脚本故障排查:按文件名与父文件夹匹配压缩文件
解决PowerShell压缩指定父目录文件到Zip的问题
需求说明
给定逗号分隔的带父文件夹的文件项(例如 $itemsToInclude = "stage\arsw.war,dev\deployfile"),在$workspace="D:\ims"路径下递归查找,仅将同时匹配文件名和直接父文件夹名的文件添加至hello.zip。比如D:\ims\work1\app1\src\stage\arsw.war符合要求,而D:\ims\work1\app1\src\wow\arsw.war因父文件夹不符被排除。
原脚本问题
用户尝试的脚本执行后出现两个问题:
- 无法找到
dev\deployfile对应的文件 - 找到的文件无法正常添加到压缩包,报错
Compress-Archive : The path 'arsw.war' either does not exist or is not a valid file system path.
原脚本代码
PS D:\ims> cd D:\ims $workspace = “D:\ims” $itemsToInclude = “stage\arsw.war,dev\deployfile” $items = $itemsToInclude -split “,” | ForEach-Object { $_.Trim() } $matchingFiles = @() foreach ($item in $items) { # Get the file name and the parent folder name from the item Write-Host "Split-Path -Path $item -Leaf" $fileName = Split-Path -Path $item -Leaf Write-Host "Split-Path -Path $item -Parent" $parentFolder = Split-Path -Path $item -Parent Write-Host "$fileName and $parentFolder" $files = Get-ChildItem -Path $workspace -Filter $fileName -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Directory.Name -eq $parentFolder } # Add the matching files to the array using array subexpression operator $matchingFiles = @($matchingFiles; $files) Write-Host "FOUND $($files.FullName) and $($matchingFiles.FullName)" if ($matchingFiles) { Compress-Archive -Path $matchingFiles -DestinationPath hello.zip } else { Write-Host “No matching files were found in $workspace” } }
执行错误输出
Split-Path -Path stage\arsw.war -Leaf Split-Path -Path stage\arsw.war -Parent arsw.war and stage FOUND D:\ims\work1\app1\src\stage\arsw.war and D:\ims\work1\app1\src\stage\arsw.war Compress-Archive : The path 'arsw.war' either does not exist or is not a valid file system path. At line:33 char:1 + Compress-Archive -Path $matchingFiles -DestinationPath hello.zip + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (arsw.war:String) [Compress-Archive], InvalidOperationException + FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive Split-Path -Path dev\deployfile -Leaf Split-Path -Path dev\deployfile -Parent deployfile and dev FOUND and D:\ims\work1\app1\src\stage\arsw.war Compress-Archive : The path 'arsw.war' either does not exist or is not a valid file system path. At line:33 char:1 + Compress-Archive -Path $matchingFiles -DestinationPath hello.zip + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (arsw.war:String) [Compress-Archive], InvalidOperationException + FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive
问题分析
- 压缩路径错误:
$matchingFiles存储的是FileInfo对象,直接传给Compress-Archive时,PowerShell可能自动解析为文件名而非完整路径,导致找不到文件。 - 文件查找逻辑缺陷:原脚本用
-Filter $fileName递归查找,若文件无扩展名(如deployfile),Windows文件系统的过滤规则可能无法匹配,改用Where-Object同时匹配文件名和父目录更可靠。 - 重复压缩覆盖:原脚本在每次循环都执行
Compress-Archive,会覆盖之前的压缩包,应该收集完所有匹配文件后统一执行压缩。
修复后的脚本
$workspace = "D:\ims" $itemsToInclude = "stage\arsw.war,dev\deployfile" # 拆分并清理要匹配的项 $items = $itemsToInclude -split "," | ForEach-Object { $_.Trim() } $matchingFiles = @() foreach ($item in $items) { # 拆分文件名和父目录名 $fileName = Split-Path -Path $item -Leaf $parentFolder = Split-Path -Path $item -Parent Write-Host "正在查找: 父目录[$parentFolder] 下的文件[$fileName]" # 递归查找符合条件的文件:文件名完全匹配,且直接父目录名匹配 $foundFiles = Get-ChildItem -Path $workspace -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $fileName -and $_.Directory.Name -eq $parentFolder } if ($foundFiles) { Write-Host "找到匹配文件: $($foundFiles.FullName -join ', ')" $matchingFiles += $foundFiles.FullName } else { Write-Host "未找到匹配文件: $item" } } # 统一压缩所有找到的文件 if ($matchingFiles.Count -gt 0) { # 使用 -Update 参数实现增量添加,若需要覆盖压缩包则移除该参数 Compress-Archive -Path $matchingFiles -DestinationPath "$workspace\hello.zip" -Update Write-Host "压缩完成,共 $($matchingFiles.Count) 个文件已添加到 hello.zip" } else { Write-Host "未找到任何符合条件的文件" }
关键修复点
- 传递完整路径:将
$foundFiles.FullName加入数组,确保Compress-Archive能识别正确的文件路径。 - 优化查找逻辑:去掉
-Filter,改用Where-Object同时匹配文件名和父目录,解决无扩展名文件的匹配问题。 - 统一压缩时机:所有文件查找完成后执行一次压缩,避免循环中重复覆盖压缩包;
-Update参数支持增量添加文件,按需选择是否保留。 - 增强日志输出:更清晰的提示信息,方便排查匹配情况。
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

