# 機能設計書 4-Compare-DbaAgReplicaAgentJob

## 概要

本ドキュメントは、dbatools PowerShellモジュールのCompare-DbaAgReplicaAgentJob機能の設計仕様を定義する。本機能は、可用性グループ（AG）の全レプリカ間でSQL Agentジョブの構成を比較し、不整合（欠落や変更日の差異）を検出する。

### 本機能の処理概要

Compare-DbaAgReplicaAgentJobは、可用性グループに参加しているすべてのレプリカ間でSQL Agentジョブの構成を比較し、差異を特定するPowerShellコマンドである。AGはデータベースレベルの同期を行うが、SQL Agentジョブなどのサーバーレベルオブジェクトは自動同期されないため、手動での管理が必要である。本機能は、この構成ドリフトを検出する。

**業務上の目的・背景**：可用性グループ環境では、データベースはプライマリとセカンダリ間で自動同期されるが、SQL Agentジョブは各レプリカで独立して管理される。フェイルオーバー後にジョブが存在しない、または構成が異なる場合、バックアップ、メンテナンス、アラート処理などの重要な運用タスクが実行されない可能性がある。本機能は、ジョブ構成の不整合を事前に検出し、フェイルオーバー時の運用リスクを低減する。

**機能の利用シーン**：
- フェイルオーバー前の運用準備状況確認
- ジュニアDBAによる変更適用後の検証
- 定期的な構成ドリフト監視
- トラブルシューティング時の構成差異分析

**主要な処理内容**：
1. 可用性グループとレプリカの取得
2. 各レプリカからSQL Agentジョブの収集
3. 全ジョブ名のユニオンリスト作成
4. 各ジョブについてレプリカ間の存在チェック
5. オプションで変更日の比較
6. 差異の出力

**関連システム・外部連携**：
- SQL Server SMO (Server Management Objects)
- SQL Server Agent
- msdb データベース

**権限による制御**：
- 各レプリカへの接続権限
- SQL Server Agentジョブの参照権限（SQLAgentReaderRole以上）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | AGレプリカ管理 | 補助機能 | レプリカ間のSQLエージェントジョブ比較 |

## 機能種別

比較/検証処理 / 構成監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | パイプライン対応 |
| SqlCredential | PSCredential | No | SQL Server接続用認証情報 | - |
| AvailabilityGroup | string[] | No | 可用性グループ名フィルタ | - |
| ExcludeSystemJob | switch | No | システムジョブを除外 | - |
| IncludeModifiedDate | switch | No | 変更日比較を含める | - |
| EnableException | switch | No | 例外有効化 | - |

### 入力データソース

- SQL Serverインスタンスへの直接接続
- パイプライン経由のインスタンス指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AvailabilityGroup | string | 可用性グループ名 |
| Replica | string | レプリカインスタンス名 |
| JobName | string | SQL Agentジョブ名 |
| Status | string | 状態（Present/Missing） |
| DateLastModified | DateTime | 最終変更日（IncludeModifiedDate時） |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- 差異がある場合のみ出力

## 処理フロー

### 処理シーケンス

```
1. インスタンス接続
   └─ Connect-DbaInstance（MinimumVersion 11）

2. HADR有効確認
   └─ IsHadrEnabledチェック

3. 可用性グループ取得
   └─ AvailabilityGroupパラメータでフィルタ

4. 各AGについてレプリカ一覧取得
   └─ 2レプリカ未満は比較スキップ

5. 各レプリカからジョブ収集
   └─ Connect-DbaInstance（各レプリカ）
   └─ Get-DbaAgentJob
   └─ ExcludeSystemJob時はシステムジョブ除外

6. 全ジョブ名のユニオンリスト作成

7. 各ジョブについて差異検出
   └─ レプリカに存在しない場合: Missing
   └─ IncludeModifiedDate時: 変更日も記録

8. 結果出力
   └─ Missingがある場合は出力
   └─ IncludeModifiedDate時は変更日差異も出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Connect-DbaInstance]
    B --> C{HADR有効?}
    C -->|No| Z1[エラー: HADR未構成]
    C -->|Yes| D[可用性グループ取得]
    D --> E{AGフィルタ指定?}
    E -->|Yes| F[フィルタ適用]
    E -->|No| G{AG存在?}
    F --> G
    G -->|No| Z2[エラー: AG見つからず]
    G -->|Yes| H[各AGをループ]
    H --> I{レプリカ数>=2?}
    I -->|No| J[比較スキップ]
    I -->|Yes| K[レプリカ一覧取得]
    J --> H
    K --> L[各レプリカからジョブ収集]
    L --> M{ExcludeSystemJob?}
    M -->|Yes| N[システムジョブ除外]
    M -->|No| O[全ジョブ名ユニオン]
    N --> O
    O --> P[各ジョブをループ]
    P --> Q[各レプリカをループ]
    Q --> R{ジョブ存在?}
    R -->|No| S[Missing記録]
    R -->|Yes| T{IncludeModifiedDate?}
    T -->|Yes| U[変更日記録]
    T -->|No| Q
    U --> Q
    S --> Q
    Q --> V{差異あり?}
    V -->|Yes| W[結果出力]
    V -->|No| P
    W --> P
    P --> X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | SQLバージョン要件 | SQL Server 2012以上が必要 | 常時 |
| BR-02 | HADR必須 | HADRが有効でない場合はエラー | 常時 |
| BR-03 | 最小レプリカ数 | 2レプリカ未満は比較対象外 | 常時 |
| BR-04 | 差異時のみ出力 | 全レプリカで同一の場合は出力なし | 常時 |
| BR-05 | 変更日差異 | IncludeModifiedDate時、変更日が異なれば出力 | IncludeModifiedDate指定時 |

### 計算ロジック

- システムジョブリスト: syspolicy_purge_history, DBA_AgentJobHistoryRetention, DBA_IndexOptimize, DBA_CommandLogCleanup

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ジョブ取得 | msdb.dbo.sysjobs | SELECT | ジョブ一覧取得 |
| ジョブ詳細取得 | msdb.dbo.sysjobhistory | SELECT | 変更日取得 |

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

#### msdb.dbo.sysjobs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name | - | ジョブ名 |
| SELECT | date_modified | - | 変更日 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Server接続失敗 | 接続情報確認 |
| - | HADRError | HADRが有効でない | HADR有効化確認 |
| - | NoAGError | 指定AGが見つからない | AG名確認 |
| - | ReplicaError | レプリカ接続失敗 | レプリカ接続確認 |

### リトライ仕様

- 本機能にリトライロジックは実装されていない
- 失敗時はStop-Functionでエラー出力しContinue

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

- 読み取り専用処理のためトランザクション不要

## パフォーマンス要件

- 各レプリカへの接続と取得に時間を要する
- ジョブ数に比例した処理時間
- 大規模環境では多数のレプリカ接続が発生

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

- SQL Server認証またはWindows認証対応
- 各レプリカへの接続には適切な権限が必要
- ジョブ参照にはSQLAgentReaderRole以上が必要

## 備考

- システムジョブリストはハードコードされている
- 変更日比較は同一ジョブ名でのみ意味がある

---

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

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

### 推奨読解順序

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

システムジョブリストとパラメータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | beginブロックのsystemJobs定義（93-99行目） |
| 1-2 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | param()ブロック（83-91行目） |

**読解のコツ**: $systemJobsはExcludeSystemJob時に除外されるジョブ名のリスト。

#### Step 2: メイン処理フローを理解する

インスタンス接続からAG取得までの流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | 接続とHADRチェック（103-112行目） |
| 2-2 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | AG取得とフィルタ（114-122行目） |

**主要処理フロー**:
1. **105行目**: Connect-DbaInstance（MinimumVersion 11）
2. **110-112行目**: IsHadrEnabled確認
3. **116-118行目**: AvailabilityGroupフィルタ適用

#### Step 3: ジョブ収集ロジックを理解する

各レプリカからのジョブ収集と全ジョブ名ユニオンを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | レプリカループとジョブ収集（139-163行目） |

**主要処理フロー**:
- **147行目**: Get-DbaAgentJobでジョブ取得
- **149-151行目**: ExcludeSystemJob処理
- **155-158行目**: allJobNamesへの追加（重複チェック付き）

#### Step 4: 差異検出ロジックを理解する

ジョブの存在チェックと変更日比較を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | 差異検出ループ（167-212行目） |

**主要処理フロー**:
- **170-180行目**: Missing検出とオブジェクト生成
- **181-189行目**: IncludeModifiedDate時のPresent記録
- **192-210行目**: 差異判定と出力条件

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

```
Compare-DbaAgReplicaAgentJob
    │
    ├─ Connect-DbaInstance (初期接続)
    │
    ├─ server.AvailabilityGroups (AG取得)
    │
    ├─ ag.AvailabilityReplicas (レプリカ取得)
    │
    └─ 各レプリカについて
           ├─ Connect-DbaInstance (レプリカ接続)
           └─ Get-DbaAgentJob (ジョブ取得)
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance
                                  │
                                  ▼
                          ┌─────────────────────┐
AvailabilityGroup ────────▶│ AG取得・フィルタ    │
                          └─────────────────────┘
                                  │
                                  ▼
                          ┌─────────────────────┐
                          │ 各レプリカ接続      │
                          │ ジョブ収集          │
ExcludeSystemJob ─────────▶│ (システムジョブ除外)│
                          └─────────────────────┘
                                  │
                                  ▼
                          ┌─────────────────────┐
                          │ 全ジョブ名ユニオン  │
                          └─────────────────────┘
                                  │
                                  ▼
                          ┌─────────────────────┐
IncludeModifiedDate ─────▶│ 差異検出            │
                          │ Missing/変更日比較  │
                          └─────────────────────┘
                                  │
                                  ▼
                          PSCustomObject
                          (差異情報)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Compare-DbaAgReplicaAgentJob.ps1 | `public/Compare-DbaAgReplicaAgentJob.ps1` | ソース | メインコマンド実装 |
| Get-DbaAgentJob.ps1 | `public/Get-DbaAgentJob.ps1` | ソース | ジョブ取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | インスタンス接続 |
