Hyper-Vを稼働させていて、自動スナップショットを何度か行っていると気が付く事があります。スナップショットを消す場合、最新のスナップショットデータを消すのはMsvm_PreviousSettingDataがあるから楽なのですが、逆に一番古いスナップショットを消す場合は?と言われると困ってしまうわけです。
というわけで、自分自身必要に狩られたので先輩プログラマに聞きつつ作ってみました。動作的には各スナップショットの名前に自動的に付く時間から一番古いスナップショットを探していますので、スナップショット名を変更すると正常に動作しません。
やり方が強引なので、利用するのであれば動作確認してからでお願いしますね。
使い方はMSDNのサンプルと同じで
cscript RemoveVirtualSystemSnapshot.vbs vmName
です。
option explicit dim objWMIService dim managementService dim fileSystem const JobStarting = 3 const JobRunning = 4 const JobCompleted = 7 const wmiStarted = 4096 const wmiSuccessful = 0 Main() '----------------------------------------------------------------- ' Main '----------------------------------------------------------------- Sub Main() dim computer, objArgs, vmName, vm, snapshotSetting set fileSystem = Wscript.CreateObject("Scripting.FileSystemObject") computer = "." set objWMIService = GetObject("winmgmts:\\" & computer & "\root\virtualization") set managementService = objWMIService.ExecQuery("select * from Msvm_VirtualSystemManagementService").ItemIndex(0) set objArgs = WScript.Arguments if WScript.Arguments.Count = 1 then vmName = objArgs.Unnamed.Item(0) else WScript.Echo "usage: cscript RemoveVirtualSystemSnapshot.vbs vmName" WScript.Quit(1) end if set vm = GetComputerSystem(vmName) set snapshotSetting = GetComputerSystemSnapshotSettings(vm) 'MsgBox snapshotSetting.ElementName 'WScript.Quit(0) if RemoveVirtualSystemSnapshot(snapshotSetting) then WriteLog "Done" WScript.Quit(0) else WriteLog "RemoveVirtualSystemSnapshot Failed." WScript.Quit(1) end if End Sub '----------------------------------------------------------------- ' Retrieve Msvm_VirtualComputerSystem from base on its ElementName '----------------------------------------------------------------- Function GetComputerSystem(vmElementName) On Error Resume Next dim query query = Format1("select * from Msvm_ComputerSystem where ElementName = '{0}'", vmElementName) set GetComputerSystem = objWMIService.ExecQuery(query).ItemIndex(0) if (Err.Number <> 0) then WriteLog Format1("Err.Number: {0}", Err.Number) WriteLog Format1("Err.Description:{0}",Err.Description) WScript.Quit(1) end if End Function '----------------------------------------------------------------- ' Retrieve the oldest Msvm_VirtualComputerSystem snapshot '----------------------------------------------------------------- Function GetComputerSystemSnapshotSettings(computerSystem) On Error Resume Next dim query ' query = Format1("ASSOCIATORS OF {{0}} WHERE resultClass = Msvm_VirtualSystemsettingData AssocClass = Msvm_PreviousSettingData", computerSystem.Path_.Path) query = Format1("ASSOCIATORS OF {{0}} WHERE resultClass = Msvm_VirtualSystemsettingData", computerSystem.Path_.Path) Dim i Dim MinTimeNo MinTimeNo = -1 For i = 0 To objWMIService.ExecQuery(query).Count - 1 If InStr(objWMIService.ExecQuery(query).ItemIndex(i).ElementName,")") > 0 AND InStr(objWMIService.ExecQuery(query).ItemIndex(i).ElementName,"(") > 0 Then ' MsgBox objWMIService.ExecQuery(query).ItemIndex(i).ElementName & "--" & Left(objWMIService.ExecQuery(query).ItemIndex(i).CreationTime,14) & "-" & objWMIService.ExecQuery(query).ItemIndex(i).SettingType If MinTimeNo = -1 Then MinTimeNo = i Else If Left(objWMIService.ExecQuery(query).ItemIndex(MinTimeNo).CreationTime,14) > Left(objWMIService.ExecQuery(query).ItemIndex(i).CreationTime,14) Then MinTimeNo = i End if End If End If Next 'MsgBox objWMIService.ExecQuery(query).ItemIndex(MinTimeNo).ElementName & "--" & Left(objWMIService.ExecQuery(query).ItemIndex(MinTimeNo).CreationTime,14) set GetComputerSystemSnapshotSettings = objWMIService.ExecQuery(query).ItemIndex(MinTimeNo) if (Err.Number <> 0) then WriteLog Format1("Err.Number: {0}", Err.Number) WriteLog Format1("Err.Description:{0}",Err.Description) WScript.Quit(1) end if End Function '----------------------------------------------------------------- ' Revmove a virtual system Snapshot '----------------------------------------------------------------- Function RemoveVirtualSystemSnapshot(snapshotSettingData) dim objInParam, objOutParams RemoveVirtualSystemSnapshot = false set objInParam = managementService.Methods_("RemoveVirtualSystemSnapshot").InParameters.SpawnInstance_() objInParam.SnapshotSettingData = snapshotSettingData.Path_.Path set objOutParams = managementService.ExecMethod_("RemoveVirtualSystemSnapshot", objInParam) if objOutParams.ReturnValue = wmiStarted then if (WMIJobCompleted(objOutParams)) then RemoveVirtualSystemSnapshot = true end if elseif objOutParams.ReturnValue = wmiSuccessful then RemoveVirtualSystemSnapshot = true else WriteLog Format1("RemoveVirtualSystemSnapshot failed with ReturnValue {0}", objOutParams.ReturnValue) end if End Function '----------------------------------------------------------------- ' Handle wmi Job object '----------------------------------------------------------------- Function WMIJobCompleted(outParam) dim WMIJob, jobState WMIJobCompleted = true set WMIJob = objWMIService.Get(outParam.Job) jobState = WMIJob.JobState while jobState = JobRunning or jobState = JobStarting WriteLog Format1("In progress... {0}% completed.",WMIJob.PercentComplete) WScript.Sleep(1000) set WMIJob = objWMIService.Get(outParam.Job) jobState = WMIJob.JobState wend if (WMIJob.JobState <> JobCompleted) then WriteLog Format1("ErrorDescription:{0}", WMIJob.ErrorDescription) WriteLog Format1("ErrorCode:{0}", WMIJob.ErrorCode) WMIJobCompleted = false end if End Function '----------------------------------------------------------------- ' Create the console log files. '----------------------------------------------------------------- Sub WriteLog(line) dim fileStream set fileStream = fileSystem.OpenTextFile(".\RemoveVirtualSystemSnapshot.log", 8, true) WScript.Echo line fileStream.WriteLine line fileStream.Close End Sub '------------------------------------------------------------------------------ ' The string formating functions to avoid string concatenation. '------------------------------------------------------------------------------ Function Format2(myString, arg0, arg1) Format2 = Format1(myString, arg0) Format2 = Replace(Format2, "{1}", arg1) End Function '------------------------------------------------------------------------------ ' The string formating functions to avoid string concatenation. '------------------------------------------------------------------------------ Function Format1(myString, arg0) Format1 = Replace(myString, "{0}", arg0) End Function