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

PowerShell文件夹清理脚本路径拼接异常求助

PowerShell清理脚本路径合并错误及目录忽略问题修复

问题概述

编写的PowerShell脚本用于清理C:\Shares下超过60天的文件,要求部分目录清理子文件夹、部分仅清理本级文件,但运行时出现两个路径被拼接成无效路径的错误,调整+=后仍有部分目录被忽略。

报错信息

Transcript started, output file is C:\Logs\SystemScripts\sCloud-Files-Cleardown_Transcript20231113.txt
Clearing C:\Shares\Files155Live\Imports\Backup\NewcastleC:\Shares\Files999Live\Exports\Backup\Tyneside
Set-Location : Cannot find path
'C:\Shares\Files155Live\Imports\Backup\NewcastleC:\Shares\Files999Live\Exports\Backup\Tyneside' because it does not exist.
At C:\scripts\sCloud_AXISNT_Cleardown.ps1:50 char:9
- Set-Location $folderPath
- ~~~~~~~~~~~~~~~~~~~~~~~~
- CategoryInfo          : ObjectNotFound: (C:\Shares\Files...Backup\Tyneside:String) [Set-Location], ItemNotFoundException
- FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

Get-ChildItem : Cannot find path
'C:\Shares\Files155Live\Imports\Backup\NewcastleC:\Shares\Files999Live\Exports\Backup' because it does not exist.
At C:\scripts\sCloud_AXISNT_Cleardown.ps1:52 char:3
- Get-ChildItem -Path $folderPath -Recurse -Force `
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- CategoryInfo          : ObjectNotFound: (C:\Shares\Files...Exports\Backup:String) [Get-ChildItem], ItemNotFoundException
- FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

原脚本代码

$baseLocation = "C:\Shares"
$workingDir = "C:\Logs\"
$transcriptFilePath = $workingDir + "SystemScripts\"
$fileDate = Get-Date -format yyyyMMdd
$transcriptFile = $transcriptFilePath+"Files-_Transcript"+$fileDate+".txt"
$nDays = (Get-Date).AddDays(-60)
# Build list of paths to include in cleardown process
$pathsExcludeSubfolders = (Get-ChildItem C:\Shares\Files???Test\Imports\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsExcludeSubfolders += (Get-ChildItem C:\Shares\Files???Test\Exports\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsExcludeSubfolders += (Get-ChildItem C:\Shares\Files???Live\Imports\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsExcludeSubfolders += (Get-ChildItem C:\Shares\Files???Live\Exports\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder
    
$pathsIncludeSubfolders += (Get-ChildItem C:\Shares\Files???Test\Imports\Backup\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsIncludeSubfolders += (Get-ChildItem C:\Shares\Files???Test\Exports\Backup\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsIncludeSubfolders += (Get-ChildItem C:\Shares\Files???Live\Imports\Backup\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

$pathsIncludeSubfolders += (Get-ChildItem C:\Shares\Files???Live\Exports\Backup\*\ -Directory `
    | Select-Object @{ n= 'Folder'; e = { Convert-Path $_.PSPath } } ).Folder

# Check path exist for transcript logging
If(!(Test-Path $transcriptFilePath))
{
    New-Item -Path "C:\Logs\SystemScripts" -ItemType Directory
    
    Start-Transcript -Path $transcriptFile -Append
}
Else
{
    Start-Transcript -Path $transcriptFile -Append
}

# Cleardown log files older than $nDays
foreach($pathInclude in $pathsIncludeSubfolders){

"Clearing $($pathInclude)"
    DeleteItems $pathInclude $nDays $true
}

foreach($pathExclude in $pathsExcludeSubfolders){

"Clearing $($pathExclude)"
    DeleteItems $pathExclude $nDays $false
}

Stop-Transcript

问题根源

  1. 数组未初始化导致字符串拼接:$pathsIncludeSubfolders未预先初始化为数组,当第一个Get-ChildItem返回单个目录时,变量被定义为字符串类型,后续+=操作会将新路径直接拼接到原有字符串后,形成无效的合并路径。
  2. 路径匹配逻辑不完整:原脚本仅匹配Backup下的一级子目录,未包含Backup目录本身,导致该目录下的文件未被清理;手动拼接路径也存在潜在格式错误风险。

修复后的完整脚本

$baseLocation = "C:\Shares"
$workingDir = "C:\Logs\"
$fileDate = Get-Date -Format yyyyMMdd

# 使用Join-Path安全拼接路径,避免手动拼接错误
$transcriptFilePath = Join-Path -Path $workingDir -ChildPath "SystemScripts"
$transcriptFile = Join-Path -Path $transcriptFilePath -ChildPath "Files-_Transcript$fileDate.txt"
$nDays = (Get-Date).AddDays(-60)

# 预先初始化数组,确保后续+=操作是添加元素而非字符串拼接
$pathsExcludeSubfolders = @()
$pathsIncludeSubfolders = @()

# 构建需要清理(不包含子文件夹)的路径列表
$pathsExcludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Imports\*") -Directory).FullName
$pathsExcludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Exports\*") -Directory).FullName
$pathsExcludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Imports\*") -Directory).FullName
$pathsExcludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Exports\*") -Directory).FullName

# 构建需要清理(包含子文件夹)的路径列表
# 加入Backup目录本身(如需清理该目录下的文件)
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Imports\Backup") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Imports\Backup\*") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Exports\Backup") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Test\Exports\Backup\*") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Imports\Backup") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Imports\Backup\*") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Exports\Backup") -Directory).FullName
$pathsIncludeSubfolders += (Get-ChildItem (Join-Path $baseLocation "Files???Live\Exports\Backup\*") -Directory).FullName

# 确保日志目录存在,无需手动判断
New-Item -Path $transcriptFilePath -ItemType Directory -Force | Out-Null
Start-Transcript -Path $transcriptFile -Append

# 清理包含子文件夹的目录
foreach($pathInclude in $pathsIncludeSubfolders){
    Write-Host "Clearing $pathInclude"
    DeleteItems $pathInclude $nDays $true
}

# 清理不包含子文件夹的目录
foreach($pathExclude in $pathsExcludeSubfolders){
    Write-Host "Clearing $pathExclude"
    DeleteItems $pathExclude $nDays $false
}

Stop-Transcript

关键修复点

  • 数组初始化:提前用@()初始化两个路径数组,确保所有+=操作都是向数组添加元素,而非字符串拼接。
  • 安全路径拼接:使用Join-Path替代手动+拼接路径,避免因路径分隔符缺失或多余导致的错误。
  • 完善路径匹配:添加Backup目录本身的匹配(若需要清理该目录下的文件),避免遗漏目录。
  • 简化代码:用FullName替代Convert-Path $_.PSPath,直接获取目录完整路径,提升执行效率。
  • 简化日志目录创建:用New-Item -Force自动创建目录(若不存在),省去冗余的Test-Path判断。

内容的提问来源于stack exchange,提问作者Mikano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:19:51