# 機能設計書 585-Sync-DbaLoginPermission

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Sync-DbaLoginPermission`コマンドレットに関する機能設計書です。本機能はSQL Serverインスタンス間でログインの権限とロールメンバーシップを同期します。

### 本機能の処理概要

`Sync-DbaLoginPermission`は、ソースから宛先のSQL Serverインスタンスへ包括的なログインセキュリティ設定を同期し、環境間で一貫した権限構成を確保します。この機能は既存のログインの権限のみを変更し、ログイン自体の作成や削除は行いません。

**業務上の目的・背景**：開発、ステージング、本番環境間で一貫したセキュリティ構成を維持する必要があります。また、サーバー再構築時にログイン権限を復元する際、ログインを再作成せずに権限のみを復元する必要がある場面もあります。本機能はこれらの課題を解決します。

**機能の利用シーン**：
- 開発・ステージング・本番環境間でのセキュリティ構成の一貫性維持
- サーバー再構築後のログイン権限の復元
- 災害復旧環境でのセキュリティ設定の同期
- セキュリティ監査前の権限統一
- サーバーロールや権限の一括更新

**主要な処理内容**：
1. ソースSQL Serverインスタンスへの接続
2. 対象ログインの取得（Get-DbaLoginを使用）
3. 各宛先インスタンスへの接続
4. Update-SqlPermission内部関数によるサーバーロール、サーバー権限、SQL Agentジョブ所有権、資格情報マッピング、データベースユーザーマッピング、データベースロール、データベース権限の同期

**関連システム・外部連携**：Get-DbaLogin、Update-SqlPermission内部関数を使用します。

**権限による制御**：ソースおよび宛先の両方でsysadmin権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 67 | ログイン権限同期 | 主機能 | ログイン権限の同期 |

## 機能種別

データ連携 / セキュリティ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | 権限読み取り元のソースインスタンス | パイプライン入力対応 |
| SourceSqlCredential | PSCredential | No | ソースインスタンス接続用の代替資格情報 | - |
| Destination | DbaInstanceParameter[] | Yes | 権限適用先の宛先インスタンス | 複数指定可能 |
| DestinationSqlCredential | PSCredential | No | 宛先インスタンス接続用の代替資格情報 | - |
| Login | string[] | No | 同期対象の特定ログイン名 | - |
| ExcludeLogin | string[] | No | 同期から除外するログイン名 | - |
| EnableException | switch | No | 例外をスローするモード | - |

### 入力データソース

- Get-DbaLoginによるログイン情報
- ソースインスタンスの権限情報（Update-SqlPermissionが読み取り）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SourceServer | string | ソースSQL Serverインスタンス名 |
| DestinationServer | string | 宛先SQL Serverインスタンス名 |
| Name | string | 同期されたログイン名 |
| Type | string | 操作タイプ（常に"Login Permissions"） |
| Status | string | 操作結果（Successful, Failed） |
| Notes | string | 追加情報（成功時はnull、失敗時はエラーメッセージ） |
| DateTime | DbaDateTime | 同期実行日時 |

### 出力先

PowerShellパイプラインへのPSCustomObject（TypeName: MigrationObject）の出力

## 処理フロー

### 処理シーケンス

```
1. ソースインスタンスへの接続
   └─ Connect-DbaInstance

2. 対象ログインの取得
   └─ Get-DbaLoginでLogin/ExcludeLoginフィルタ適用

3. 現在のログイン名の取得
   └─ 自分自身のログインはスキップ対象として取得

4. 各宛先インスタンスでの処理
   └─ Connect-DbaInstance（MinimumVersion 8）
   └─ 各ソースログインに対して：
      └─ 自分自身のログインはスキップ
      └─ ホストログイン/システムログインはスキップ
      └─ 宛先にログインが存在しない場合はスキップ
      └─ Update-SqlPermissionで権限同期

5. 結果出力
   └─ MigrationObjectとして結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Connect-DbaInstance Source]
    B --> C{接続成功?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[Get-DbaLogin]
    E --> F{ログイン存在?}
    F -->|No| G[エラー終了]
    F -->|Yes| H[現在のログイン取得]
    H --> I[各宛先ループ]
    I --> J[Connect-DbaInstance Dest]
    J --> K{接続成功?}
    K -->|No| L[エラー出力、次の宛先へ]
    K -->|Yes| M[各ソースログインループ]
    M --> N{自分自身のログイン?}
    N -->|Yes| O[スキップ]
    N -->|No| P{ホスト/システムログイン?}
    P -->|Yes| O
    P -->|No| Q{宛先にログイン存在?}
    Q -->|No| O
    Q -->|Yes| R[Update-SqlPermission]
    R --> S{成功?}
    S -->|Yes| T[Successful出力]
    S -->|No| U[Failed出力]
    T --> V{次のログイン?}
    U --> V
    O --> V
    V -->|Yes| M
    V -->|No| W{次の宛先?}
    W -->|Yes| I
    W -->|No| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-585-01 | 自己ログイン保護 | 現在接続中のログインの権限は同期しない | 常時 |
| BR-585-02 | ホストログイン保護 | ホストベースのログイン（コンピュータ名で始まる）は同期しない | 常時 |
| BR-585-03 | システムログイン保護 | "NT "で始まるシステムログインは同期しない | 常時 |
| BR-585-04 | ログイン存在確認 | 宛先にログインが存在しない場合はスキップ | 常時 |
| BR-585-05 | 権限のみ同期 | ログイン自体の作成・削除は行わない | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| サーバーロール同期 | sys.server_role_members | INSERT/DELETE | ロールメンバーシップを同期 |
| サーバー権限同期 | sys.server_permissions | INSERT/DELETE | サーバーレベル権限を同期 |
| データベースロール同期 | sys.database_role_members | INSERT/DELETE | DBロールメンバーシップを同期 |
| データベース権限同期 | sys.database_permissions | INSERT/DELETE | DBレベル権限を同期 |

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

Update-SqlPermission内部関数により、複数のシステムテーブルが更新されます。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | ソース接続失敗 | Stop-Functionで終了 |
| - | ConnectionError | 宛先接続失敗 | Stop-Function、次の宛先へ |
| - | NoLoginsError | マッチするログインなし | Stop-Functionで終了 |
| - | SyncError | 権限同期失敗 | Failed出力、次のログインへ |

### リトライ仕様

リトライ処理なし。各宛先・各ログインは独立して処理されます。

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

Update-SqlPermission内で各権限変更が実行されます。トランザクション管理の詳細は内部関数に依存します。

## パフォーマンス要件

特に規定なし。進捗表示（Write-ProgressHelper）を実装しています。

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

- ソースおよび宛先の両方でsysadmin権限が必要
- 自分自身のログインの権限は変更しない（ロックアウト防止）
- システムログインは同期対象外
- SupportsShouldProcess実装（ConfirmImpact = "Medium"）

## 備考

- Update-SqlPermission内部関数を使用して包括的な権限同期を実行
- Copy-SqlLoginとの違い：ログイン自体は作成せず、権限のみを同期
- 出力にはTypeNameとしてMigrationObjectが設定される

---

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

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

### 推奨読解順序

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

出力されるPSCustomObject（MigrationObject）の構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | 152-160行目: 出力構造定義 |

**読解のコツ**: PSCustomObjectにはSourceServer、DestinationServer、Name、Type、Status、Notes、DateTimeの7プロパティがあり、TypeNameとしてMigrationObjectが設定されます。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | 91-102行目: パラメータ定義 |

**主要処理フロー**:
1. **93-95行目**: Source（必須、パイプライン入力対応）とSourceSqlCredential
2. **96-98行目**: Destination（必須、複数可）とDestinationSqlCredential
3. **99-101行目**: Login、ExcludeLogin

#### Step 3: ログイン取得とフィルタリング

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | 107-118行目: ソース接続とログイン取得 |

**主要処理フロー**:
- **107-112行目**: ソースインスタンス接続
- **114-118行目**: Get-DbaLoginでログイン取得、マッチなしの場合はエラー

#### Step 4: 権限同期処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | 121-149行目: ログインスキップ条件 |
| 4-2 | Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | 162-173行目: Update-SqlPermission呼び出し |

**主要処理フロー**:
- **121行目**: 現在のログイン取得（TrueLogin）
- **133-137行目**: 自分自身のログインをスキップ
- **139-144行目**: ホスト/システムログインをスキップ
- **146-149行目**: 宛先にログインが存在しない場合スキップ
- **163行目**: Update-SqlPermissionで権限同期実行

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

```
Sync-DbaLoginPermission
    │
    ├─ Connect-DbaInstance (Source)
    │      └─ ソースインスタンス接続
    │
    ├─ Get-DbaLogin
    │      └─ 対象ログインの取得
    │
    ├─ Connect-DbaInstance (Destination)
    │      └─ 宛先インスタンス接続（MinimumVersion 8）
    │
    └─ Update-SqlPermission
           ├─ サーバーロール同期
           ├─ サーバー権限同期
           ├─ SQL Agentジョブ所有権同期
           ├─ 資格情報マッピング同期
           ├─ データベースユーザーマッピング同期
           ├─ データベースロール同期
           └─ データベース権限同期
```

### データフロー図

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

Source ────────────────▶ Connect-DbaInstance ──────────▶ $sourceServer
                              │
Login/ExcludeLogin ────▶ Get-DbaLogin ─────────────────▶ $allLogins
                              │
Destination ───────────▶ Connect-DbaInstance ──────────▶ $destServer
                              │
                         Update-SqlPermission ─────────▶ MigrationObject
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Sync-DbaLoginPermission.ps1 | `public/Sync-DbaLoginPermission.ps1` | ソース | メイン処理 |
| Get-DbaLogin.ps1 | `public/Get-DbaLogin.ps1` | ソース | ログイン取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
