Windows

GPOでMSIパッケージをサイレント・インストールする


 全てのMSIパッケージに共通するものではないことを、あらかじめ断っておきます。
 ただ、IT管理者が多くのPCにソフトウェアを配布したり、インストールしたい場合において何かの参考になれば...という程度のもので す。

  Wix でインストーラー作成で作成したMSIファイルの様に、カスタムインストールをしない(ただ単にインストールのみを 行う)ものにおいて、
GPOを使用して配布・インストールするTipsです。

 Wix でインストーラー作成で作成したMSIパッケージはWindowsサービス版です。

従って、

1. Windowsサービス版として作成したソフトウェアは、Administrator(s)でないとインストール出来ない。Windows Vista以降はBuiltin\AdministratorでないとNG
2. アプリケーション設定ファイル(confgiファイル)を更新する場合、ファイル更新後にサービスを再起動しないと、更新してもexeに反映されない
3. DomainUsers, Builtin\Usersなどの一般ユーザーの権限ではACLで更新が拒否されるため(Vista以降はBuiltin\Administratorで なければNG)、Builtin\System などの特殊アカウントの権限が必要になる。つまり、ログオンスクリプトなどでの配布インストール不可である。

上記のような制限事項があります。

 これらの制限事項をクリアするにはGPOとWSH(VBScript)を組み合わせて使う必要があります。
 さらに、GPOにて「ソフトウェアの設定」でmsiパッケージを割り当てるだけでは、設定ファイルに記述してあるアプリケーション固 有の情報を更新することが不可なため、インストールから更新まで「コンピュータ起動時に」一括して行う必要があります。

以下に参考としてのVBScriptとGPOの設定を示します。

[ IntraMasterInstall.vbs ]
---------------------------
Option Explicit

Dim args
Dim objFSO
Dim WshShell
Dim WshNetwork
Dim programpath
Dim strComputer
Dim objRegistry
Dim strKeyPath
Dim arrSubkeys
Dim objSubkey
Dim objWMIService
Dim colItems
Dim objItem
Dim newFSO

Dim i

Sub err_sub()
    WScript.Echo "使い方" & Chr(13) & Chr(13) &_
     "cscript IntraMasterInstall.vbs -i | -d |  -u | -x | -dx" & Chr(13) & Chr(13) &_
     "-i ... msiパッケージのインストールを実行" & Chr(13) &_
     "-d ... ディレクトリごとインストールを実行" & Chr(13) &_
     "-u ... confgiファイルアップデートを実行" & Chr(13) &_
     "-x ... msiパッケージのアンインストールを実行" & Chr(13) &_
     "-dx ... ディレクトリごとアンインストールを実行"
    WScript.Quit
End Sub


'レジストリを参照し、.NETFramework2.0 SP1がインストールされているかチェック
Function InstallCheck()
    'On Error Resume Next
    Const HKEY_LOCAL_MACHINE = &H80000002
    strComputer = "."
    Set objRegistry=GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
    strKeyPath = "SOFTWARE\Microsoft\.NETFramework"
    objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys
   
    For Each objSubkey In arrSubkeys
        If Left(objSubkey,4) = "v1.0" Then
            'WScript.Echo ".Framework v1.0がインストール済"
            'InstallCheck = 1
            Exit Function
        End If

        If Left(objSubkey,8) = "v2.0 SP1" Then
            Install()
            'WScript.Echo ".Framework v2.0 SP1がインストール済"
            'WScript.Echo objSubKey
            'InstallCheck = 0
            Exit Function
        End If

        If Left(objSubkey,10) = "v2.0.50727" Then
            'WScript.Echo ".Framework v2.0がインストール済"
            'WScript.Echo objSubKey
            'InstallCheck = 0
            Exit Function
        End If
    Next
End Function

'msiパッケージのインストール
Function Install()
    programpath = ("\\dc2003\share\IntraMaster.msi")

    If Not objFSO.FileExists("C:\Program Files\IntraMaster\IntraMasterService.exe.config") Then
        ' ***Run setup program***
        WshShell.Run "msiexec /q /i " & programpath,0,True
    Else
        Update()
    End If
End Function

'msiパッケージでインストールした場合のアップデート
Function Update()
    If objFSO.FileExists("C:\Program Files\IntraMaster\IntraMasterService.exe.config") Then
        If objFSO.Getfile("C:\Program Files\IntraMaster\IntraMasterService.exe.config").DateCreated < _
            newFSO.GetFile("\\dc2003\share\app\IntraMasterService.exe.config").DateCreated Then
                WshShell.Run "net stop IntraMaster ",0,True
                newFSO.CopyFile "\\dc2003\share\app\IntraMasterService.exe.config", "C:\Program Files\IntraMaster\IntraMasterService.exe.config", True
                'WshShell.Run "net start IntraMaster",0,True
        End If
    End If
End Function


'msiパッケージのアンインストール
Function UnInstall()
    WshShell.Run "msiexec /x {75AD61FC-0FCA-4AB2-AD89-02FAC9AE6659} /q", 0, True
End Function

Function DirectoryCopy()
    If Not objFSO.FolderExists("C:\Program Files\IntraMaster") Then
        newFSO.CopyFolder "\\dc2003\share\app", "C:\Program Files\IntraMaster", True
    End If
End Function

Function DirectoryRemove()
    If objFSO.FolderExists("C:\Program Files\IntraMaster") Then
        newFSO.DeleteFolder "C:\Program Files\IntraMaster", True
    End If
End Function


Set objFSO = CreateObject("scripting.filesystemobject")
Set newFSO = CreateObject("scripting.filesystemobject")
Set WshShell = WScript.CreateObject("Wscript.Shell")
Set WshNetwork = WScript.CreateObject("Wscript.Network")

Set args = WScript.Arguments

For i=0 to args.Count - 1
    Select Case args(i)
        Case "-i"
            InstallCheck()
        Case "-d"
            DirectoryCopy()
        Case "-u"
            Update()
        Case "-x"
            UnInstall()
        Case "-dx"
            DirectoryRemove()
        Case Else
            err_sub
    End Select
Next

If i = 0 Then
    err_sub
End If

If Not IsNull(objFSO) Then
    On Error Resume Next
    objFSO = Nothing
End If

If Not IsNull(WshShell) Then
    On Error Resume Next
    WshShell = Nothing
End If

If Not IsNull(WshNetwork) Then
    On Error Resume Next
    WshNetwork = Nothing
End If
[ EOF ]
---------------------------

gpo.JPG
このページの先頭へ