1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Microsoft Standard Installer(.msi) ファイル小ネタ

Posted at

遅いWindowsPC のGUIなんて・・・・

軽快な、ubuntu の shell での操作に慣れてしまうと、低スペック高年式のWindows PC を取り扱うと・・・その遅さに思わず、
「PowerShellでもなんでもいい、もっさりGUI要らん」
となりますよね。

  • 要らないアプリこそ取っ払いたいのに、GUIでちまちまやるのが遅い。
  • Microsoft Standard Installer は並列処理してくれない・・・のはやむ得ないから、とりあえずバッチにしたい。

・・・などと思ったので、記事にしてみました。

msiexecとPowerShellを活用したバッチ処理を実装してみる

MSIパッケージについて

MSI(Microsoft Installer)パッケージは、Windowsの標準的なソフトウェアインストール形式です。各MSIパッケージには一意のProduct Code(GUID)が割り当てられ、システムのレジストリに登録されます。

msiexecコマンドの基本

msiexec /x {ProductCode} /quiet /norestart
  • /x: アンインストールオプション
  • /quiet: サイレント実行
  • /norestart: 再起動の抑制

課題:製品名や製造元からProduct Codeを特定する

通常のアンインストール処理では、正確なProduct Code(GUID)が必要です。しかし、実際の運用では「Adobe製品をすべて削除」や「特定バージョンのソフトウェアのみ削除」といった要求が発生します。

解決策:msi-search/msi_search.ps1の活用

GitHubで公開されているmsi-search/msi_search.ps1スクリプトは、インストール済みMSIパッケージの情報を効率的に検索する機能を提供します。

スクリプトの主要機能

  1. レジストリ検索: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstallからインストール情報を取得
  2. WMI クエリ: Win32_Productクラスを使用したシステム情報の取得
  3. フィルタリング: 製造元(Publisher)、製品名(DisplayName)による絞り込み
  4. Product Code抽出: アンインストールに必要なGUIDの特定

実装例

1. 基本的な検索スクリプト

# 製造元による検索
.\msi_search.ps1 -Publisher "Adobe Systems"

# 製品名による部分一致検索
.\msi_search.ps1 -DisplayName "*Office*"

2. バッチアンインストール処理

# 検索結果からProduct Codeを取得してアンインストール
$products = .\msi_search.ps1 -Publisher "Adobe Systems"
foreach ($product in $products) {
    $productCode = $product.ProductCode
    Write-Host "Uninstalling: $($product.DisplayName)"
    Start-Process -FilePath "msiexec.exe" -ArgumentList "/x", $productCode, "/quiet", "/norestart" -Wait
}

3. エラーハンドリングとログ出力

$logFile = "C:\Temp\uninstall_log.txt"
$products = .\msi_search.ps1 -Publisher "Adobe Systems"

foreach ($product in $products) {
    try {
        $productCode = $product.ProductCode
        $displayName = $product.DisplayName
        
        Write-Output "$(Get-Date): Starting uninstall of $displayName" | Tee-Object -FilePath $logFile -Append
        
        $process = Start-Process -FilePath "msiexec.exe" -ArgumentList "/x", $productCode, "/quiet", "/norestart" -Wait -PassThru
        
        if ($process.ExitCode -eq 0) {
            Write-Output "$(Get-Date): Successfully uninstalled $displayName" | Tee-Object -FilePath $logFile -Append
        } else {
            Write-Output "$(Get-Date): Failed to uninstall $displayName (Exit Code: $($process.ExitCode))" | Tee-Object -FilePath $logFile -Append
        }
    }
    catch {
        Write-Output "$(Get-Date): Error processing $displayName - $($_.Exception.Message)" | Tee-Object -FilePath $logFile -Append
    }
}

実行時の注意点

権限要件

  • 管理者権限での実行が必要です。
  • 実行ポリシーが、設定されてないとPowerShellスクリプトは起動しません。 Powershellを楽に実行してもらうには 
  • UAC(ユーザーアカウント制御)の考慮

パフォーマンス最適化

  • WMI クエリは処理時間が長い場合があるため、レジストリベースの検索を優先
  • 大量のソフトウェアが対象の場合は、並列処理の検討

リスク管理

# 事前確認(ドライラン)の実装
param(
    [switch]$WhatIf
)

if ($WhatIf) {
    Write-Host "以下の製品がアンインストール対象です:"
    $products | ForEach-Object { Write-Host "- $($_.DisplayName)" }
    return
}

応用例

1. 特定バージョンの一括削除

# 古いバージョンのJavaを一括削除
$oldJava = .\msi_search.ps1 -DisplayName "*Java*" | Where-Object { 
    $_.Version -lt "8.0.0" 
}

2. CSV出力による管理

$results = .\msi_search.ps1 -Publisher "Microsoft Corporation"
$results | Export-Csv -Path "C:\Temp\installed_software.csv" -NoTypeInformation

3. リモート実行

Invoke-Command -ComputerName $servers -ScriptBlock {
    # リモートサーバーでの一括アンインストール処理
}

トラブルシューティング

よくある問題と対処法

  1. Exit Code 1618: 別のインストール処理が実行中

    • Windows Installerサービスの状態確認
    • 処理の順次実行
  2. Exit Code 1605: 製品が見つからない

    • Product Codeの再確認
    • レジストリ情報との整合性チェック
  3. 権限エラー:

    • 管理者権限での実行確認
    • グループポリシーの制限確認

セキュリティ考慮事項

  • スクリプトの署名検証
  • 実行ポリシーの適切な設定
  • ログファイルのアクセス制御
  • 誤削除防止のための事前確認機能

まとめ

msiexecとPowerShellスクリプトを組み合わせることで、製造元や製品名をキーとした効率的なMSIパッケージの一括アンインストールが可能になります。msi-search/msi_search.ps1のようなツールを活用することで、複雑なProduct Code特定作業を自動化し、大規模環境でのソフトウェア管理を効率化できます。

ただし、本番環境での実行前には必ず十分なテストと事前確認を行い、適切なバックアップとログ記録を実装することが重要です。

参考リソース

  • Microsoft公式ドキュメント: msiexecコマンドリファレンス
  • GitHub: msi-search/msi_search.ps1
  • PowerShell Gallery: 関連モジュール
  • Windows Installer エラーコード一覧
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?