You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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因父文件夹不符被排除。

原脚本问题

用户尝试的脚本执行后出现两个问题:

  1. 无法找到dev\deployfile对应的文件
  2. 找到的文件无法正常添加到压缩包,报错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

问题分析

  1. 压缩路径错误:$matchingFiles存储的是FileInfo对象,直接传给Compress-Archive时,PowerShell可能自动解析为文件名而非完整路径,导致找不到文件。
  2. 文件查找逻辑缺陷:原脚本用-Filter $fileName递归查找,若文件无扩展名(如deployfile),Windows文件系统的过滤规则可能无法匹配,改用Where-Object同时匹配文件名和父目录更可靠。
  3. 重复压缩覆盖:原脚本在每次循环都执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:38:13