# 機能設計書 320-Install-DbaMaintenanceSolution

## 概要

本ドキュメントは、Ola Hallengren氏のメンテナンスソリューションをインストールするInstall-DbaMaintenanceSolution機能の設計仕様を記載する。

### 本機能の処理概要

Install-DbaMaintenanceSolutionは、GitHubからOla Hallengren氏のSQL Server Maintenance Solutionをダウンロードし、ストアドプロシージャとオプションでSQL Agentジョブをインストールする機能である。

**業務上の目的・背景**：SQL Serverのメンテナンス作業（バックアップ、整合性チェック、インデックス最適化）は、データベースの安定運用に不可欠である。Ola Hallengren氏のMaintenance Solutionは、世界中で何千ものSQL Server環境で使用されている業界標準のメンテナンスフレームワークである。本機能は、DatabaseBackup、DatabaseIntegrityCheck、IndexOptimize、CommandExecuteなどのストアドプロシージャを簡単にデプロイし、オプションで事前構成されたSQL Agentジョブを作成することで、手動のメンテナンススクリプト作成を置き換える。

**機能の利用シーン**：本機能は以下のような場面で利用される。
- 新規SQL Server環境へのメンテナンスソリューション導入
- 既存環境のMaintenance Solutionアップグレード
- 複数インスタンスへの一括デプロイ
- 自動スケジュール付きバックアップジョブの構成
- オフライン環境へのインストール（LocalFile使用）

**主要な処理内容**：
1. GitHubからMaintenance Solutionのダウンロード（またはローカルファイル使用）
2. 対象SQL Serverインスタンスへの接続
3. 既存オブジェクトの確認とオプション削除
4. ストアドプロシージャとテーブルの作成
5. SQL Agentジョブの作成とスケジュール設定

**関連システム・外部連携**：GitHub（OlaHallengren/sql-server-maintenance-solution）からのダウンロード。Save-DbaCommunitySoftware内部関数を使用。

**権限による制御**：対象データベースへのCREATE PROCEDURE/TABLE権限、SQL Agentジョブ管理権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | メンテナンスソリューション管理 | 主機能 | Ola Hallengrenソリューションのインストール |

## 機能種別

インストール / コミュニティツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | インストール先SQL Serverインスタンス | パイプライン入力対応 |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 | Windows/SQL/AD認証サポート |
| Database | string | No | インストール先データベース（デフォルト: master） | - |
| BackupLocation | string | No | バックアップファイル保存先 | - |
| CleanupTime | int | No | バックアップ保持時間（時間単位） | InstallJobs時のみ有効 |
| OutputFileDirectory | string | No | ジョブ出力ファイルディレクトリ | - |
| ReplaceExisting | switch | No | 既存オブジェクトを置換 | - |
| LogToTable | switch | No | CommandLogテーブルへのログ有効化 | - |
| Solution | string[] | No | インストールするソリューション | All/Backup/IntegrityCheck/IndexOptimize |
| InstallJobs | switch | No | SQL Agentジョブを作成 | - |
| AutoScheduleJobs | string[] | No | 自動スケジュール設定 | WeeklyFull/DailyFull/NoDiff/FifteenMinuteLog/HourlyLog |
| StartTime | string | No | ジョブ開始時刻（HHMMSS形式、デフォルト: 011500） | - |
| LocalFile | string | No | ローカルZIPファイルパス | - |
| Force | switch | No | キャッシュを無視して再ダウンロード | - |
| InstallParallel | switch | No | 並列実行用Queue/QueueDatabaseテーブル作成 | - |
| ChangeBackupType | switch | No | バックアップタイプの自動変換有効化 | InstallJobs時のみ |
| Compress | switch | No | バックアップ圧縮有効化 | InstallJobs時のみ |
| CopyOnly | switch | No | コピーのみバックアップ | InstallJobs時のみ |
| Verify | switch | No | バックアップ検証有効化 | InstallJobs時のみ |
| CheckSum | switch | No | チェックサム検証有効化 | InstallJobs時のみ |
| ModificationLevel | int | No | ChangeBackupType適用の変更率閾値 | 0-100 |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- GitHubリポジトリ（https://github.com/olahallengren/sql-server-maintenance-solution）
- ローカルZIPファイル（LocalFile指定時）
- バンドルされたオフラインコピー（インターネット接続なし時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| Results | string | Success/Failed |

### 出力先

- PowerShellパイプライン（PSCustomObject形式）

## 処理フロー

### 処理シーケンス

```
1. 前処理（beginブロック）
   └─ Solution値の正規化
   └─ パラメータ検証（CleanupTimeとInstallJobsの組み合わせ）
   └─ インターネット接続確認
   └─ ローカルキャッシュ有無確認とダウンロード
   └─ Get-DbaOlaWithParameters関数定義
2. インスタンスループ開始
   └─ foreach SqlInstance
3. SQL Server接続
   └─ Connect-DbaInstance実行（NonPooledConnection）
4. データベース存在確認
5. 既存オブジェクト確認
   └─ ReplaceExisting未指定時は既存確認
6. 必要ファイル決定
   └─ Solutionに基づくSQLファイル選択
7. スクリプト内容のパラメータ置換
   └─ Get-DbaOlaWithParameters呼び出し
8. 既存オブジェクト削除（ReplaceExisting時）
   └─ プロシージャ、テーブル、ジョブの削除
9. スクリプト実行
   └─ Invoke-DbaQueryで各スクリプト実行
10. 自動スケジュール設定（AutoScheduleJobs時）
    └─ New-DbaAgentScheduleでスケジュール作成
11. バックアップパラメータ追加（各オプション時）
    └─ Set-DbaAgentJobStepでジョブステップ更新
12. 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{インターネット接続?}
    B -->|No| C[バンドルコピー使用]
    B -->|Yes| D{キャッシュ存在?}
    D -->|No| E[Save-DbaCommunitySoftware]
    D -->|Yes| F{Force?}
    F -->|Yes| E
    F -->|No| G[foreach SqlInstance]
    C --> G
    E --> G
    G --> H[Connect-DbaInstance]
    H --> I{接続成功?}
    I -->|No| J[エラー, Continue]
    I -->|Yes| K{Database存在?}
    K -->|No| L[エラー, Continue]
    K -->|Yes| M{ReplaceExisting?}
    M -->|No| N{既存オブジェクトあり?}
    N -->|Yes| O[エラー, Continue]
    N -->|No| P[必要ファイル決定]
    M -->|Yes| Q[既存オブジェクト削除]
    Q --> P
    P --> R[Get-DbaOlaWithParameters]
    R --> S[foreach required file]
    S --> T[Invoke-DbaQuery実行]
    T --> U{AutoScheduleJobs?}
    U -->|Yes| V[New-DbaAgentSchedule]
    U -->|No| W{追加パラメータあり?}
    V --> W
    W -->|Yes| X[Set-DbaAgentJobStep]
    W -->|No| Y[結果出力]
    X --> Y
    Y --> G
    J --> G
    L --> G
    O --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ジョブ作成制限 | InstallJobsはSolution = Allの場合のみ使用可能 | InstallJobs指定時 |
| BR-002 | CleanupTime依存 | CleanupTimeはInstallJobsと併用必須 | CleanupTime指定時 |
| BR-003 | デフォルトデータベース | Database未指定時はmasterを使用 | 常時 |
| BR-004 | テーブル削除条件 | CommandLogはLogToTable時、Queue/QueueDatabaseはInstallParallel時のみ削除 | ReplaceExisting時 |
| BR-005 | オフラインフォールバック | インターネット接続なし時はバンドルコピーを使用 | 常時 |
| BR-006 | システムDB日次バックアップ | AutoScheduleJobsでシステムDBは常に日次バックアップ | AutoScheduleJobs時 |
| BR-007 | スケジュール競合回避 | 既存スケジュールと競合時は開始時刻を1時間ずらす | AutoScheduleJobs時 |
| BR-008 | デフォルト開始時刻 | StartTime未指定時は01:15（011500）を使用 | AutoScheduleJobs時 |

### 自動スケジュールオプション

| オプション | 説明 |
|-----------|------|
| WeeklyFull | 週次フル、日次差分、15分間隔ログバックアップ |
| DailyFull | 日次フル、差分なし、15分間隔ログバックアップ |
| NoDiff | 差分バックアップをスキップ |
| FifteenMinuteLog | 15分間隔ログバックアップ（デフォルト） |
| HourlyLog | 毎時ログバックアップ |

### 作成されるジョブ一覧

| ジョブ名 | 説明 |
|---------|------|
| DatabaseBackup - USER_DATABASES - FULL | ユーザーDB完全バックアップ |
| DatabaseBackup - USER_DATABASES - DIFF | ユーザーDB差分バックアップ |
| DatabaseBackup - USER_DATABASES - LOG | ユーザーDBログバックアップ |
| DatabaseBackup - SYSTEM_DATABASES - FULL | システムDB完全バックアップ |
| DatabaseIntegrityCheck - USER_DATABASES | ユーザーDB整合性チェック |
| DatabaseIntegrityCheck - SYSTEM_DATABASES | システムDB整合性チェック |
| IndexOptimize - USER_DATABASES | ユーザーDBインデックス最適化 |
| CommandLog Cleanup | コマンドログクリーンアップ |
| Output File Cleanup | 出力ファイルクリーンアップ |
| sp_delete_backuphistory | バックアップ履歴削除 |
| sp_purge_jobhistory | ジョブ履歴削除 |

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 既存オブジェクト確認 | - | SELECT | Get-DbaModule、Get-DbaDbTableでオブジェクト検索 |
| オブジェクト削除 | dbo.CommandExecute等 | DROP | ReplaceExisting時のプロシージャ/テーブル削除 |
| プロシージャ作成 | - | CREATE PROCEDURE | ストアドプロシージャのインストール |
| テーブル作成 | dbo.CommandLog等 | CREATE TABLE | ログテーブルの作成 |

### 作成されるオブジェクト

| オブジェクト名 | 種別 | 条件 |
|--------------|------|------|
| dbo.CommandExecute | ストアドプロシージャ | 常時 |
| dbo.DatabaseBackup | ストアドプロシージャ | Solution含むBackup/All |
| dbo.DatabaseIntegrityCheck | ストアドプロシージャ | Solution含むIntegrityCheck/All |
| dbo.IndexOptimize | ストアドプロシージャ | Solution含むIndexOptimize/All |
| dbo.CommandLog | テーブル | LogToTable時 |
| dbo.Queue | テーブル | InstallParallel時 |
| dbo.QueueDatabase | テーブル | InstallParallel時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Serverへの接続失敗 | 接続情報と権限を確認 |
| - | DatabaseNotFound | 指定データベースが存在しない | データベース名を確認 |
| - | ObjectExists | 既存オブジェクトあり（ReplaceExisting未指定） | -ReplaceExisting指定 |
| - | ParameterConflict | InstallJobs未指定でCleanupTime指定 | -InstallJobs指定 |
| - | SolutionConflict | Solution != AllでInstallJobs指定 | -Solution All指定 |
| - | ScriptError | スクリプト実行エラー | 権限を確認 |

### リトライ仕様

リトライ機能は実装されていない。ダウンロード失敗時はバンドルコピーにフォールバック。

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

各スクリプトは独立して実行される。スクリプト内でのトランザクション管理はスクリプト自身に依存。

## パフォーマンス要件

- ローカルキャッシュによりダウンロード回数を最小化
- インターネット接続なし時のバンドルコピーフォールバック
- NonPooledConnectionで接続プール問題を回避

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

- SqlCredentialによる認証情報の安全な受け渡し
- GitHubからの信頼されたソースのみ使用
- CREATE PROCEDURE/TABLE権限が必要
- SQL Agentジョブ管理権限が必要

## 備考

- Ola Hallengren氏（ola.hallengren.com）が提供するコミュニティツール
- SupportsShouldProcess対応（WhatIf/Confirm）
- 整合性チェックはフルバックアップ前に実行推奨
- インデックス最適化後のフルバックアップで差分を小さくする

---

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

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

### 推奨読解順序

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

出力されるオブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | .OUTPUTSコメント（127-138行目）で出力プロパティを確認 |

**読解のコツ**: ResultsプロパティがSuccess/Failedのみのシンプルな出力。

#### Step 2: パラメータ検証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | 303-318行目のbeginブロック検証 |

**主要処理フロー**:
- **306-308行目**: Solution = Allの正規化
- **310-313行目**: InstallJobsとSolution != Allの競合チェック
- **315-318行目**: CleanupTimeとInstallJobsの依存チェック

#### Step 3: ダウンロードとキャッシュ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | 325-360行目のインターネット確認とダウンロード |

**主要処理フロー**:
- **326-343行目**: インターネット接続確認
- **341行目**: オフラインフォールバック
- **345-360行目**: キャッシュ確認とダウンロード

#### Step 4: パラメータ置換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | 362-413行目 Get-DbaOlaWithParameters関数 |

**主要処理フロー**:
- **371-375行目**: Database置換
- **378-382行目**: BackupLocation置換
- **385-389行目**: CleanupTime置換
- **399-403行目**: LogToTable置換
- **406-410行目**: CreateJobs置換

#### Step 5: 自動スケジュール処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | 557-729行目のAutoScheduleJobs処理 |

**主要処理フロー**:
- **600-620行目**: WeeklyFull/DailyFull選択
- **679-690行目**: NoDiff処理
- **692-715行目**: HourlyLog/FifteenMinuteLog選択

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

```
Install-DbaMaintenanceSolution
    │
    ├─ begin
    │      ├─ Get-NetConnectionProfile（インターネット確認）
    │      ├─ Save-DbaCommunitySoftware
    │      │      └─ GitHub API / LocalFile展開
    │      └─ Get-DbaOlaWithParameters（内部関数）
    │
    └─ process
           ├─ Connect-DbaInstance
           │      └─ NonPooledConnection
           │
           ├─ Get-DbaModule
           │      └─ 既存プロシージャ確認
           │
           ├─ Get-DbaDbTable
           │      └─ 既存テーブル確認
           │
           ├─ Get-DbaAgentJob
           │      └─ 既存ジョブ確認/削除
           │
           ├─ Invoke-DbaQuery
           │      └─ スクリプト実行
           │
           ├─ New-DbaAgentSchedule
           │      └─ ジョブスケジュール作成
           │
           ├─ Set-DbaAgentJobStep
           │      └─ ジョブステップ更新
           │
           └─ Disconnect-DbaInstance
```

### データフロー図

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

GitHub/LocalFile ─────▶ Save-DbaCommunitySoftware ───▶ ローカルキャッシュ
        │                                                    │
        ▼                                                    ▼
オフラインコピー ──────▶ フォールバック ─────────────▶ スクリプトファイル
        │                                                    │
        ▼                                                    ▼
SqlInstance ───────────▶ Connect-DbaInstance ───────▶ Server オブジェクト
        │                                                    │
        ▼                                                    ▼
Database ──────────────▶ データベース検証 ─────────▶ 対象DB
        │                                                    │
        ▼                                                    ▼
Solution ──────────────▶ 必要ファイル選択 ────────▶ 対象SQLファイル
        │                                                    │
        ▼                                                    ▼
BackupLocation/         ▶ Get-DbaOlaWithParameters ──▶ 置換済みスクリプト
CleanupTime etc.               │
        │                      ▼
        ▼               Invoke-DbaQuery
ReplaceExisting ───────▶ 既存オブジェクト削除 ────▶ クリーンアップ
        │                      │
        ▼                      ▼
InstallJobs ───────────▶ ジョブ作成 ──────────────▶ SQL Agentジョブ
        │                      │
        ▼                      ▼
AutoScheduleJobs ──────▶ New-DbaAgentSchedule ────▶ ジョブスケジュール
        │                      │
        ▼                      ▼
ChangeBackupType/       ▶ Set-DbaAgentJobStep ────▶ ジョブステップ更新
Compress etc.                  │
                               ▼
                        PSCustomObject（Results）
                               │
                               ▼
                        パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | ソース | メイン機能実装 |
| Save-DbaCommunitySoftware.ps1 | `private/functions/Save-DbaCommunitySoftware.ps1` | ソース | ダウンロード処理（依存先） |
| Get-DbaModule.ps1 | `public/Get-DbaModule.ps1` | ソース | 既存プロシージャ確認（依存先） |
| Get-DbaDbTable.ps1 | `public/Get-DbaDbTable.ps1` | ソース | 既存テーブル確認（依存先） |
| New-DbaAgentSchedule.ps1 | `public/New-DbaAgentSchedule.ps1` | ソース | ジョブスケジュール作成（依存先） |
| Set-DbaAgentJobStep.ps1 | `public/Set-DbaAgentJobStep.ps1` | ソース | ジョブステップ更新（依存先） |
| maintenancesolution/ | `bin/maintenancesolution/` | データ | バンドルされたオフラインコピー |
