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

PowerShell嵌套ElseIf脚本异常:仅D/E盘可备份,求排查及方案建议

问题描述

编写了一个PowerShell备份脚本,逻辑是周一至周五循环使用D、E、F、G四个磁盘备份Downloads文件夹,周末不执行备份。但脚本仅能备份到D盘和E盘,F、G盘完全不生效,怀疑是ElseIf语句或括号错误,同时想知道是否用switch更合适。当前脚本如下:

$TodaysDate = [DateTime]::Today.ToString("yyyy-MM-dd")
$YesterdaysDate = [DateTime]::Today.AddDays(-1).ToString("yyyy-MM-dd")
$WeekendDate = [DateTime]::Today.AddDays(-3).ToString("yyyy-MM-dd")

If ("D:\SNAProBackupTest\backups $YesterdaysDate" -Or "D:\SNAProBackupTest\backups $WeekendDate")
{
    md "E:\SNAProBackupTest\backups $TodaysDate"
    XCOPY   "C:\Users\daniel presnell\Downloads"  "E:\SNAProBackupTest\backups $TodaysDate"
}
ElseIf ("E:\SNAProBackupTest\backups $YesterdaysDate" -Or "E:\SNAProBackupTest\backups $WeekendDate")
{
    md "F:\SNAProBackupTest\backups $TodaysDate"
    XCOPY   "C:\Users\daniel presnell\Downloads" "F:\SNAProBackupTest\backups $TodaysDate"
}
ElseIf ("F:\SNAProBackupTest\backups $YesterdaysDate" -Or "F:\SNAProBackupTest\backups $WeekendDate")
{
    md "G:\SNAProBackupTest\backups $TodaysDate"
    XCOPY   "C:\Users\daniel presnell\Downloads" "G:\SNAProBackupTest\backups $TodaysDate"
}
ElseIf ("G:\SNAProBackupTest\backups $YesterdaysDate" -Or "G:\SNAProBackupTest\backups $WeekendDate")
{
    md "D:\SNAProBackupTest\backups $TodaysDate"
    XCOPY   "C:\Users\daniel presnell\Downloads" "D:\SNAProBackupTest\backups $TodaysDate"
}

ECHO Backup Complete!

问题原因

核心错误是If/ElseIf条件判断逻辑完全错误:直接传入字符串路径在PowerShell中会被视为$true(非空字符串都被判定为真值),所以第一个If语句永远成立,后续的ElseIf分支根本不会被执行,导致只会触发D→E的备份逻辑,其他盘的分支永远走不到。

另外还有两个小问题:

  • 没有判断当前是否是周末,脚本会在周末也执行
  • 使用md和XCOPY未处理异常(比如目录已存在、XCOPY缺少必要参数等)

修正后的If-Else脚本

先判断是否是周末,再检查前一天或周末的备份目录是否存在,再执行对应备份:

$today = Get-Date
$todaysDate = $today.ToString("yyyy-MM-dd")
$yesterdaysDate = $today.AddDays(-1).ToString("yyyy-MM-dd")
$weekendDate = $today.AddDays(-3).ToString("yyyy-MM-dd")
$sourceDir = "C:\Users\daniel presnell\Downloads"
$backupBase = "SNAProBackupTest\backups"

# 周末不执行备份
if ($today.DayOfWeek -in 'Saturday', 'Sunday') {
    Write-Host "今日是周末,跳过备份"
    exit
}

# 检查各盘的备份目录是否存在
$dExists = Test-Path "D:\$backupBase $yesterdaysDate" -Or (Test-Path "D:\$backupBase $weekendDate")
$eExists = Test-Path "E:\$backupBase $yesterdaysDate" -Or (Test-Path "E:\$backupBase $weekendDate")
$fExists = Test-Path "F:\$backupBase $yesterdaysDate" -Or (Test-Path "F:\$backupBase $weekendDate")
$gExists = Test-Path "G:\$backupBase $yesterdaysDate" -Or (Test-Path "G:\$backupBase $weekendDate")

if ($dExists) {
    $targetDir = "E:\$backupBase $todaysDate"
}
elseif ($eExists) {
    $targetDir = "F:\$backupBase $todaysDate"
}
elseif ($fExists) {
    $targetDir = "G:\$backupBase $todaysDate"
}
elseif ($gExists) {
    $targetDir = "D:\$backupBase $todaysDate"
}
else {
    # 默认第一次备份到D盘
    $targetDir = "D:\$backupBase $todaysDate"
}

# 创建目录(已存在则不报错)
New-Item -Path $targetDir -ItemType Directory -Force
# 使用Robocopy替代XCOPY,更可靠(也可以保留XCOPY,需加参数)
Robocopy $sourceDir $targetDir /E /R:3 /W:5
# 或者用XCOPY:XCOPY $sourceDir $targetDir /E /I /Y

Write-Host "Backup Complete!"

使用Switch优化的版本

Switch更适合这种多分支判断场景,结构更清晰:

$today = Get-Date
$todaysDate = $today.ToString("yyyy-MM-dd")
$yesterdaysDate = $today.AddDays(-1).ToString("yyyy-MM-dd")
$weekendDate = $today.AddDays(-3).ToString("yyyy-MM-dd")
$sourceDir = "C:\Users\daniel presnell\Downloads"
$backupBase = "SNAProBackupTest\backups"

# 周末跳过
if ($today.DayOfWeek -in 'Saturday', 'Sunday') {
    Write-Host "今日是周末,跳过备份"
    exit
}

# 获取存在的备份盘
$existingDrive = switch ($true) {
    (Test-Path "D:\$backupBase $yesterdaysDate") -or (Test-Path "D:\$backupBase $weekendDate") { 'D' }
    (Test-Path "E:\$backupBase $yesterdaysDate") -or (Test-Path "E:\$backupBase $weekendDate") { 'E' }
    (Test-Path "F:\$backupBase $yesterdaysDate") -or (Test-Path "F:\$backupBase $weekendDate") { 'F' }
    (Test-Path "G:\$backupBase $yesterdaysDate") -or (Test-Path "G:\$backupBase $weekendDate") { 'G' }
    default { 'D' } # 默认第一次备份到D盘
}

# 根据存在的盘确定目标盘
$targetDrive = switch ($existingDrive) {
    'D' { 'E' }
    'E' { 'F' }
    'F' { 'G' }
    'G' { 'D' }
}

$targetDir = "$targetDrive:\$backupBase $todaysDate"
New-Item -Path $targetDir -ItemType Directory -Force
Robocopy $sourceDir $targetDir /E /R:3 /W:5

Write-Host "Backup Complete!"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:02:05