Files
RemoveWeeklyShapshot/README.md
2026-02-19 23:23:51 +08:00

18 KiB
Raw Blame History

RemoveWeeklySnapshot

以下需求需要每周执行一次

  • 连接vCenter/Esxi/Hyper-V
  • 获取所有 vms
  • 获取所有 snapshots
  • 筛选出15天半个月前的 snapshots
  • 以上内容以 Excel 表格的形式导出,超出 15 天的快照填充蓝色底标识
  • Outlook 邮箱发送超出 15 天的快照
  • 增加排除不能删除的快照
  • 需要控制每台 vCenter 不可以同时删除超过 4 个快照
  • 最后删除 15 天前的 snapshot并同时记录删除的 snapshot 日志信息
你想获取 代码 示例输出
名称 vm.name "WebServer-01"
MOID vm._moId "vm-12"
电源状态 vm.runtime.powerState poweredOn / poweredOff
开机时间 vm.runtime.bootTime datetime 对象
CPU数 vm.config.hardware.numCPU 4
内存(MB) vm.config.hardware.memoryMB 8192
操作系统 vm.config.guestFullName "CentOS 7 (64-bit)"
IP地址 vm.guest.ipAddress "192.168.1.100"
主机名 vm.guest.hostName "webserver01.local"
存储路径 vm.config.files.vmPathName "[Datastore1] WebServer-01/WebServer-01.vmx"
快照数量 len(vm.snapshot.rootSnapshotList) 3

输出所有可用的属性和方法

vm.config.createDate  # 虚拟机的创建时间
vm.runtime.bootTime  # 虚拟机上次启动的时间

以下这些方法和属性主要用于操作虚拟机VM、快照、存储和其他资源。

vm ├── 基础标识 │ ├── name VM名称 │ └── _moId 内部ID (vm-12) │ ├── runtime 【运行状态】 │ ├── powerState poweredOn/Off/Suspended │ ├── bootTime 开机时间 │ └── host 所在物理机 │ ├── config 【硬件配置】 │ ├── hardware CPU/内存/硬盘 │ ├── guestFullName 操作系统 │ └── files VMX文件路径 │ ├── guest 【客户机内部信息】 │ ├── hostName 主机名 │ ├── ipAddress IP地址 │ └── toolsStatus VMware Tools状态 │ ├── snapshot 【快照】 │ └── rootSnapshotList 快照树 │ ├── storage 【存储】 │ └── perDatastoreUsage 各数据存储用量 │ ├── network 【网络】 │ └── [Network] 连接的端口组 │ └── summary 【快速汇总】 ├── overallStatus 整体健康状态 └── quickStats 实时性能数据

  1. AcquireMksTicket / AcquireTicket:获取访问虚拟机控制台的票据,允许用户通过 Web 界面访问 VM。
  2. Clone / CloneVM_Task:克隆一个虚拟机,创建其副本。
  3. CreateSnapshot / CreateSnapshot_Task:创建虚拟机快照,以保存当前 VM 的状态。
  4. Destroy / Destroy_Task:删除虚拟机及其所有数据。
  5. PowerOn / PowerOnVM_Task:启动虚拟机。
  6. PowerOff / PowerOffVM_Task:关闭虚拟机。
  7. Reset / ResetVM_Task:重置虚拟机,相当于按下重启按钮。
  8. RevertToCurrentSnapshot / RevertToCurrentSnapshot_Task:将虚拟机恢复到当前快照的状态。
  9. Migrate / MigrateVM_Task:迁移虚拟机到不同的主机或数据存储。
  10. SetCustomValue:设置自定义属性值,以便在虚拟机上存储额外信息。

属性列表

这些属性通常包含关于虚拟机或其他资源的状态和配置信息。以下是一些关键属性的说明:

  1. name:虚拟机的名称。
  2. guest:关于虚拟机操作系统的信息,如操作系统类型、版本等。
  3. config:虚拟机的配置详情,例如 CPU、内存、硬盘等。
  4. runtime:虚拟机的运行时状态,包括电源状态(开机、关机、挂起等)。
  5. snapshot:当前虚拟机的快照信息。
  6. summary:虚拟机的概述信息,包括状态、资源使用情况等。
  7. resourcePool:虚拟机所在的资源池。
  8. datastore:虚拟机的存储位置,指向其使用的存储库。
  9. overallStatus:虚拟机的总体状态,可能是正常、警告、错误等。
  10. recentTask:最近执行的任务列表。

其他属性

  • capability:虚拟机支持的功能,如支持的虚拟硬件版本。
  • declaredAlarmState:声明的警报状态,用于监控虚拟机的健康状况。
  • triggeredAlarmState:触发的警报状态,显示当前激活的警报。
        for vm in vm_view.view:
            print(dir(vm))  # 输出所有可用的属性和方法
            # print(vm.summary)
            # print(vm.snapshot)
            # print(vars(vm.summary))
['AcquireMksTicket', 'AcquireTicket', 'Answer', 'AnswerVM', 'ApplyEvcMode', 'ApplyEvcModeVM_Task', 'Array', 'AttachDisk', 'AttachDisk_Task', 'CheckCustomizationSpec', 'Clone', 'CloneVM_Task', 'ConsolidateDisks', 'ConsolidateVMDisks_Task', 'CreateScreenshot', 'CreateScreenshot_Task', 'CreateSecondary', 'CreateSecondaryEx', 'CreateSecondaryVMEx_Task', 'CreateSecondaryVM_Task', 'CreateSnapshot', 'CreateSnapshotEx', 'CreateSnapshotEx_Task', 'CreateSnapshot_Task', 'CryptoUnlock', 'CryptoUnlock_Task', 'Customize', 'CustomizeVM_Task', 'DefragmentAllDisks', 'Destroy', 'Destroy_Task', 'DetachDisk', 'DetachDisk_Task', 'DisableSecondary', 'DisableSecondaryVM_Task', 'DropConnections', 'EnableSecondary', 'EnableSecondaryVM_Task', 'EstimateStorageForConsolidateSnapshots_Task', 'EstimateStorageRequirementForConsolidate', 'ExportVm', 'ExtractOvfEnvironment', 'InstantClone', 'InstantClone_Task', 'MakePrimary', 'MakePrimaryVM_Task', 'MarkAsTemplate', 'MarkAsVirtualMachine', 'Migrate', 'MigrateVM_Task', 'MountToolsInstaller', 'PowerOff', 'PowerOffVM_Task', 'PowerOn', 'PowerOnVM_Task', 'PromoteDisks', 'PromoteDisks_Task', 'PutUsbScanCodes', 'QueryChangedDiskAreas', 'QueryConnections', 'QueryFaultToleranceCompatibility', 'QueryFaultToleranceCompatibilityEx', 'QueryUnownedFiles', 'RebootGuest', 'ReconfigVM_Task', 'Reconfigure', 'RefreshStorageInfo', 'Reload', 'ReloadFromPath', 'Relocate', 'RelocateVM_Task', 'RemoveAllSnapshots', 'RemoveAllSnapshots_Task', 'Rename', 'Rename_Task', 'Reset', 'ResetGuestInformation', 'ResetVM_Task', 'RevertToCurrentSnapshot', 'RevertToCurrentSnapshot_Task', 'SendNMI', 'SetCustomValue', 'SetDisplayTopology', 'SetScreenResolution', 'ShutdownGuest', 'StandbyGuest', 'StartRecording', 'StartRecording_Task', 'StartReplaying', 'StartReplaying_Task', 'StopRecording', 'StopRecording_Task', 'StopReplaying', 'StopReplaying_Task', 'Suspend', 'SuspendVM_Task', 'Terminate', 'TerminateFaultTolerantVM', 'TerminateFaultTolerantVM_Task', 'TerminateVM', 'TurnOffFaultTolerance', 'TurnOffFaultToleranceForVM_Task', 'UnmountToolsInstaller', 'Unregister', 'UnregisterVM', 'UpgradeTools', 'UpgradeTools_Task', 'UpgradeVM_Task', 'UpgradeVirtualHardware', '_GetMethodInfo', '_GetMethodList', '_GetMoId', '_GetPropertyInfo', '_GetPropertyList', '_GetServerGuid', '_GetStub', '_InvokeAccessor', '_InvokeMethod', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__', '_methodInfo', '_moId', '_propInfo', '_propList', '_serverGuid', '_stub', '_version', '_wsdlName', 'alarmActionsEnabled', 'availableField', 'capability', 'config', 'configIssue', 'configStatus', 'customValue', 'datastore', 'declaredAlarmState', 'disabledMethod', 'effectiveRole', 'environmentBrowser', 'guest', 'guestHeartbeatStatus', 'layout', 'layoutEx', 'name', 'network', 'overallStatus', 'parent', 'parentVApp', 'permission', 'recentTask', 'reloadVirtualMachineFromPath_Task', 'resourceConfig', 'resourcePool', 'rootSnapshot', 'runtime', 'setCustomValue', 'snapshot', 'storage', 'summary', 'tag', 'triggeredAlarmState', 'value']

获取虚拟机属性

获取和打印出虚拟机 (VM) 概要信息的所有属性,提供了关于虚拟机的基本信息,vm.summary 会返回一个字典,包含常见属性。可以使用 vm.guest.ipAddress 方法获取到虚拟机的IP地址等。

print(vm.summary)

(vim.vm.Summary) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], vm = 'vim.VirtualMachine:1', runtime = (vim.vm.RuntimeInfo) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], device = (vim.vm.DeviceRuntimeInfo) [ (vim.vm.DeviceRuntimeInfo) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], runtimeState = (vim.vm.DeviceRuntimeInfo.VirtualEthernetCardRuntimeState) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], vmDirectPathGen2Active = false, vmDirectPathGen2InactiveReasonVm = (str) [ 'vmNptDisabledOrDisconnectedAdapter' ], vmDirectPathGen2InactiveReasonOther = (str) [], vmDirectPathGen2InactiveReasonExtended = , uptv2Active = , uptv2InactiveReasonVm = (str) [], uptv2InactiveReasonOther = (str) [], reservationStatus = , attachmentStatus = 'red', featureRequirement = (vim.vm.FeatureRequirement) [] }, key = 4000 } ], host = 'vim.HostSystem:ha-host', connectionState = 'connected', powerState = 'poweredOff', vmFailoverInProgress = , faultToleranceState = 'notConfigured', dasVmProtection = , toolsInstallerMounted = false, suspendTime = , bootTime = , suspendInterval = 0, question = , memoryOverhead = , maxCpuUsage = 5184, maxMemoryUsage = 4096, numMksConnections = 0, recordReplayState = 'inactive', cleanPowerOff = false, needSecondaryReason = , onlineStandby = false, minRequiredEVCModeKey = , consolidationNeeded = false, offlineFeatureRequirement = (vim.vm.FeatureRequirement) [ (vim.vm.FeatureRequirement) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], key = 'cpuid.lm', featureName = 'cpuid.lm', value = 'Bool:Min:1' } ], featureRequirement = (vim.vm.FeatureRequirement) [], featureMask = (vim.host.FeatureMask) [], vFlashCacheAllocation = , paused = false, snapshotInBackground = false, quiescedForkParent = , instantCloneFrozen = false, cryptoState = , suspendedToMemory = , opNotificationTimeout = , iommuActive = }, guest = (vim.vm.Summary.GuestSummary) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], guestId = , guestFullName = , toolsStatus = 'toolsNotRunning', toolsVersionStatus = 'guestToolsUnmanaged', toolsVersionStatus2 = 'guestToolsUnmanaged', toolsRunningStatus = 'guestToolsNotRunning', hostName = , ipAddress = , hwVersion = }, config = (vim.vm.Summary.ConfigSummary) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], name = 'VMware vCenter Server Appliance', template = false, vmPathName = '[datastore1] VMware vCenter Server Appliance/VMware vCenter Server Appliance.vmx', memorySizeMB = 4096, cpuReservation = 0, memoryReservation = 0, numCpu = 2, numEthernetCards = 1, numVirtualDisks = 13, uuid = '564d7d77-f37f-64a7-47f2-a131a337c070', instanceUuid = '529e8be2-58ca-617c-ad7e-7f66de667471', guestId = 'other3xLinux64Guest', guestFullName = 'Other 3.x Linux (64-bit)', annotation = 'VMware vCenter Server Appliance', product = , installBootRequired = , ftInfo = , managedBy = , tpmPresent = false, numVmiopBackings = 0, hwVersion = }, storage = (vim.vm.Summary.StorageSummary) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], committed = 37476296711, uncommitted = 303123661815, unshared = 37476296711, timestamp = 2026-02-19T09:11:27.701184Z }, quickStats = (vim.vm.Summary.QuickStats) { dynamicType = , dynamicProperty = (vmodl.DynamicProperty) [], overallCpuUsage = , overallCpuDemand = , overallCpuReadiness = , guestMemoryUsage = , hostMemoryUsage = , guestHeartbeatStatus = 'gray', distributedCpuEntitlement = , distributedMemoryEntitlement = , staticCpuEntitlement = , staticMemoryEntitlement = , grantedMemory = , privateMemory = , sharedMemory = , swappedMemory = , balloonedMemory = , consumedOverheadMemory = , ftLogBandwidth = , ftSecondaryLatency = , ftLatencyStatus = , compressedMemory = , uptimeSeconds = , ssdSwappedMemory = , activeMemory = , memoryTierStats = (vim.vm.Summary.QuickStats.MemoryTierStats) [] }, overallStatus = 'green', customValue = (vim.CustomFieldsManager.Value) [] }

获取快照属性

输出快照所有信息

print(vm.snapshot)
(vim.vm.SnapshotInfo) {
   dynamicType = <unset>,
   dynamicProperty = (vmodl.DynamicProperty) [],
   currentSnapshot = 'vim.vm.Snapshot:1-snapshot-3',
   rootSnapshotList = (vim.vm.SnapshotTree) [
      (vim.vm.SnapshotTree) {
         dynamicType = <unset>,
         dynamicProperty = (vmodl.DynamicProperty) [],
         snapshot = 'vim.vm.Snapshot:1-snapshot-1',
         vm = 'vim.VirtualMachine:1',
         name = 'snap-01',  # 第一层快照
         description = 'Ansible snapshot',
         id = 1,
         createTime = 2026-02-17T03:26:08.834505Z,
         state = 'poweredOff',
         quiesced = false,
         backupManifest = <unset>,
         childSnapshotList = (vim.vm.SnapshotTree) [
            (vim.vm.SnapshotTree) {
               dynamicType = <unset>,
               dynamicProperty = (vmodl.DynamicProperty) [],
               snapshot = 'vim.vm.Snapshot:1-snapshot-2',
               vm = 'vim.VirtualMachine:1',
               name = 'snap-02',  # 第二层快照
               description = 'test-Ansible snapshot',
               id = 2,
               createTime = 2026-02-17T08:57:39.122511Z,
               state = 'poweredOff',
               quiesced = false,
               backupManifest = <unset>,
               childSnapshotList = (vim.vm.SnapshotTree) [
                  (vim.vm.SnapshotTree) {
                     dynamicType = <unset>,
                     dynamicProperty = (vmodl.DynamicProperty) [],
                     snapshot = 'vim.vm.Snapshot:1-snapshot-3',
                     vm = 'vim.VirtualMachine:1',
                     name = '虚拟机快照 2026%252f2%252f19 12:28:36',  # 第二层快照
                     description = '',
                     id = 3,
                     createTime = 2026-02-19T04:28:38.007703Z,
                     state = 'poweredOn',
                     quiesced = false,
                     backupManifest = <unset>,
                     childSnapshotList = (vim.vm.SnapshotTree) [],
                     replaySupported = false
                  }
               ],
               replaySupported = false
            }
         ],
         replaySupported = false
      }
   ]
}

打印快照树

def print_snapshot_tree(snapshot_info, level=0):
    """递归打印快照树(辅助函数)"""
    indent = "  " * level
    print(f"{indent}├─ {snapshot_info['name']}")
    print(f"{indent}│  ├─ 创建时间: {snapshot_info['createTime']}")
    print(f"{indent}│  ├─ 描述: {snapshot_info['description']}")
    print(f"{indent}│  ├─ 状态: {snapshot_info['state']}")
    if snapshot_info['sizeMB']:
        print(f"{indent}│  ├─ 大小: {snapshot_info['sizeMB']} MB")

    for child in snapshot_info['children']:
        print_snapshot_tree(child, level + 1)
        
if __name__ == '__main__':
    vms = get_all_vms()

    # 打印示例显示每个VM的快照信息
    for vm in vms:
        print(f"\nVM: {vm['name']}")
        if vm['snapshots']:
            print(f"快照数量: {len(vm['snapshots'])}")
            for snapshot in vm['snapshots']:
                print_snapshot_tree(snapshot)
        else:
            print("无快照")