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

Windows Server 2016中PowerShell备份清理脚本未删除文件夹

PowerShell备份清理脚本在Windows Server 2016中不执行删除操作排查与修复

问题描述

编写的PowerShell脚本用于删除备份文件夹并保留最新3个,测试环境通过任务计划执行正常,但部署到Windows Server 2016后:

  • 脚本能正常执行并发送完成通知邮件
  • 可检测到备份文件夹名称,但实际未执行删除操作
  • 已将备份目录移至服务器本地、设置执行策略为RemoteSigned,问题仍存在

原脚本如下:

# Gets path of Backup folder
$backup_path = 'C:\Backup'

# Getting the subfolders inside the Backup folder
$subfolders = Get-ChildItem -Path $backup_path -Directory -Force

# Checks if the number of folders is more than 3**
if ($subfolders.Count -gt 3) {

    # Sort subfolders by Creation Time
    $sorted_subfolders = $subfolders | Sort-Object -Property CreationTime

    # Getting number of subfolders to delete
    $delete_count = $subfolders.Count - 3

    # Deletes the subfolders and their contents
    $sorted_subfolders[0..($delete_count - 1)] | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

    # Write a message to the console when deletion complete 
    Write-Output "Deleted $($delete_count) subfolders"

    # Create a string for email with the folder names
    $email_body = "The Backup Management Script Has been Executed Successfully!`n`n" +
                  "The following folders were deleted from the SQL backup folder:`n" +
                  ($sorted_subfolders[0..($delete_count - 1)].Name -join "`n") + "`n`n" +
                  "The following folders are left in the SQL backup folder:`n" +
                  ($sorted_subfolders[$delete_count..($subfolders.Count - 1)].Name -join "`n")

}
else {
    # Writes email to Admin when Latest 3 Backup folders are left**

    $email_body = "No backup Folder Older than 3 Days Have been Found!`n Please Check If the Backup has run as scheduled."
}

# Sends email notification
$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = "SMTP server IP"
$mailmessage.from = ("Noreply.backup@domain.com")
$mailmessage.To.add("Admin@domain.com")
$mailmessage.Subject = "Backup Cleanup Job"
$mailmessage.Body = $email_body
$smtpclient.Send($mailmessage)

排查与修复方案

1. 任务计划执行权限不足

Windows Server 2016的任务计划默认可能使用低权限账户(如本地系统账户)运行,而C:\Backup目录需要管理员权限才能删除文件。

  • 解决:编辑任务计划,在「安全选项」中勾选使用最高权限运行,并确保执行账户对C:\Backup目录拥有完全控制权限。

2. 错误被静默屏蔽无法定位问题

原脚本中Remove-Item使用-ErrorAction SilentlyContinue,会掩盖所有删除错误,导致无法知道失败原因。

  • 解决:临时移除该参数,或改为-ErrorAction Stop并添加错误捕获,例如:
try {
    $sorted_subfolders[0..($delete_count - 1)] | Remove-Item -Force -Recurse -ErrorAction Stop
    Write-Output "Deleted $($delete_count) subfolders"
} catch {
    $email_body = "删除操作失败:`n$($_.Exception.Message)"
}

3. 排序逻辑不符合实际备份场景

按CreationTime排序可能不准确——部分备份工具会复用文件夹,此时LastWriteTime更能反映备份的最新状态。

  • 解决:修改排序属性为LastWriteTime:
$sorted_subfolders = $subfolders | Sort-Object -Property LastWriteTime

4. 数组索引边界优化

原脚本用索引切片0..($delete_count -1)存在边界计算风险,改用Select-Object -First更直观可靠:

$foldersToDelete = $sorted_subfolders | Select-Object -First $delete_count
$foldersToDelete | Remove-Item -Force -Recurse -ErrorAction Stop

5. 任务计划的PowerShell调用方式修正

Windows Server 2016中任务计划调用PowerShell时,需指定完整路径并明确执行参数:

  • 程序/脚本:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • 添加参数:-ExecutionPolicy RemoteSigned -File "C:\你的脚本路径\CleanupBackup.ps1"

修改后的完整脚本

# 备份文件夹路径
$backup_path = 'C:\Backup'

# 获取备份文件夹下的子目录
$subfolders = Get-ChildItem -Path $backup_path -Directory -Force

# 判断子目录数量是否超过3个
if ($subfolders.Count -gt 3) {
    # 按最后修改时间排序(更贴合备份更新逻辑)
    $sorted_subfolders = $subfolders | Sort-Object -Property LastWriteTime

    # 计算需要删除的文件夹数量
    $delete_count = $subfolders.Count - 3

    # 筛选待删除和剩余的文件夹
    $foldersToDelete = $sorted_subfolders | Select-Object -First $delete_count
    $remainingFolders = $sorted_subfolders | Select-Object -Last 3

    try {
        # 执行删除操作
        $foldersToDelete | Remove-Item -Force -Recurse -ErrorAction Stop
        Write-Output "已删除 $($delete_count) 个文件夹"

        # 构建成功通知邮件内容
        $email_body = "备份清理脚本执行成功!`n`n" +
                      "已从SQL备份目录删除以下文件夹:`n" +
                      ($foldersToDelete.Name -join "`n") + "`n`n" +
                      "SQL备份目录剩余以下文件夹:`n" +
                      ($remainingFolders.Name -join "`n")
    } catch {
        # 构建错误通知邮件内容
        $email_body = "备份清理脚本执行失败!`n`n错误信息:`n$($_.Exception.Message)"
    }
} else {
    # 文件夹数量不足3个时的通知内容
    $email_body = "未找到超过3个的备份文件夹!`n请检查备份任务是否按计划执行。"
}

# 发送邮件通知
$SmtpClient = New-Object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = "SMTP server IP"
$mailmessage.from = ("Noreply.backup@domain.com")
$mailmessage.To.add("Admin@domain.com")
$mailmessage.Subject = "备份清理任务通知"
$mailmessage.Body = $email_body
$smtpclient.Send($mailmessage)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:13:10