WIN1@Codename

Codename

Hyper-V をプログラムでどうにかしてみる VBScript その11 (SCSIディスクの追加)

前回、SCSIコントローラーを追加しましたので、今度はSCSIハードディスクを追加してみます。
少々手順が複雑なのですが、まずはディスクドライブを追加した上で、vhdハードディスクを接続するといった手順になります。

Option Explicit

Dim strServerName, strVMName, strDiskPath, objWMIService, objManagementService
strServerName = "."
strVMName = "TestVM"  
strDiskPath = "E:\Hyper-V\TestVM\ScsiDisk.vhd"
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\virtualization")
Set objManagementService = objWMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemManagementService").ItemIndex(0)

Call SetScsiDiskDrive(strVMName)
Call SetScsiHardDisk(strVMName, strDiskPath)

Function SetSCSIHardDisk(strVMName, strDiskPath)
    Dim objComputerSystem
    Set objComputerSystem = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'").ItemIndex(0)
  
    Dim objResourcePool
    Set objResourcePool = objWMIService.ExecQuery("SELECT * FROM Msvm_ResourcePool WHERE ResourceType = 21 AND ResourceSubType = 'Microsoft Virtual Hard Disk' AND OtherResourceType = null").ItemIndex(0)

    Dim objAllocationCapabilities
    Set objAllocationCapabilities = objWMIService.ExecQuery("ASSOCIATORS OF {" & objResourcePool.Path_.Path & "} WHERE ResultClass = Msvm_AllocationCapabilities").ItemIndex(0)
   
    Dim objSettingsDefineCapabilities
    Set objSettingsDefineCapabilities = objWMIService.ExecQuery("REFERENCES OF {" & objAllocationCapabilities.Path_.Path & "} WHERE ResultClass = Msvm_SettingsDefineCapabilities").ItemIndex(0)
  
    Dim objHardDisk
    If objSettingsDefineCapabilities.ValueRole = 0 Then
        Set objHardDisk = objWMIService.Get(objSettingsDefineCapabilities.PartComponent)
    End If

    Dim objVirtualSystemSettingData
    Set objVirtualSystemSettingData = objWMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemSettingData WHERE ElementName = '" & strVMName & "'").ItemIndex(0)

    Dim objSCSIController, objResourceAllocationSettingData
    Set objResourceAllocationSettingData = objWMIService.ExecQuery("Associators of {Msvm_VirtualSystemSettingData='" & objVirtualSystemSettingData.InstanceID & "'} Where ResultClass=Msvm_ResourceAllocationSettingData AssocClass=Msvm_VirtualSystemSettingDataComponent")
    For Each objSCSIController In objResourceAllocationSettingData   
        If objSCSIController.ResourceSubType = "Microsoft Synthetic SCSI Controller" Then
Exit For
        End If
    Next

    Dim objDiskDrive, strDiskPaths
    strDiskPaths = Array(1)
    strDiskPaths(0) = strDiskPath
    Set objDiskDrive = objWMIService.ExecQuery("SELECT * FROM Msvm_ResourceAllocationSettingData WHERE Parent = '" & Replace(objSCSIController.Path_.Path, "\", "\\") & "' AND Address = '0'").ItemIndex(0)
    objHardDisk.Parent = objDiskDrive.Path_.Path
    objHardDisk.Connection = strDiskPaths
   
    Dim strResourceSettingData
    strResourceSettingData = Array(1)
    strResourceSettingData(0) = objHardDisk.GetText_(1)  

    Dim objInParam, objOutParams
    Set objInParam = objManagementService.Methods_("AddVirtualSystemResources").InParameters.SpawnInstance_()
    objInParam.ResourceSettingData = strResourceSettingData
    objInParam.TargetSystem = objComputerSystem.Path_.Path
    Set objOutParams = objManagementService.ExecMethod_("AddVirtualSystemResources", objInParam)

    Call JobCompleted(objOutParams, objWMIService)
End Function

Function SetSCSIDiskDrive(strVMName)
    Dim objComputerSystem
    Set objComputerSystem = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'").ItemIndex(0)

    Dim objResourcePool
    Set objResourcePool = objWMIService.ExecQuery("SELECT * FROM Msvm_ResourcePool WHERE ResourceType = 22 AND ResourceSubType = 'Microsoft Synthetic Disk Drive' AND OtherResourceType = null").ItemIndex(0)

    Dim objAllocationCapabilities
    Set objAllocationCapabilities = objWMIService.ExecQuery("ASSOCIATORS OF {" & objResourcePool.Path_.Path & "} WHERE ResultClass = Msvm_AllocationCapabilities").ItemIndex(0)
   
    Dim objSettingsDefineCapabilities
    Set objSettingsDefineCapabilities = objWMIService.ExecQuery("REFERENCES OF {" & objAllocationCapabilities.Path_.Path & "} WHERE ResultClass = Msvm_SettingsDefineCapabilities").ItemIndex(0)
  
    Dim objDiskDrive
    If objSettingsDefineCapabilities.ValueRole = 0 Then
        Set objDiskDrive = objWMIService.Get(objSettingsDefineCapabilities.PartComponent)
    End If

    Dim objVirtualSystemSettingData
    Set objVirtualSystemSettingData = objWMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemSettingData WHERE ElementName = '" & strVMName & "'").ItemIndex(0)
   
    Dim objSCSIController, objResourceAllocationSettingData
    Set objResourceAllocationSettingData = objWMIService.ExecQuery("Associators of {Msvm_VirtualSystemSettingData='" & objVirtualSystemSettingData.InstanceID & "'} Where ResultClass=Msvm_ResourceAllocationSettingData AssocClass=Msvm_VirtualSystemSettingDataComponent")
    For Each objSCSIController In objResourceAllocationSettingData   
        If objSCSIController.ResourceSubType = "Microsoft Synthetic SCSI Controller" Then
Exit For
        End If
    Next
 
    objDiskDrive.Parent = objSCSIController.Path_.Path
    objDiskDrive.Address = 0

    Dim strResourceSettingData
    strResourceSettingData = Array(1)
    strResourceSettingData(0) = objDiskDrive.GetText_(1)  

    Dim objInParam, objOutParams
    Set objInParam = objManagementService.Methods_("AddVirtualSystemResources").InParameters.SpawnInstance_()
    objInParam.ResourceSettingData = strResourceSettingData
    objInParam.TargetSystem = objComputerSystem.Path_.Path
    Set objOutParams = objManagementService.ExecMethod_("AddVirtualSystemResources", objInParam)

    Call JobCompleted(objOutParams, objWMIService) 
End Function

Function JobCompleted(objOutParams, objWMIService)
    Dim objJob
    If (objOutParams.ReturnValue = 0) Then
        Wscript.Echo "OK"
    ElseIf (objOutParams.ReturnValue <> 4096) Then
        Wscript.Echo "NG"
        Wscript.Echo objOutParams.ReturnValue
    Else  
        Set objJob = objWMIService.Get(objOutParams.Job)
        While (objJob.JobState = 3) Or (objJob.JobState = 4)
WScript.Sleep(1000)
Set objJob = objWMIService.Get(objOutParams.Job)
        Wend
        If (objJob.JobState <> 7) Then
Wscript.Echo "NG"
Wscript.Echo "ErrorCode:" & objJob.ErrorCode
Wscript.Echo "ErrorDescription:" & objJob.ErrorDescription
        Else
Wscript.Echo "OK"
        End If
    End If
End Function

長いです。。。
スクリプトでこの長さはいやになってしまいますね。
ここまでになると、VB.netに切り替えたほうがよかなと思います。

Hyper-V をプログラムでどうにかしてみる VBScript その10 (SCSIコントローラーの設定)

通常仮想マシンにはIDE経由の仮想ハードディスクを接続しますが、SCSIディスクを使用するとホットスワップ対応なので、仮想マシンの稼働中でもハードディスクの取り付け、取り外しが可能となります。
(OS使用領域は除く)

今回はSCSIハードディスクを使用するためにSCSIコントローラーを追加するスクリプトの紹介となります。

Option Explicit

Dim strServerName, strVMName, objWMIService, objManagementService
strServerName = "."
strVMName = "TestVM" 
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\virtualization")
Set objManagementService = objWMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemManagementService").ItemIndex(0)

Call SetScsiController(strVMName)

Function SetScsiController(strVMName)
    Dim objComputerSystem
    Set objComputerSystem = objWMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'").ItemIndex(0)

    Dim objResourcePool
    Set objResourcePool = objWMIService.ExecQuery("SELECT * FROM Msvm_ResourcePool WHERE ResourceType = 22 AND ResourceSubType = 'Microsoft Synthetic Disk Drive' AND OtherResourceType = null").ItemIndex(0)

    Dim objAllocationCapabilities
    Set objAllocationCapabilities = objWMIService.ExecQuery("ASSOCIATORS OF {" & objResourcePool.Path_.Path & "} WHERE ResultClass = Msvm_AllocationCapabilities").ItemIndex(0)
   
    Dim objSettingsDefineCapabilities
    Set objSettingsDefineCapabilities = objWMIService.ExecQuery("REFERENCES OF {" & objAllocationCapabilities.Path_.Path & "} WHERE ResultClass = Msvm_SettingsDefineCapabilities").ItemIndex(0)
  
   Dim objSCSIController
    Set objSCSIController = objWMIService.ExecQuery("SELECT * FROM Msvm_ResourceAllocationSettingData WHERE ResourceType = 6 AND ResourceSubType = 'Microsoft Synthetic SCSI Controller' AND OtherResourceType = null").ItemIndex(0)
    objSCSIController.ElementName = "SCSI コントローラー"

    Dim strResourceSettingData
    strResourceSettingData = Array(1)
    strResourceSettingData(0) = objSCSIController.GetText_(1)  

    Dim objInParam, objOutParams
    Set objInParam = objManagementService.Methods_("AddVirtualSystemResources").InParameters.SpawnInstance_()
    objInParam.ResourceSettingData = strResourceSettingData
    objInParam.TargetSystem = objComputerSystem.Path_.Path
    Set objOutParams = objManagementService.ExecMethod_("AddVirtualSystemResources", objInParam)

    Call JobCompleted(objOutParams, objWMIService)
End Function

Function JobCompleted(objOutParams, objWMIService)
    Dim objJob
    If (objOutParams.ReturnValue = 0) Then
        Wscript.Echo "OK"
    ElseIf (objOutParams.ReturnValue <> 4096) Then
        Wscript.Echo "NG"
        Wscript.Echo objOutParams.ReturnValue
    Else  
        Set objJob = objWMIService.Get(objOutParams.Job)
        While (objJob.JobState = 3) Or (objJob.JobState = 4)
WScript.Sleep(1000)
Set objJob = objWMIService.Get(objOutParams.Job)
        Wend
        If (objJob.JobState <> 7) Then
Wscript.Echo "NG"
Wscript.Echo "ErrorCode:" & objJob.ErrorCode
Wscript.Echo "ErrorDescription:" & objJob.ErrorDescription
        Else
Wscript.Echo "OK"
        End If
    End If
End Function

スクリプトはPowerShell? WSH?

マイクロソフトのスクリプトセンター、
http://technet.microsoft.com/ja-jp/scriptcenter/

サンプルコードが世界中から投稿されていますが、スクリプトと呼ばれるものの定義としては「メモ帳などで簡単に作成編集できるもの」という感じでしょうか。

以前はバッチファイルとして、サーバー管理者などが定期的な処理作業を簡略化するために、コマンドを組み合わせたものを使用するのが一般的でした。

Windows Script Host(WSH)がWindows98に搭載されるようになると、Windows上の簡単な処理はVBScriptでメモ帳などを使用して簡単に作れるようになりました。

中には数MBにおよぶ膨大なスクリプトをみかけることもありますが、やはりスクリプトは手軽に簡単にがキーワードとなるようです。

最近では、スクリプトがWSHのほかにPowerShellを使用して作成される機会が増えてきたようです。

Windows制御のコマンドラインの集まりで、.NetFramework を利用できるのが最大の特徴ではないでしょうか。 VisualStudioでプログラムを書くほどではないけれども、WSHでは面倒な処理もPowerShellでは簡単にコードが書けるといったものがかなりあるようです。

ただ、あまりにもコマンドがありすぎて、お目当てのコマンドを探し出すのが結構大変な場合もあります。

TPOにあわせて、WSHとPowerShellを使い分けることでさらに効率的なスクリプト作成ができるようになりますね。

FC2Ad