# 機能設計書 6-Compare-DbaAgReplicaLogin

## 概要

本ドキュメントは、dbatools PowerShellモジュールのCompare-DbaAgReplicaLogin機能の設計仕様を定義する。本機能は、可用性グループ（AG）の全レプリカ間でSQL Serverログインの構成を比較し、不整合を検出する。

### 本機能の処理概要

Compare-DbaAgReplicaLoginは、可用性グループに参加しているすべてのレプリカ間でSQL Serverログインの構成を比較し、差異を特定するPowerShellコマンドである。ログインはサーバーレベルオブジェクトであり、AGによる自動同期は行われないため、フェイルオーバー後のアクセス問題を未然に防ぐために重要である。

**業務上の目的・背景**：SQL Serverログインは、データベースへのアクセス認証の基盤である。可用性グループ環境では、フェイルオーバー後にセカンダリがプライマリになるが、ログインが存在しない場合やSIDが不一致の場合、アプリケーションがデータベースに接続できなくなる。本機能は、ログインの不整合を事前に検出し、アクセス障害を予防する。

**機能の利用シーン**：
- フェイルオーバー前のアクセス構成確認
- ログイン変更後の全レプリカへの適用検証
- 定期的なセキュリティ監査
- オーファンユーザー問題の予防的検出

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

**関連システム・外部連携**：
- SQL Server SMO (Server Management Objects)
- Active Directory（Windows認証ログインの場合）

**権限による制御**：
- 各レプリカへの接続権限
- ログイン参照権限（securityadmin以上推奨）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | AGレプリカ管理 | 補助機能 | レプリカ間のログイン比較 |

## 機能種別

比較/検証処理 / セキュリティ監査

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- SQL Serverインスタンスへの直接接続
- sys.server_principalsからの変更日取得（IncludeModifiedDate時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AvailabilityGroup | string | 可用性グループ名 |
| Replica | string | レプリカインスタンス名 |
| LoginName | string | ログイン名 |
| Status | string | 状態（Present/Missing） |
| ModifyDate | DateTime | 変更日（IncludeModifiedDate時） |
| CreateDate | DateTime | 作成日 |

### 出力先

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

## 処理フロー

### 処理シーケンス

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

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

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

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

5. 各レプリカからログイン収集
   └─ Connect-DbaInstance（各レプリカ）
   └─ Get-DbaLogin（ExcludeSystemLogin対応）
   └─ IncludeModifiedDate時: sys.server_principalsクエリ

6. 全ログイン名のユニオンリスト作成

7. 各ログインについて差異検出
   └─ レプリカに存在しない場合: Missing
   └─ IncludeModifiedDate時: 変更日比較

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

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Connect-DbaInstance]
    B --> C{HADR有効?}
    C -->|No| Z1[エラー: HADR未構成]
    C -->|Yes| D[可用性グループ取得]
    D --> E{AG存在?}
    E -->|No| Z2[エラー: AG見つからず]
    E -->|Yes| F[各AGをループ]
    F --> G{レプリカ数>=2?}
    G -->|No| H[比較スキップ]
    G -->|Yes| I[レプリカ一覧取得]
    H --> F
    I --> J{ExcludeSystemLogin?}
    J -->|Yes| K[Get-DbaLogin -ExcludeSystemLogin]
    J -->|No| L[Get-DbaLogin]
    K --> M{IncludeModifiedDate?}
    L --> M
    M -->|Yes| N[sys.server_principalsクエリ]
    M -->|No| O[全ログイン名ユニオン]
    N --> O
    O --> P[各ログインをループ]
    P --> Q{ログイン存在?}
    Q -->|No| R[Missing記録]
    Q -->|Yes| S{IncludeModifiedDate?}
    S -->|Yes| T[Present+日付記録]
    S -->|No| U[次のレプリカ]
    R --> U
    T --> U
    U --> 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 | 差異時のみ出力 | Missing または 変更日差異時 | 常時 |
| BR-05 | ログインタイプフィルタ | S（SQL）、U（Windows）、G（グループ）のみ | sys.server_principalsクエリ時 |

### 計算ロジック

- modify_dateクエリ: `SELECT name, modify_date FROM sys.server_principals WHERE [type] IN ('S', 'U', 'G')`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ログイン取得 | master.sys.server_principals | SELECT | ログイン一覧取得 |
| 変更日取得 | master.sys.server_principals | SELECT | modify_date取得 |

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

#### master.sys.server_principals

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name | type IN ('S','U','G') | ログイン名 |
| SELECT | modify_date | - | 変更日 |
| SELECT | create_date | - | 作成日（SMO経由） |

## エラー処理

### エラーケース一覧

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

### リトライ仕様

- 本機能にリトライロジックは実装されていない

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

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

## パフォーマンス要件

- 各レプリカへの接続と取得に時間を要する
- IncludeModifiedDate時は追加クエリ実行
- ログイン数に比例した処理時間

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

- パスワードは取得・比較されない
- SIDの比較は本機能では行わない
- securityadmin以上の権限推奨

## 備考

- Get-DbaLoginはExcludeSystemLoginパラメータをサポート
- Invoke-DbaQueryで直接sys.server_principalsをクエリ

---

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

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

### 推奨読解順序

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

パラメータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Compare-DbaAgReplicaLogin.ps1 | `public/Compare-DbaAgReplicaLogin.ps1` | param()ブロック（85-94行目） |

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

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

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

**主要処理フロー**:
1. **99行目**: Connect-DbaInstance（MinimumVersion 11）
2. **104-106行目**: IsHadrEnabled確認

#### Step 3: ログイン収集ロジックを理解する

各レプリカからのログイン収集とmodify_date取得を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Compare-DbaAgReplicaLogin.ps1 | `public/Compare-DbaAgReplicaLogin.ps1` | レプリカループとログイン収集（133-174行目） |

**主要処理フロー**:
- **141-145行目**: Get-DbaLogin（ExcludeSystemLogin対応）
- **147-161行目**: IncludeModifiedDate時のInvoke-DbaQueryとデータ構築

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

ログインの存在チェックと変更日比較を把握する。

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

**主要処理フロー**:
- **182-190行目**: Missing検出
- **191-199行目**: IncludeModifiedDate時のPresent記録
- **203-221行目**: 差異判定と出力

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

```
Compare-DbaAgReplicaLogin
    │
    ├─ Connect-DbaInstance (初期接続)
    │
    ├─ server.AvailabilityGroups (AG取得)
    │
    ├─ ag.AvailabilityReplicas (レプリカ取得)
    │
    └─ 各レプリカについて
           ├─ Connect-DbaInstance (レプリカ接続)
           ├─ Get-DbaLogin (ログイン取得)
           └─ Invoke-DbaQuery (modify_date取得)
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance
                                  │
AvailabilityGroup ────────▶ AG取得・フィルタ
                                  │
ExcludeSystemLogin ───────▶ Get-DbaLogin
                                  │
IncludeModifiedDate ──────▶ Invoke-DbaQuery
                           (sys.server_principals)
                                  │
                                  ▼
                          差異検出
                          (Missing/変更日比較)
                                  │
                                  ▼
                          PSCustomObject
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Compare-DbaAgReplicaLogin.ps1 | `public/Compare-DbaAgReplicaLogin.ps1` | ソース | メインコマンド実装 |
| Get-DbaLogin.ps1 | `public/Get-DbaLogin.ps1` | ソース | ログイン取得 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | クエリ実行 |
