# 機能設計書 321-Install-DbaMultiTool

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Install-DbaMultiTool` 機能の設計書である。DBA MultiToolは、データベースドキュメンテーション、インデックス最適化、および管理タスクのための5つの重要なT-SQLストアドプロシージャをSQL Serverインスタンスにインストールする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：データベース管理者(DBA)は、日常的なデータベース管理タスクにおいて、オブジェクト情報の詳細取得、データベースドキュメント生成、ファイルサイズ最適化分析、インデックス圧縮による容量削減見積もり、ログイン再作成スクリプト生成などを手作業でT-SQLスクリプトを書いて実施している。DBA MultiToolは、これらの共通タスクを支援する5つのストアドプロシージャを提供し、作業効率を大幅に向上させる。

**機能の利用シーン**：データベースマイグレーション時のドキュメント生成、コンプライアンス報告用のデータベース情報収集、キャパシティプランニングのためのファイルサイズ分析、複数インスタンスへの一括ツール展開、オフライン環境でのツールインストールなどで利用される。

**主要な処理内容**：
1. GitHubから最新版のDBA MultiToolをダウンロード（またはローカルファイルを使用）
2. ローカルキャッシュに保存
3. 指定されたSQL Serverインスタンスに接続
4. ターゲットデータベースに5つのストアドプロシージャ（sp_helpme, sp_doc, sp_sizeoptimiser, sp_estindex, sp_help_revlogin）をインストール
5. インストール結果を返却

**関連システム・外部連携**：
- GitHub（DBA MultiToolリポジトリ: https://github.com/LowlyDBA/dba-multitool/）
- Save-DbaCommunitySoftware（ダウンロード処理）

**権限による制御**：ターゲットデータベースへのCREATE PROCEDURE権限が必要。通常はdb_ownerまたはsysadmin権限で実行される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | PowerShellコマンドラインからの実行 |

## 機能種別

インストール処理 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | ターゲットSQL Serverインスタンス | パイプラインから受け取り可能 |
| SqlCredential | PSCredential | No | 認証用資格情報 | Windows/SQL認証対応 |
| Database | object | No | インストール先データベース（デフォルト: master） | - |
| Branch | string | No | ダウンロードするブランチ（main/development） | ValidateSetで検証 |
| LocalFile | string | No | ローカルZIPファイルパス | - |
| Force | switch | No | キャッシュを無視して再ダウンロード | - |
| EnableException | switch | No | 例外を有効化 | - |
| Confirm | switch | No | 確認プロンプト表示 | SupportsShouldProcess |
| WhatIf | switch | No | 実行内容の表示のみ | SupportsShouldProcess |

### 入力データソース

- GitHub: DBA MultiToolリポジトリから最新版を取得
- ローカルファイル: LocalFileパラメータで指定されたZIPファイル
- ローカルキャッシュ: dbatoolsデータディレクトリ内のキャッシュ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverをホストするコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名（computer\instance） |
| Database | string | インストール先データベース名 |
| Name | string | インストールされたストアドプロシージャ名 |
| Status | string | インストール状態（Installed/Updated/Error） |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. beginブロック：ローカルキャッシュの確認と更新
   └─ Force指定時またはキャッシュ不在時にSave-DbaCommunitySoftwareで取得
2. processブロック：各インスタンスに対して処理
   └─ Connect-DbaInstanceで接続（最小バージョン11=SQL Server 2012）
3. 既存プロシージャの確認
   └─ sys.proceduresからis_ms_shipped=0のプロシージャ名を取得
4. スクリプトファイルの取得
   └─ sp_helpme.sql, sp_doc.sql, sp_sizeoptimiser.sql, sp_estindex.sql, sp_help_revloginをフィルタ
5. 各スクリプトの実行
   └─ Invoke-DbaQueryでスクリプトを実行
6. 結果オブジェクトの出力
   └─ 既存プロシージャの場合はUpdated、新規の場合はInstalled、エラー時はError
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Force指定または<br>キャッシュ不在?}
    B -->|Yes| C[Save-DbaCommunitySoftwareでダウンロード]
    B -->|No| D[キャッシュを使用]
    C --> D
    D --> E[各SqlInstanceをループ]
    E --> F[Connect-DbaInstance<br>MinimumVersion=11]
    F --> G{接続成功?}
    G -->|No| H[エラー出力して次へ]
    G -->|Yes| I[既存プロシージャ一覧を取得]
    I --> J[5つのスクリプトファイルを取得]
    J --> K[各スクリプトをループ]
    K --> L[Invoke-DbaQueryで実行]
    L --> M{実行成功?}
    M -->|No| N[Status=Error]
    M -->|Yes| O{既存プロシージャ?}
    O -->|Yes| P[Status=Updated]
    O -->|No| Q[Status=Installed]
    N --> R[結果オブジェクト出力]
    P --> R
    Q --> R
    R --> S{次のスクリプト?}
    S -->|Yes| K
    S -->|No| T{次のインスタンス?}
    H --> T
    T -->|Yes| E
    T -->|No| U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-321-01 | 最小バージョン制約 | SQL Server 2012以上が必要 | 接続時に検証 |
| BR-321-02 | キャッシュ優先 | Forceなしの場合はキャッシュを使用 | キャッシュ存在時 |
| BR-321-03 | ブランチ選択 | mainまたはdevelopmentブランチを選択可能 | Branch指定時 |
| BR-321-04 | 既存プロシージャ更新 | 既存の場合はUpdatedステータス | プロシージャ存在時 |

### 計算ロジック

ステータス判定ロジック：
- エラー発生時: Status = 'Error'
- プロシージャ名が既存一覧に含まれる場合: Status = 'Updated'
- 上記以外: Status = 'Installed'

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 既存プロシージャ確認 | sys.procedures | SELECT | is_ms_shipped=0のプロシージャ名を取得 |
| プロシージャ作成/更新 | ターゲットデータベース | DDL | ストアドプロシージャの作成または置換 |

### テーブル別操作詳細

#### sys.procedures

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name | is_ms_shipped = 0 | ユーザー定義プロシージャのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンスへの接続失敗 | Stop-Functionで処理継続 |
| - | DownloadError | GitHubからのダウンロード失敗 | Stop-Functionで処理中断 |
| - | ExecutionError | スクリプト実行失敗 | Status=Errorで出力、次のスクリプトへ |

### リトライ仕様

明示的なリトライ機能は実装されていない。Forceパラメータで再ダウンロードを試行可能。

## トランザクション仕様

各スクリプトの実行は独立しており、明示的なトランザクション制御は行われていない。スクリプト内でバッチ処理として実行される。

## パフォーマンス要件

特に定義されていない。ネットワーク状況によりダウンロード時間が変動する。

## セキュリティ考慮事項

- Windows認証およびSQL認証に対応
- MFAサポートはConnect-DbaInstanceを事前に使用
- Azure Active Directory認証対応
- 資格情報はPSCredentialオブジェクトとして安全に管理

## 備考

- DBA MultiTool公式サイト: https://dba-multitool.org
- GitHubリポジトリ: https://github.com/LowlyDBA/dba-multitool/
- 作者: John McCall (@lowlydba)

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

出力オブジェクトの構造を把握することから始める。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | 174-181行目のPSCustomObject定義を確認 |

**読解のコツ**: PowerShellのPSCustomObjectはハッシュテーブル形式で定義され、プロパティ名と値のペアを持つ。

#### Step 2: エントリーポイントを理解する

処理の起点となるパラメータ定義と関数構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | 119-130行目のparam定義でパラメータを確認 |

**主要処理フロー**:
1. **119-130行目**: パラメータ定義（SqlInstance必須、Database既定値master）
2. **131-146行目**: beginブロックでキャッシュ更新判定
3. **148-203行目**: processブロックでインスタンス毎のインストール処理

#### Step 3: キャッシュ管理処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | 135-145行目のSave-DbaCommunitySoftware呼び出し |

**主要処理フロー**:
- **135行目**: Get-DbatoolsConfigValueでデータディレクトリパス取得
- **136行目**: ブランチ名を含むキャッシュパス生成
- **137-145行目**: Force/LocalFile指定時またはキャッシュ不在時にダウンロード

#### Step 4: インストール処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | 151-199行目のインストールロジック |

**主要処理フロー**:
- **153行目**: Connect-DbaInstanceで最小バージョン11を指定して接続
- **159-160行目**: 既存プロシージャ一覧をsys.proceduresから取得
- **163-168行目**: 5つのスクリプトファイルをフィルタ
- **170-199行目**: 各スクリプトをInvoke-DbaQueryで実行し結果を出力

### プログラム呼び出し階層図

```
Install-DbaMultiTool
    │
    ├─ Get-DbatoolsConfigValue
    │      └─ dbatools設定からデータディレクトリパス取得
    │
    ├─ Join-DbaPath
    │      └─ キャッシュパスの構築
    │
    ├─ Save-DbaCommunitySoftware
    │      └─ GitHubからのダウンロードとキャッシュ保存
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Serverへの接続（SMOオブジェクト作成）
    │
    ├─ Get-ChildItem
    │      └─ スクリプトファイルの検索
    │
    └─ Invoke-DbaQuery
           └─ SQLスクリプトの実行
```

### データフロー図

```
[入力]                   [処理]                        [出力]

GitHubリポジトリ ───▶ Save-DbaCommunitySoftware ───▶ ローカルキャッシュ
       or                     │
ローカルZIPファイル           │
                              ▼
                    Get-ChildItem（SQLファイル取得）
                              │
                              ▼
SqlInstance ───────▶ Connect-DbaInstance ───▶ SMO Server Object
                              │
                              ▼
                    Invoke-DbaQuery（スクリプト実行）
                              │
                              ▼
                        PSCustomObject
                    （インストール結果）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | ソース | メイン関数の実装 |
| Save-DbaCommunitySoftware.ps1 | `private/functions/Save-DbaCommunitySoftware.ps1` | ソース | コミュニティソフトウェアのダウンロード |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | SQLクエリ実行 |
