2010/06/29

Hyper-V Scripting: テキスト ベースの Hyper-V マネージャー

(今は亡き)Windows Server World 2008年12月号(IDGジャパン)で、特集「“寄せ集め”スクリプト作成術」を書きました。この記事の中で Windows Server 2008 Server Core での利用を想定したシステム構成ツールと、テキスト ベースのイベント ビューアー (http://yamanxworld.blogspot.com/2009/11/blog-post.html)、テキスト ベースの Hyper-V マネージャー (hvmンgrcui.cmd) を紹介しました。テキスト ベースの Hyper-V マネージャーについては、当時、誌面の都合上、コードなどはばっさりカットされてしまいましたが、Hyper-V 2.0 環境でも動くし、個々のツールは単体でも活用できるものなので、記事よりちょっとだけ機能拡張したものを公開したいと思います。

テキスト ベースの Hyper-V マネージャーは、メニュー用のバッチ ファイル (hvmngrcui.cmd) と 4 つの VBScript ファイル (hvvmstat.vbs、hvvmstart.vbs、hvvmsave.vbs、hvvmshut.vbs) で構成され、仮想マシンのステータスの一覧表示、仮想マシンの開始、保存、シャットダウンに対応ができます。完全にコマンドライン (Cmd.exe) だけで動くので、Server Core インストールの Hyper-V ホストや、Microsoft Hyper-V Server 2008 R2 などで仮想マシンを制御するのに利用できます。

[hvmngrcui.cmd]
メニュー用のバッチ ファイルです。
@echo off
:STARTMENU
CLS
echo.
echo Hyper-V Manager (CUI)
echo ───────────────────────────────────────
echo 仮想マシン (ローカル)
echo.
cscript //NoLogo hvvmstat.vbs
echo.
echo ------------------------------------------------------------------------------
echo [ 開始(1) ][ 保存(2) ][ シャットダウン(3) ][ 終了(Q) ]
echo.
SET /P INPUTKEY=メニューを選択して下さい:
if %INPUTKEY% == Q goto END
if %INPUTKEY% == q goto END
if %INPUTKEY% == 1 goto STARTVM
if %INPUTKEY% == 2 goto SAVEVM
if %INPUTKEY% == 3 goto SHUTDOWNVM
goto STARTMENU

:STARTVM
echo.
cscript //NoLogo hvvmstart.vbs
PAUSE
goto STARTMENU

:SAVEVM
echo.
cscript //NoLogo hvvmsave.vbs
PAUSE
goto STARTMENU

:SHUTDOWNVM
echo.
cscript //NoLogo hvvmshut.vbs
PAUSE
goto STARTMENU

:END

[hvvmstat.vbs]
仮想マシンを一覧表示します。単体 (cscript hvvmstat.vbs) でも利用できます。
Option Explicit
Dim WMIService, VMs, VM

If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
  WScript.Echo "このスクリプトはCSCRIPT.EXEを使用して実行して下さい。"
  WScript.Quit
End if

Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem")
WScript.Echo "状態 仮想マシン名"
WScript.Echo "-------------- --------------------------------------------------------------"
For Each VM In VMs
  if VM.Caption = "仮想マシン" then
    Select Case VM.EnabledState
    Case 2
      WScript.StdOut.Write "実行中 " 'Running
    Case 3
      WScript.StdOut.Write "オフ " 'Stoped
    Case 32768
      WScript.StdOut.Write "一時停止 " 'Paused
    Case 32769
      WScript.StdOut.Write "保存完了 " 'Saved
    Case 32770
      WScript.StdOut.Write "開始中.. " 'Starting
    Case 32771
      WScript.StdOut.Write "SnapShot作成中.." 'Snapshotting
    Case 32772
      WScript.StdOut.Write "移行中.. " 'Migrating
    Case 32773
      WScript.StdOut.Write "保存中.. " 'Saving
    Case 32774
      WScript.StdOut.Write "停止中.. " 'Stopping
    Case 32775
      WScript.StdOut.Write "削除 " 'Deleted
    Case 32776
      WScript.StdOut.Write "一時停止中... " 'Pausing
    Case Else
      WScript.StdOut.Write "不明 " 'Unknown
    End Select
    WScript.Echo VM.ElementName
  end if
Next

[hvvmstart.vbs]
指定した仮想マシンを開始します。単体 (cscript hvvmstart.vbs "仮想マシン名") でも利用できます。

Option Explicit
Dim arg, targetVM, WMIService, VMs, InputKey

If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
  WScript.Echo "このスクリプトはCSCRIPT.EXEを使用して実行して下さい。"
  WScript.Quit
End if

Set arg = WScript.Arguments
if arg.Count = 0 then
  WScript.StdOut.Write "開始する仮想マシン名を入力して下さい: "
  InputKey = Trim(WScript.StdIn.ReadLine)
  If InputKey <> "" then
    targetVM = InputKey
  Else
    WScript.Echo "仮想マシン名が入力されませんでした。中止します。"
    WScript.Quit
  End If
else
  targetVM = arg(0)
end if

Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")

Select Case VMs.ItemIndex(0).EnabledState
Case 3, 32768, 32769
  WScript.StdOut.Write targetVM & " を開始します"
  VMs.ItemIndex(0).RequestStateChange(2)
  Do while VMs.ItemIndex(0).EnabledState > 2
    Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
    WScript.StdOut.Write(".")
    WScript.sleep 100
  Loop
  WScript.Echo "完了"
Case 2
  WScript.Echo targetVM & " は既に動作しています。"
Case Else
  WScript.Echo targetVM & " を開始できません。"
End Select

[hvvmsave.vbs]
指定した仮想マシンの状態を保存して停止にします。単体 (cscript hvvmsave.vbs "仮想マシン名") でも利用できます。
Option Explicit
Dim arg, targetVM, WMIService, VMs, InputKey

If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
  WScript.Echo "このスクリプトはCSCRIPT.EXEを使用して実行して下さい。"
  WScript.Quit
End if

Set arg = WScript.Arguments
if arg.Count = 0 then
  WScript.StdOut.Write "状態を保存する仮想マシン名を入力して下さい: "
  InputKey = Trim(WScript.StdIn.ReadLine)
  If InputKey <> "" then
    targetVM = InputKey
  Else
    WScript.Echo "仮想マシン名が入力されませんでした。中止します。"
    WScript.Quit
  End If
else
  targetVM = arg(0)
end if

Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")

Select Case VMs.ItemIndex(0).EnabledState
Case 2
  WScript.StdOut.Write targetVM & " を保存します"
  VMs.ItemIndex(0).RequestStateChange(32769)
  Do while VMs.ItemIndex(0).EnabledState <> 32769
    Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")
    WScript.StdOut.Write(".")
    WScript.sleep 100
  Loop
  WScript.Echo "完了"
Case Else
  WScript.Echo targetVM & " は動作していません。"
End Select

[hvvmshut.vbs]
指定した仮想マシンをシャットダウンします。単体 (cscript hvvmshut.vbs "仮想マシン名") でも利用できます。 記事にはなかった機能です。
Option Explicit
Dim arg, targetVM, WMIService, VMs, InputKey, VMshut, VMshutRet

If Right((LCase(WScript.FullName)),11) <> "cscript.exe" then
  WScript.Echo "このスクリプトはCSCRIPT.EXEを使用して実行して下さい。"
  WScript.Quit
End if

Set arg = WScript.Arguments
if arg.Count = 0 then
  WScript.StdOut.Write "シャットダウンを開始する仮想マシン名を入力して下さい: "
  InputKey = Trim(WScript.StdIn.ReadLine)
  If InputKey <> "" then
    targetVM = InputKey
  Else
    WScript.Echo "仮想マシン名が入力されませんでした。中止します。"
    WScript.Quit
  End If
else
  targetVM = arg(0)
end if

Set WMIService = GetObject("winmgmts:\\.\root\virtualization")
Set VMs = WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & targetVM & "'")

Select Case VMs.ItemIndex(0).EnabledState
Case 2
  WScript.StdOut.Write targetVM & " のシャットダウンを開始します。"
  Set VMshut = WMIService.ExecQuery("SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='" & VMs.ItemIndex(0).Name & "'")
  VMshutRet = VMshut.ItemIndex(0).InitiateShutdown(True,"shutdown by script")
  if VMshutRet = 0 then
    WScript.Echo "... 成功しました。"
  else
    WScript.Echo targetVM & " ... 失敗しました。"
  end if
Case Else
  WScript.Echo targetVM & " は動作していません。"
End Select

0 件のコメント: