Powershell批量解压目录下zip文件并重命名内部txt到公共目录
问题原因
- 原脚本未定义
$UnzipPath变量,Move-Item执行时目标路径非法,是触发未授权访问报错的核心原因 - 每次解压出的
export.txt直接写入同一临时目录,会覆盖前一次的解压结果,最终仅保留最后一个文件 - 无需额外的临时文件移动步骤,可在解压时直接指定最终文件名,简化流程
可行方案
方案1:使用PowerShell内置功能实现(推荐,要求PowerShell 5.1及以上版本)
无需依赖COM组件,逻辑更稳定,不需要提前重命名原zip文件也可实现唯一命名:
# 配置根目录和最终txt存放目录 $rootPath = "C:\Insert Root Directory here" $targetPath = "C:\Insert Location to put .txt files here" # 创建目标目录(不存在则新建) if (-not (Test-Path -Path $targetPath -PathType Container)) { New-Item -Path $targetPath -ItemType Directory -Force | Out-Null } # 递归获取所有zip文件 $zipFiles = Get-ChildItem -LiteralPath $rootPath -Filter "*.zip" -Recurse -File foreach ($zip in $zipFiles) { # 生成唯一的txt文件名:父目录名_原zip文件名(去掉.zip后缀).txt,确保不会重复 # 如果已经提前完成zip文件重命名,可直接简化为 $txtName = $zip.BaseName + ".txt" $txtName = "{0}_{1}.txt" -f $zip.Directory.Name, $zip.BaseName $targetTxtPath = Join-Path -Path $targetPath -ChildPath $txtName # 临时解压目录,每个zip单独用一个临时目录避免文件覆盖 $tempExtractDir = Join-Path -Path $env:TEMP -ChildPath ([guid]::NewGuid().ToString("N")) New-Item -Path $tempExtractDir -ItemType Directory -Force | Out-Null try { # 解压zip到临时目录 Expand-Archive -LiteralPath $zip.FullName -DestinationPath $tempExtractDir -Force # 找到解压出的export.txt,移动到目标目录并重命名 Get-ChildItem -Path $tempExtractDir -Filter "export.txt" -File | Move-Item -Destination $targetTxtPath -Force Write-Host "已处理文件:$txtName" } finally { # 清理临时目录 Remove-Item -Path $tempExtractDir -Recurse -Force -ErrorAction SilentlyContinue } }
方案2:修复原有Shell.Application版本的脚本
针对你原有的写法,修复变量定义和覆盖问题:
$ZipFilesPath = "C:\Insert Root Directory here" # 直接定义最终存放目录,不需要额外临时移动步骤 $TargetPath = "C:\Insert Location to put .txt files here" If(!(test-path $TargetPath)) { New-Item -ItemType Directory -Force -Path $TargetPath | Out-Null } $Shell = New-Object -com Shell.Application $ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP -File foreach ($ZipFile in $ZipFiles) { $ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName) write-host "正在处理:$ZipFileActualName" # 每个zip单独创建临时解压目录,避免文件覆盖 $tempDir = Join-Path $env:TEMP $ZipFileActualName if (-not (Test-Path $tempDir)) { New-Item -ItemType Directory -Force -Path $tempDir | Out-Null } $tempLocation = $Shell.NameSpace($tempDir) $ZipFolder = $Shell.NameSpace($ZipFile.fullname) $tempLocation.Copyhere($ZipFolder.items(), 1040) # 移动重命名到目标目录 Get-ChildItem $tempDir -Filter *.txt | Move-Item -Destination (Join-Path $TargetPath "$ZipFileActualName.txt") -Force # 清理临时目录 Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue }
注意事项
- 执行脚本时建议右键PowerShell选择「以管理员身份运行」,避免权限不足导致的读写错误
- 如果需要自定义命名规则,直接修改对应文件名的生成逻辑即可
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

