【PowerShell】依存関係チェッカーに学ぶ、必須ソフトウェアのチェック方法


前回の投稿では、Identity Developer Training Kit で発生する、日本語環境でのエラー回避方法について紹介しました。

【WP7 for IT Pro】Identity Developer Training Kit の前提条件チェックが通らないときの対処

エラー回避のキーとなるのは、Windows PowerShell スクリプトでした。

で、依存関係チェッカーが使用しているスクリプトを改めて眺めてみると、コレが結構勉強になる代物でして。簡単なスクリプトなんですけどね。

Identity Developer Training Kit で用意されている前提条件チェック用スクリプトは以下の通りです。ファイル名を見れば何をチェックしているか、一目瞭然ですよね。

PS C:\IdentityTrainingKitVS2010\Assets\DependencyChecker\scripts\dependencies\check> dir |ft name

Name
—-
CheckASPNET4.ps1
CheckAzureMMC.ps1
CheckAzureTools13ForVS2010.ps1
CheckAzureTools14ForVS2010.ps1
CheckAzureToolsForVS2008.ps1
CheckAzureToolsForVS2010.ps1
CheckIIS7.ps1
CheckIis7AspNet.ps1
CheckIisRewrite.ps1
CheckIISStaticContent.ps1
CheckLoadUserProfile.ps1
CheckNET35SP1.ps1
CheckNET4.ps1
CheckNetServicesSDK.ps1
CheckSilverlight4ToolsForVS.ps1
CheckSilverlightDevTools.ps1
CheckSilverlightToolsForVS.ps1
CheckSqlServer.ps1
CheckSqlServer2008.ps1
CheckVistaSP2.ps1
CheckVS2008.ps1
CheckVS2010.ps1
CheckWCFHTTPAct.ps1
CheckWifRuntime.ps1
CheckWifSdk4.ps1
CheckWP7AddInVS2010.ps1
CheckWP7Emulator.ps1

ここで、CheckVS2010.ps1 の中身を見てみましょう。以下は CheckVS2010.ps1 の全体像です。

function SearchUninstall($SearchFor, $UninstallKey, $Version)
{
$uninstallObjects = ls -path $UninstallKey;
$found = $FALSE;

foreach($uninstallEntry in  $uninstallObjects)
{
   $entryProperty = Get-ItemProperty -LiteralPath registry::$uninstallEntry
   if($entryProperty.DisplayName -like $searchFor -and $entryProperty.DisplayVersion -like $Version)
    {      
       $found = $TRUE;
       break;
    }
}

$found;
}

function SearchAllUninstallKeys($SearchFor, $Version)
{
    $os = Get-WMIObject win32_operatingsystem
    [bool] $found = $False;
    $SearchFor64bits = "$SearchFor (64-bit)"   
   
    # Seach in uninstall folder
    $found =  SearchUninstall -SearchFor $SearchFor -UninstallKey ‘HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\’ -Version $Version;   
    if($found) {return $found;}
   
    #Search in 64 bit keys folders
    if ($os.OSArchitecture -eq "64-bit") {
        #Wow folder
        $found =  SearchUninstall -SearchFor $SearchFor -UninstallKey ‘HKLM:SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\’ -Version $Version;   
        if($found)  {return $found;}
       
        #Wow folder, 64 bits
        $found =  SearchUninstall -SearchFor  $SearchFor64bits -UninstallKey ‘HKLM:SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\’-Version $Version;   
        if($found)  {return $found;}
       
        #32bit folder, 64 bits
        $found =  SearchUninstall -SearchFor  $SearchFor64bits -UninstallKey ‘HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\’-Version $Version;   
        if($found)  {return $found;}
    }
   
    return $found;
}

## SearchAllUninstallKeys -SearchFor ‘Microsoft Visual Studio 2010*’ -Version ‘10.0.30319’;
SearchAllUninstallKeys -SearchFor ‘Microsoft Visual Studio 2010*’ -Version ‘10.0.40219’;

一番最後の行が最初に実行されるコマンドで、ここで指定した文字列(製品名)とバージョン番号が SearchUninstall と SearchAllUninstallKeys という関数に渡されます。

SearchUninstall は引数として与えられたレジストリキー(Uninstall)の中から、製品名とバージョン番号を検索する関数です。エントリと値が存在していれば True が返されます。

SearchUninstall を呼び出しているのが SearchAllUninstallKeys  関数です。この関数では、以下の4つのパターンを想定して検索を行っており、いずれかが True になればインストールされていると判断しています。

    • 32ビット用のキーに32ビット版がインストールされている場合
    • 64ビット用のキーに64ビット版がインストールされている場合
    • 64ビット用のキーに32ビット版がインストールされている場合
    • 32ビット用のキーに64ビット版がインストールされている場合

(参考)32-bit and 64-bit Application Data in the Registry (Windows)

もう一つ、別のタイプのスクリプトを見てみましょう。CheckIIS7.ps1 です。ファイル名からわかるとおり、IIS7とASP.NETがインストールされているかどうかをチェックするスクリプトです。

function Check-RegistryValue($PropertyPath, $PropertyName, $PropertyValue)
{
    if ((Test-Path -path $PropertyPath) -ne $True)
    {
        return $FALSE;
    }

    $found = $FALSE;
   
    $entryProperty = Get-ItemProperty -path $PropertyPath

    if($entryProperty.psobject.Properties -ne $null)
    {
        $registryValue = $entryProperty.psobject.Properties[$PropertyName].value;

        if($registryValue -eq $PropertyValue)
        {
            $found = $TRUE;
        }
    }

    $found;
}

$query = Get-WmiObject Win32_Service | where {$_.Name -eq "w3svc" }

$hasIIS = ($query -ne $null);
$hasAspNet = Check-RegistryValue -PropertyPath "HKLM:\SOFTWARE\Microsoft\INETSTP\Components" -PropertyName "ASPNET" -PropertyValue "1";

$hasIIS -and $hasAspNet;

このスクリプトでは、はじめに Win32_Service を使用して IIS(w3csvc)のサービス状態を取得しています。ためしに、PowerShell のコンソールで、以下のコマンドを入力してみてください。

Get-WmiObject Win32_Service | where {$_.Name -eq "w3svc" }

IISが稼働しているかどうかにかかわらず、ただしくサービスとしてインストールされていれば、以下のような結果が返されます。

PS C:\>  Get-WmiObject Win32_Service | where {$_.Name -eq "w3svc" }

ExitCode  : 0
Name      : W3SVC
ProcessId : 3108
StartMode : Auto
State     : Running
Status    : OK

ASP.NET がインストールされているかどうかはサービスを見るだけでは判別できないため、例によってレジストリキーをチェックしています。ただし、これまでのように「製品」としてインストールされているわけでは無いので Uninstall キーをチェックしても意味がありません。そこで、Uninstall キーの代わりに \SOFTWARE\Microsoft\INETSTP\Components というキーをチェックしています。

最後に、IIS のインストール状態と ASP.NET のインストール状態を論理演算し、結果が True であればチェックをパスすることができます。

以前はこうしたスクリプトは VBSで提供されることが多かったのですが、ここ数年ですっかり Windows PowerShell にとって変わられました。こうした現状を見るにつけ、Windows の次のバージョン(なんて名前になるかは知りませんが)で VBS が使えなくなることは無いにしても、おそらく進化も望めないのだろうと、若干寂しくなる今日この頃です。

Comments (0)

Skip to main content