【Management】Hyper-V ゲスト OS のサービス状態を ホスト OS に問い合わせる

もう1年以上も前に、以下の投稿をしました。

Hyper-V の「データ交換」機能を使用すると、「ホスト OS」経由で「ゲスト OS」の情報を知ることができます。

※具体的な方法は上記の投稿を参照してください

この機能の何が便利かというと、ゲストOSにネットワーク的に接続できなくても、ホストに問い合わせれば情報が得られるというところです。マルチテナントなどの理由で、ホストとゲストのネットワーク的な接続性を無効にしている場合には有用でしょう。

既定で参照可能な情報は、以下のようなものです。

  • FullyQualifiedDomainName:TF20101102-01.tf.com
  • OSName:Windows Server 2008 R2 Enterprise
  • OSVersion:6.1.7600
  • CSDVersion
    OSMajorVersion:6
  • OSMinorVersion:1
  • OSBuildNumber:7600
  • OSPlatformId:2
  • ServicePackMajor:0
  • ServicePackMinor:0
  • SuiteMask:274
  • ProductType:2
  • OSEditionId:10
  • ProcessorArchitecture:9
  • IntegrationServicesVersion:6.1.7600.16385
  • NetworkAddressIPv4:192.168.200.1;192.168.200.10;xxx.xx....
  • NetworkAddressIPv6:2002:xxxx:f0a7::xxxx:f0a7
  • RDPAddressIPv4:192.168.200.1;192.168.200.10;xxx.xx....
  • RDPAddressIPv6:2002:xxxx:f0a7::xxxx:f0a7

これらの情報から、ゲスト OS の基本的な情報を知ることができます。

上記の値は、ゲストOSの以下のレジストリパスに書かれています。

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\Virtual Machine
\Auto

では、業務に特化した独自の情報をホストOS経由で知りたい...といった場合にはどうしたらよいでしょう?

あくまでも「マイクロソフトにサポートされた方式ではない」という前提で書きますが、上記のレジストリパスに書いてしまえばよいのです。

ただし、OS の再起動により(Hyper-V Data Exchange Service の再起動ではなく)独自に追加したエントリはクリアされるので注意してください。

例えば、ゲストOSにインストールされているサービスの状態を監視したい場合には、以下のようなスクリプトを定期的に実行して上記のキーに書き込み、ホスト側からも定期的に取りだせばよいわけです。

以下の例では、PowerShell を使用しています。$Svc に サービスの状態一覧を格納し、Set-ItemProperty コマンドレットを使用してレジストリに各サービスの状態を格納しています。本当は Reg_Multi_SZ 形式で全てのサービスの状態を1つのValueで格納するのが美しいのですが、この形式だとホスト側から KVP Exchange を介してデータが受け取れないようなのです。仕方がないので、ちょっとアレかなぁとは思いつつ、String 形式で1サービス 1 Value で格納しています(もっと良い方法をお持ちの方、教えてください!)。

※以下はゲスト側で実行するスクリプトです

PS C:\> $regpath_auto = "HKLM:Software\Microsoft\Virtual Machine\auto" PS C:\> $svc=Get-Service PS C:\> foreach($svcstatus in $svc){Set-ItemProperty -path $regpath_auto -name $svcstatus.Name -value $svcstatus.Status -type String}

上記のスクリプトの結果、Auto キーには以下のようなデータが格納されます。うーん、美しくない....。ま、とりあえず、それぞれのサービスの起動状態

image

あとはホスト側で以下のようなスクリプトを実行して、サービスの状態を取得すればOKです。

※以下のスクリプとはホスト側、もしくはホストと通信可能なマシンで実行します

PS C:\> Cred = Get-Credential localhost\administrator PS C:\> $GUEST1 = Get-WmiObject -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='<Hyper-V管理ツール上でのゲストOSの名前>'" –ComputerName <ホストOSのホスト名> -Credential $Cred PS C:\> $Kvp = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Guest1} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent" –ComputerName <ホストOSのホスト名> -Credential $Cred

PS C:\> filter Import-CimXml { $CimXml = [Xml]$_ $CimObj = New-Object -TypeName System.Object foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY")) { $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE } $CimObj }

PS C:\> $kvp.GuestIntrinsicExchangeItems | Import-CimXml | ft Name,Data

取得した結果は以下のようなかんじで表示されるはずです。赤い文字であらわした部分が、ゲストOS上で動作しているサービスの状態です。

PS C:\> $kvp.GuestIntrinsicExchangeItems | Import-CimXml | ft Name,Data

Name Data ---- ---- FullyQualifiedDomainName TF20101102-01.tf.com OSName Windows Server 2008 R2 Enterprise OSVersion 6.1.7600 CSDVersion OSMajorVersion 6 OSMinorVersion 1 OSBuildNumber 7600 OSPlatformId 2 ServicePackMajor 0 ServicePackMinor 0 SuiteMask 274 ProductType 2 OSEditionId 10 ProcessorArchitecture 9 IntegrationServicesVersion 6.1.7600.16385 NetworkAddressIPv4 192.168.200.1;192.168.200.10;157.60.... NetworkAddressIPv6 2002:9d3c:f0a7::9d3c:f0a7 RDPAddressIPv4 192.168.200.1;192.168.200.10;157.60.... RDPAddressIPv6 2002:9d3c:f0a7::9d3c:f0a7 adfssrv Running ADWS Running AeLookupSvc Running ALG Stopped AppHostSvc Running AppIDSvc Stopped Appinfo Stopped AppMgmt Stopped aspnet_state Stopped AudioEndpointBuilder Stopped AudioSrv Stopped BFE Running BITS Stopped Browser Stopped c2wts Stopped CertPropSvc Running clr_optimization_v2.0.50727_32 Stopped clr_optimization_v2.0.50727_64 Stopped clr_optimization_v4.0.30319_32 Stopped clr_optimization_v4.0.30319_64 Stopped COMSysApp Stopped CryptSvc Running DcomLaunch Running defragsvc Stopped Dfs Running DFSR Running Dhcp Running DNS Running Dnscache Running dot3svc Stopped DPMRA Stopped DPS Running EapHost Stopped EFS Stopped eventlog Running EventSystem Running FCRegSvc Stopped fdPHost Stopped FDResPub Stopped FontCache Stopped FontCache3.0.0.0 Stopped FwcAgent Running gpsvc Running hidserv Stopped hkmsvc Stopped idsvc Stopped IKEEXT Running IPBusEnum Stopped iphlpsvc Running IsmServ Running kdc Running KeyIso Stopped KtmRm Stopped LanmanServer Running LanmanWorkstation Running lltdsvc Stopped lmhosts Running MMCSS Stopped MpsSvc Running MSDTC Running MSiSCSI Stopped msiserver Stopped MSSQL$MICROSOFT##SSEE Running napagent Stopped Netlogon Running Netman Running NetMsmqActivator Stopped NetPipeActivator Stopped netprofm Running NetTcpActivator Stopped NetTcpPortSharing Stopped NlaSvc Running nsi Running NTDS Running NtFrs Stopped PerfHost Stopped pla Stopped PlugPlay Running PolicyAgent Running Power Running ProfSvc Running ProtectedStorage Stopped RasAuto Stopped RasMan Stopped RemoteAccess Stopped RemoteRegistry Running RpcEptMapper Running RpcLocator Stopped RpcSs Running RSoPProv Stopped sacsvr Stopped SamSs Running SCardSvr Stopped Schedule Running SCPolicySvc Stopped seclogon Stopped SENS Running SessionEnv Running SharedAccess Stopped ShellHWDetection Running SNMPTRAP Stopped Spooler Running sppsvc Running sppuinotify Stopped SQLWriter Running SSDPSRV Stopped SstpSvc Stopped swprv Stopped TapiSrv Stopped TBS Stopped TermService Running THREADORDER Stopped TrkWks Stopped TrustedInstaller Running UI0Detect Stopped UmRdpService Running upnphost Stopped UxSms Running VaultSvc Stopped vds Running vmicheartbeat Running vmickvpexchange Running vmicshutdown Running vmictimesync Running vmicvss Running VSS Stopped W32Time Running W3SVC Running WAS Running WcsPlugInService Stopped WdiServiceHost Stopped WdiSystemHost Stopped Wecsvc Stopped wercplsupport Stopped WerSvc Stopped WinHttpAutoProxySvc Stopped Winmgmt Running WinRM Running wmiApSrv Stopped WPDBusEnum Running wuauserv Running wudfsvc Stopped

PS C:\>

次回はホストからゲストにメッセージを送付する方法について投稿します。