使用Applescript关闭VMware Fusion虚拟机并对其进行安全备份

使用Applescript关闭VMware Fusion虚拟机并对其进行安全备份,applescript,backup,vmware,virtual-machine,fusion,Applescript,Backup,Vmware,Virtual Machine,Fusion,VMware建议不要使用Apple的Time Machine备份虚拟机(VM),除非使用快照。但是,许多有经验的高级用户强烈反对使用快照,因为每个快照链都位于前一个快照链上,这意味着任何链接的故障都可能导致VM失败,并增加VM的复杂性并降低其性能 所以,我正在尝试编写一个AppleScript,它关闭所有运行的虚拟机,然后复制一个备份。这应该是干净和简单的 但是,我在挂起的VM上遇到了一些问题(因此,训练营VM不是问题,因为它们不能挂起)。如果虚拟机被挂起,那么您需要将其关闭(关机),以便对其进

VMware建议不要使用Apple的Time Machine备份虚拟机(VM),除非使用快照。但是,许多有经验的高级用户强烈反对使用快照,因为每个快照链都位于前一个快照链上,这意味着任何链接的故障都可能导致VM失败,并增加VM的复杂性并降低其性能

所以,我正在尝试编写一个AppleScript,它关闭所有运行的虚拟机,然后复制一个备份。这应该是干净和简单的

但是,我在挂起的VM上遇到了一些问题(因此,训练营VM不是问题,因为它们不能挂起)。如果虚拟机被挂起,那么您需要将其关闭(关机),以便对其进行干净的备份。关闭挂起的VM的唯一方法是首先恢复它,然后关闭它的电源。如果虚拟机在其自己的窗口中打开,这对AppleScript来说不是问题。VMWare Fusion将此VM正确报告为已挂起,允许脚本先恢复它,然后将其关闭

不幸的是,如果VM窗口已关闭,因此它没有自己的窗口,而只是出现在虚拟机库中,则VMware Fusion不会正确地将VM报告为已挂起。即使虚拟机已挂起,VMware Fusion也会将该状态报告为“关机”,这意味着将备份挂起的虚拟机

您可以在此处找到其他详细信息:

这是我的密码。非常欢迎反馈、建议和改进

(* Applescript application to auto back up virtual machines after certain period of system idle Requirements: [ ] "Power off the virtual machine" must be selected in VMWare Fusion "Preferences…" -> "General" -> "When closing a virtual machine:" -- this is needed because if a VM window is closed, then VMware reports the power state of a VM as "powered off" even if the VM is actually "suspended"; and from a document object there is no way to access its window [ ] In "System Preferences…" -> "Energy Saver" -> "Power adapter" -> "Computer sleep" must be set to a greater value than backup_after + ( check_every * 2 ) http://culturedcode.com/forums/read.php?7,30174,30597 To make this runable, save as application. To not show in Dock, set LSBackgroundOnly in Info.plist of created app bundle, or other ways in http://groups.google.com/group/macenterprise/browse_thread/thread/be7db35451e1dc70 *) property afterHours : 8 --23 -- hour of the day to start monitoring idle property workDayStarts : 5 -- hour of the day to stop monitoring idle property backupDuration : 2 -- number of hours needed to back up virtual machines global backup_after, check_every -- TODO: do these really need to be global ? set backup_after to 10 --(40 * 60) -- in seconds set check_every to 5 --(10 * 60) property cancelTimer : 60 -- how many seconds the user has to cancel backup property virtualizationApp : "VMware Fusion" -- variable can't be used in 'tell application' statements or won't compile, so search & replace other instances of "VMware Fusion" property resumeDelay : 120 --(4 * 60) -- in seconds; usually takes backup_after then -- test to see if backup has been done today if my hasNotBackedUpToday(backupLocation) then -- warn the user that VM application will force close VMs repeat with secondsLeft from cancelTimer to 1 by -1 set dialogResult to display alert virtualizationApp & " is about to force quit and back up virtual machines " message "This AppleScript is set to force close " & virtualizationApp & ", if it's open, and its virtual machines, and then to back up the virtual machines." & return & return & "Click \"Cancel\" to delay these actions until later, or press \"OK\" to quit and back up." & return & return & secondsLeft & " seconds left." buttons {"OK", "Cancel"} default button "OK" as warning giving up after 1 if secondsLeft = 1 or (button returned of dialogResult) is "OK" then -- force VMs to power off, quit VM app my powerOffVMsQuitFusion() -- back up VMs if my backupVMs(backupLocation, virtualMachinesLocation) then display dialog "Successfully backed up virtual machines." else display dialog "Failed to back up virtual machines." end if exit repeat else if (button returned of dialogResult) is "Cancel" then display dialog "Backup delayed until later." exit repeat end if end repeat else return (8 * 60 * 60) -- have backed up today, so try again in 8 hrs end if end if return check_every end if end tell end idle (* * Check to see if have backed up in last 16 hrs *) on hasNotBackedUpToday(theLocation) tell application "Finder" set bLocation to POSIX file theLocation as alias sort (get folders of bLocation) by creation date set myResult to result set myResultCount to count of myResult -- this raises an error if the folder doesn't contain any files if (myResultCount is not equal to 0) then set theFile to (item 1 of myResult) if creation date of theFile is greater than ((current date) - (16 * 60 * 60)) then --display dialog "Have backed up today." return false end if end if -- delete a backup if have reached max if myResultCount ≥ numBackupsToKeep then delete item myResultCount of myResult end if set currDate to current date set folderName to ("" & (year of currDate) & "-" & (month of currDate) & "-" & (day of currDate)) make new folder at bLocation with properties {name:folderName} return true end tell end hasNotBackedUpToday (* * force VMs to power off, quit VM app *) on powerOffVMsQuitFusion() tell application "VMware Fusion" activate -- can't test to see if a VM is suspended unless VMware is running delay 10 -- give the application time to open repeat with currVM in documents set powerState to power state of currVM -- power off doesn't work on suspended VMs if powerState is suspended then -- VM reports powered off even when actually suspended, reports correctly if VM's own window open (VM Library, right-click on VM, then select "Show Windows") --display dialog "VM " & (name of currVM) & " is suspended" resume currVM -- only want to resume if actually suspended, otherwise it starts powered off VMs delay resumeDelay -- give VM time to resume end if if powerState is powered on then --display dialog "Name: " & (name of currVM) --display dialog "Name: " & (OS name of currVM) -- XP unsaved docs prevent power off unless with force, Win7 works without force try (*if (OS name of currVM) contains "7" then --display dialog "Win 7: would power off withOUT force" power off currVM delay powerOffDelay else*) --display dialog "Not Win 7 (XP, etc.): would power off with force" power off currVM with force --end if on error errMsg number errNum tell application "Finder" display dialog ("errMsg: " & errMsg & ", errNum: " & errNum) end tell end try end if end repeat quit delay 5 end tell end powerOffVMsQuitFusion (* * Back up VMs, deleting oldest backup if necessary *) on backupVMs(thisLocation, thisVMsLocation) tell application "Finder" set thisBackupLocation to POSIX file thisLocation as alias sort (get folders of thisBackupLocation) by creation date set myFinderResult to result -- This raises an error if the folder doesn't contain any files if ((count of myFinderResult) = 0) then display dialog "Error. What happened to the folder that was just created?" return false else set backupFolder to (item 1 of myFinderResult) --display dialog "Folder name: " & (name of backupFolder) -- check to see if folder is empty if ((count files of backupFolder) is not equal to 0) then display dialog "Error. Backup folder wasn't empty." return false end if -- copy virtual machines to backup folder --set vmsLocation to alias "Macintosh HD:Users:mikeong:Documents:Virtual Machines" set vmsLocation to alias thisVMsLocation duplicate every file of vmsLocation to backupFolder return true end if end tell end backupVMs (* Applescript应用程序在系统空闲一定时间后自动备份虚拟机 要求: []关闭虚拟机时,必须在VMWare Fusion“首选项…”->“常规”->“中选择“关闭虚拟机电源”:这是必需的,因为如果虚拟机窗口关闭,则即使虚拟机实际处于“挂起”状态,VMWare也会将虚拟机的电源状态报告为“关闭电源”;并且无法从文档对象访问其窗口 []在“系统首选项…”->“节能器”->“电源适配器”->“计算机睡眠”必须设置为大于+后的备份值(每*2检查一次) http://culturedcode.com/forums/read.php?7,30174,30597 要使此应用程序可运行,请另存为应用程序。 要不在Dock中显示,请仅在已创建应用程序包的Info.plist中设置LSBackgroundOnly,或以其他方式在中设置LSBackgroundOnly http://groups.google.com/group/macenterprise/browse_thread/thread/be7db35451e1dc70 *) 属性下班时间:8--23--一天中开始监控空闲时间的时间 属性workDayStarts:每天5小时停止监视空闲状态 属性备份持续时间:2--备份虚拟机所需的小时数 全局备份\u之后,检查\u every--TODO:这些真的需要全局备份吗? 将backup_after设置为10--(40*60)--秒 将check_every设置为5--(10*60) 属性cancelTimer:60--用户必须取消备份的秒数 属性虚拟化应用程序:“VMware Fusion”--变量不能用于“告诉应用程序”语句或无法编译,因此搜索并替换“VMware Fusion”的其他实例 属性恢复延迟:120--(4*60)--以秒为单位;通常在那之后需要备份 --测试以查看今天是否已完成备份 如果我的hasNotBackedUpToday(反向上传)那么 --警告用户VM应用程序将强制关闭VM 用secondsLeft从cancelTimer到1乘-1重复此操作 将dialogResult设置为显示警报virtualizationApp&“即将强制退出并备份虚拟机”消息“此AppleScript设置为强制关闭”&virtualizationApp&“,如果它已打开,则其虚拟机,然后备份虚拟机。”&return&return&“单击\”取消\将这些操作延迟到以后,或按“确定”退出并备份。&return&return&secondsLeft&secondsLeft&seconds。按钮{“确定”、“取消”}默认按钮“确定”作为警告在1后放弃 如果secondsLeft=1或(dialogResult返回的按钮)为“OK”,则 --强制虚拟机关闭电源,退出虚拟机应用程序 我的力量 --备份虚拟机 如果我的backupVMs(backupLocation,virtualMachinesLocation)那么 显示对话框“已成功备份虚拟机” 其他的 显示对话框“备份虚拟机失败” 如果结束 退出重复 否则,如果(dialogResult返回的按钮)为“取消”,则 显示对话框“备份延迟到以后” 退出重复 如果结束 结束重复 其他的 返回(8*60*60)--今天已备份,请在8小时后重试 如果结束 如果结束 退票 如果结束 结束语 结束空闲 (* *检查是否在过去16小时内备份了 *) 在hasNotBackedUpToday(位置) 告诉应用程序“查找器” 将bLocation设置为POSIX文件的位置作为别名 按创建日期排序(获取bLocation的文件夹) 将myResult设置为result 将myResultCount设置为myResult的计数 --如果文件夹不包含任何文件,则会引发错误 如果(myResultCount不等于0),则 将文件设置为(myResult的第1项) 若文件的创建日期大于((当前日期)-(16*60*60)),则 --显示对话框“今天已备份” 返回错误 如果结束 如果结束 --如果已达到最大值,请删除备份 如果myResultCount≥ 那就闭嘴吧 删除项目myResultCount的myResult 如果结束