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

使用脚本删除VMware快照遇多快照检测失效问题求助

解决多快照场景下VMware快照清理脚本的检测问题

看起来你的脚本在单快照时工作正常,但多快照场景下漏过了后续快照,我帮你分析下问题所在,然后给出修复后的代码。

首先,你的需求很清晰:

  • 删除指定天数前的快照,但保留描述含PERM的快照
  • 描述含DELT的快照,按指定日期删除

原脚本的问题点

我梳理了几个可能导致多快照检测失败的核心问题:

  1. 日期比较逻辑错误:原脚本里用字符串和DateTime对象混合比较(比如$Snap.created -le ($OldDate).ToShortDateString()),PowerShell的隐式转换在多快照场景下容易出错,导致判断条件不触发。
  2. DELT日期的字符串比较陷阱:直接用dd-MM-yyyy格式的字符串比较日期,会出现逻辑反转(比如"05-10-2024"字符串小于"10-09-2024",但实际日期是10月5日更晚)。
  3. 未处理短描述的异常:如果快照描述长度不足4个字符,Substring(0,4)会抛出异常,进入Catch块后变量被清空,可能影响后续的条件判断。
  4. $OldDate变量未明确定义:原脚本里用了$OldDate但没看到赋值,这会导致该条件永远不触发。

修复后的完整脚本

# 定义需要保留的快照天数(这里设为15天,可根据需求修改)
$OldDate = (Get-Date).AddDays(-15)

# 获取所有虚拟机的快照并选择关键属性
$AllSnaps = Get-VM | Get-Snapshot | Select-Object VM, Name, Description, SizeMB, Created

foreach ($Snap in $AllSnaps) {
    $identity = $null
    $delDate = $null

    # 先检查描述是否存在且长度足够,避免截取时抛出异常
    if ($Snap.Description -and $Snap.Description.Length -ge 4) {
        $identity = $Snap.Description.Substring(0, 4).Trim()
        
        # 尝试解析DELT后的日期,确保格式为dd-MM-yyyy
        if ($Snap.Description.Length -ge 10) {
            try {
                $delDate = [DateTime]::ParseExact($Snap.Description.Substring(5).Trim(), "dd-MM-yyyy", $null)
            }
            catch {
                Write-Warning "快照 [$($Snap.Name)] 的日期格式错误,请使用dd-MM-yyyy"
                $delDate = $null
            }
        }
    }

    # 按优先级判断快照处理逻辑
    if ($identity -eq "DELT" -and $delDate) {
        # 使用日期对象比较,避免字符串错误
        if ($delDate -le (Get-Date).Date) {
            Write-Host "$($Snap.VM) - $($Snap.Name) - $($Snap.Created) - 删除快照(按DELT指定日期)" -ForegroundColor Blue
            # 实际执行删除请取消下面的注释
            # Remove-Snapshot -Snapshot $Snap -Confirm:$false
        }
        else {
            Write-Host "$($Snap.VM) - $($Snap.Name) - $($Snap.Created) - 跳过(DELT指定日期未到)" -ForegroundColor Cyan
        }
    }
    elseif ($identity -eq "PERM") {
        Write-Host "VMName : $($Snap.VM) - SnapName : $($Snap.Name) - 创建时间 $($Snap.Created) - 大小 $($Snap.SizeMB)MB - 操作:跳过 - 原因:永久快照" -ForegroundColor Green
    }
    elseif ($Snap.Created -le $OldDate.Date) {
        Write-Host "$($Snap.VM) - $($Snap.Name) - $($Snap.Created) - 删除超过15天的快照" -ForegroundColor Red
        # 实际执行删除请取消下面的注释
        # Remove-Snapshot -Snapshot $Snap -Confirm:$false
    }
    else {
        Write-Host "$($Snap.VM) - $($Snap.Name) - $($Snap.Created) - 跳过(未达到删除条件)" -ForegroundColor Gray
    }
}

关键修复说明

  • 明确定义$OldDate:用AddDays(-15)生成DateTime对象,直接和$Snap.Created(DateTime类型)比较,逻辑更准确。
  • 安全处理描述截取:先检查描述长度再截取,避免异常中断循环。
  • 日期转换为对象:用ParseExact将DELT后的字符串转为DateTime对象,确保日期比较逻辑正确。
  • 增加日志反馈:新增了未达条件的跳过日志,方便排查哪些快照被处理,哪些被跳过。
  • 注释删除命令:默认只输出日志,确认逻辑正确后再取消注释执行实际删除,避免误删。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:04:04