自動啟動/停止腳本程式

以下的 PowerShell 腳本程式是用以啟動和停止虛擬機器,它會在特定事件發生時被 Task Scheduler 叫用。位於程式開頭的一些變數必須先根據你的實體主機系統設定好。

  • $vmrun_path:VMrun.exe 程式的完整路徑。
  • $auto_vms_path:含有你的虛擬機器之完整路徑。
  • $start_delay:啟動兩個虛擬機器之間的延遲秒數。
  • $stop_delay:停止或暫停兩個虛擬機器之間的延遲秒數。

函式 Get-AutoVMs 是此腳本程式裡的一個工作主力。它找出位於 $auto_vms_path 中,必須被控制的虛擬機器,根據每個虛擬機器檔案夾裡的 +autovm.nn (nn 是啟動順序號碼) 檔案名稱排序好,再將它們送回。

例如,若一個虛擬機器的檔案夾中,有一個檔案 +autovm.03,則它會在有檔案 +autovm.05 的虛擬機器之前被啟動。停止/暫停的順序是啟動順序的相反。要停用一個虛擬機器的自動啟動/停止,你只需要刪除檔案 +autovm.nn 或改名為像是 -autovm.nn

腳本程式內真正控制虛擬機器的部分是兩個 foreach 迴路,一個用來啟動它們,另一個用來停止/暫停它們。那兩個迴路使用 VMrun.exe 程式。啟動一虛擬機器,程式碼

& "$vmrun_path" -T ws start "$vm" nogui

被用到,nogui 指定它會在背景執行且沒有 GUI。停止和暫停一虛擬機器,程式使用

& "$vmrun_path" -T ws $command "$vm" $option

其中 $command 可以是 'stop' 或 'suspend',$option 可以是 'hard' 或 'soft'。當使用選項 'soft',VMware 會要求客戶系統先執行對應的腳本程式。當使用選項 'hard',客戶系統將不會有機會執行它的腳本程式。

# Get script arguments
# $command: start, stop or suspend
# $option: hard or soft when $command is stop or suspend
param ([string] $command, [string] $option = "soft")

## defaults
# location of vmrun.exe
$vmrun_path = "${Env:ProgramFiles(x86)}\VMware\VMware VIX\VMrun.exe"
# location of virtual machine directory
$auto_vms_path = "E:\Virtual Machines"
# delay interval (in seconds) for starting up and stopping VMs
$start_delay = 90
$stop_delay = 30

## functions
# Get VMs to be auto-started at $path sorted by +autovms.xx name.
function Get-AutoVMs($path) {
    Get-ChildItem "$path\*\+autovm.*" | Sort-Object Name `
    | ForEach-Object {$_.DirectoryName+"\*.vmx"} | Get-ChildItem `
    | ForEach-Object {$_.FullName}
}

# Get running VMs
# NOTE: this only works this VMs started in the same session, so we can't use it here.
function Get-RunningVMs() {
    & "$vmrun_path" -T ws list | Where-Object {$_.EndsWith(".vmx")} `
    | Sort-Object -Descending
}

## main program
if ($command.ToLower() -eq "start") {
    # Retrieve VMs to be auto-start
    $auto_vms = @(Get-AutoVMs $auto_vms_path)

    # Start each VM in the list
    foreach ($vm in $auto_vms) {
        & "$vmrun_path" -T ws start "$vm" nogui
        # Delay a little while.
        if ($vm -ne $auto_vms[-1])
            { Start-Sleep -Seconds $start_delay }
    }
    
    exit 10

} elseif ((("stop", "suspend") -contains $command.ToLower()) `
         -and (("soft", "hard") -contains $option.ToLower())) {
    # Retrieve VMs, and reverse its order.
    #$auto_vms = @(Get-RunningVMs)
    $auto_vms = @(Get-AutoVMs $auto_vms_path)
    [Array]::Reverse($auto_vms)

    # Suspend each VM in the running list.
    foreach ($vm in $auto_vms) {
        & "$vmrun_path" -T ws $command "$vm" $option
        # Delay a little while.
        if ($vm -ne $auto_vms[-1]) 
            { Start-Sleep -Seconds $stop_delay }
    }
    
    exit 20
}

exit 1

允許腳本程式執行

當你儲存了腳本程式到你的電腦上並試著執行它,會發現你不被允許執行它。那是因為在 Windows 7 上,預設的 ExecutionPolicy 是限制所有 PowerShell 腳本程式的執行。你必須改變 ExecutionPolicy 來允許一個管理員帳戶執行本地的 PowerShell 腳本程式。那個管理員帳戶將也是用來執行 Task Scheduler 動作。

首先,找到 Windows Powershell 於 Start Menu -> All Programs -> Accessories -> Windows Powershell。用右鍵點按它,並選用 'Run as administrator' 如果你不是以管理員帳戶登入。在指令提示輸入此指令

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

(如 PIC-1)。那將使該管理員帳戶能夠執行本地與簽屬過的遠端 PowerShell 腳本程式。

PIC-1 Set-ExecutionPolicy

FaLang translation system by Faboba