# 機能設計書 541-Copy-DbaServerRole

## 概要

本ドキュメントは、SQL Serverインスタンス間でカスタムサーバーロールを移行するPowerShell関数`Copy-DbaServerRole`の機能設計書である。

### 本機能の処理概要

Copy-DbaServerRoleは、ソースSQL Serverインスタンスからターゲットインスタンスへカスタム（ユーザー定義）サーバーロールをコピーする機能を提供する。サーバーロールの定義だけでなく、ロールに付与された権限およびロールメンバーシップも含めて移行を行う。

**業務上の目的・背景**：SQL Serverインスタンスの移行やセキュリティ構成の標準化において、カスタムサーバーロールの移行は重要な作業となる。手動での移行は時間がかかりミスが発生しやすいため、この機能により一貫性のある自動化された移行が可能となる。特に、複数環境（開発・テスト・本番）間でのセキュリティ設定の同期に有効である。

**機能の利用シーン**：
- SQL Serverの新規環境構築時にセキュリティ設定を複製する場合
- 災害復旧時に権限設定を復元する場合
- 複数環境間でセキュリティポリシーを標準化する場合
- サーバー移行プロジェクトでの権限移行作業

**主要な処理内容**：
1. ソースサーバーへの接続確立とサーバーロール一覧の取得
2. ターゲットサーバーへの接続確立
3. 対象ロールのフィルタリング（ServerRole/ExcludeServerRoleパラメータ）
4. 既存ロールの存在チェックと必要に応じた削除（Forceオプション使用時）
5. ロール定義のスクリプト化と作成
6. サーバーレベル権限のコピー
7. ロールメンバーシップの復元

**関連システム・外部連携**：SQL Server Management Objects (SMO)を使用してSQL Serverインスタンスと連携する。ソースおよびターゲットのSQL Serverは2012以上が必要。

**権限による制御**：ソースおよびターゲットSQL Serverインスタンスでsysadmin権限が必要である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし（CLI専用機能） | - | PowerShellコマンドラインから実行 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | ソースSQL Serverインスタンス | SQL Server 2012以上 |
| SourceSqlCredential | PSCredential | No | ソース接続用資格情報 | 有効なPSCredential |
| Destination | DbaInstanceParameter[] | Yes | ターゲットSQL Serverインスタンス（複数指定可） | SQL Server 2012以上 |
| DestinationSqlCredential | PSCredential | No | ターゲット接続用資格情報 | 有効なPSCredential |
| ServerRole | object[] | No | コピー対象のサーバーロール名 | 存在するロール名 |
| ExcludeServerRole | object[] | No | 除外するサーバーロール名 | 存在するロール名 |
| Force | switch | No | 既存ロールを削除して再作成 | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- ソースSQL Serverインスタンスのsys.server_principalsシステムビュー
- SMO Server.Rolesコレクション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DateTime | DbaDateTime | 操作実行時刻 |
| SourceServer | string | ソースサーバー名 |
| DestinationServer | string | ターゲットサーバー名 |
| Name | string | サーバーロール名 |
| Type | string | 常に"Server Role" |
| Status | string | Successful/Skipped/Failed |
| Notes | string | 操作結果の詳細または エラーメッセージ |

### 出力先

PowerShellパイプライン（MigrationObjectタイプ）

## 処理フロー

### 処理シーケンス

```
1. ソースサーバー接続
   └─ Connect-DbaInstance -MinimumVersion 11（SQL Server 2012+）
2. カスタムサーバーロール一覧取得
   └─ IsFixedRole=false かつ Name!='public'のロールを抽出
3. ターゲットサーバーへのループ処理開始
   └─ 各ターゲットサーバーに接続
4. 各サーバーロールの処理
   └─ ServerRole/ExcludeServerRoleによるフィルタリング
5. 既存ロールチェック
   └─ 存在する場合: Forceならドロップ、そうでなければスキップ
6. ロール作成
   └─ Script()メソッドでT-SQL生成・実行
7. 権限コピー
   └─ Get-DbaPermissionで取得、GrantStatementを実行
8. メンバーシップ復元
   └─ EnumMemberNamesで取得、AddMemberで追加
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C{接続成功?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[カスタムロール一覧取得]
    E --> F[ターゲットサーバーループ]
    F --> G[ターゲット接続]
    G --> H{接続成功?}
    H -->|No| I[次のターゲットへ]
    H -->|Yes| J[ロールループ]
    J --> K{フィルタ条件合致?}
    K -->|No| L[次のロールへ]
    K -->|Yes| M{ロール存在?}
    M -->|Yes| N{Force指定?}
    N -->|No| O[スキップ出力]
    N -->|Yes| P[既存ロール削除]
    M -->|No| Q[ロール作成]
    P --> Q
    Q --> R[権限コピー]
    R --> S[メンバーシップ復元]
    S --> T[成功出力]
    O --> L
    T --> L
    L --> U{全ロール処理完了?}
    U -->|No| J
    U -->|Yes| I
    I --> V{全ターゲット処理完了?}
    V -->|No| F
    V -->|Yes| W[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-541-01 | 固定ロール除外 | 固定サーバーロール（sysadmin等）はコピー対象外 | 常時 |
| BR-541-02 | publicロール除外 | publicロールはコピー対象外 | 常時 |
| BR-541-03 | 既存ロールスキップ | Forceなしの場合、既存ロールはスキップ | Force未指定時 |
| BR-541-04 | メンバー存在確認 | ターゲットにログインが存在しない場合はメンバーシップスキップ | メンバー追加時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ロール作成 | sys.server_principals | INSERT | サーバーロールの作成 |
| ロール削除 | sys.server_principals | DELETE | Forceオプション使用時 |
| 権限付与 | sys.server_permissions | INSERT | ロール権限の付与 |
| メンバー追加 | sys.server_role_members | INSERT | ロールメンバーの追加 |

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

#### sys.server_principals

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, type, principal_id | ソースロールからコピー | SMO経由で実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | 接続文字列・資格情報を確認 |
| - | 削除エラー | Forceでロール削除失敗 | 依存関係を確認 |
| - | 作成エラー | ロール作成失敗 | 権限・重複を確認 |
| - | 権限エラー | 権限付与失敗 | sysadmin権限を確認 |

### リトライ仕様

リトライ機能なし。エラー時は次のロール/ターゲットの処理を継続。

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

各ロールの作成・権限付与は個別のSMO操作として実行される。明示的なトランザクション制御は行わない。ロール作成後に権限付与でエラーが発生した場合、ロールは作成された状態で残る。

## パフォーマンス要件

特に定義なし。大量のロール移行時はネットワーク帯域とSQL Server負荷を考慮する必要がある。

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

- ソース・ターゲット両方でsysadmin権限が必要
- 資格情報はPSCredentialオブジェクトで安全に受け渡し
- Windows認証、SQL Server認証、Active Directory認証をサポート
- MFA使用時はConnect-DbaInstanceを使用

## 備考

- SQL Server 2012以上が必要（カスタムサーバーロールはSQL Server 2012で導入）
- WhatIfおよびConfirmスイッチをサポート

---

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

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

### 推奨読解順序

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

まず、関数のパラメータ定義と出力オブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaServerRole.ps1 | `public/Copy-DbaServerRole.ps1` | 106-118行目のパラメータ定義を確認 |

**読解のコツ**: `[parameter(Mandatory)]`属性はPowerShell v3形式で、`= $true`を省略している点に注意。

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

処理の起点となるbeginブロックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaServerRole.ps1 | `public/Copy-DbaServerRole.ps1` | 120-131行目のbeginブロック |

**主要処理フロー**:
1. **121-126行目**: ソースサーバーへの接続（MinimumVersion 11でSQL 2012以上を要求）
2. **128行目**: カスタムサーバーロールのフィルタリング（IsFixedRole=false、Name!='public'）
3. **130行目**: Forceパラメータ時の確認プロンプト無効化

#### Step 3: メイン処理ループを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaServerRole.ps1 | `public/Copy-DbaServerRole.ps1` | 132-242行目のprocessブロック |

**主要処理フロー**:
- **134-139行目**: ターゲットサーバーへの接続
- **143-162行目**: ロールフィルタリングとステータスオブジェクト作成
- **164-189行目**: 既存ロールの処理（スキップまたは削除）
- **191-239行目**: ロール作成、権限コピー、メンバーシップ復元

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

```
Copy-DbaServerRole
    │
    ├─ Connect-DbaInstance (ソース接続)
    │      └─ MinimumVersion 11 検証
    │
    ├─ Connect-DbaInstance (ターゲット接続)
    │
    ├─ Server.Roles.Script() (ロール定義取得)
    │
    ├─ Get-DbaPermission (権限取得)
    │      └─ IncludeServerLevel = $true
    │
    └─ Server.Roles[].AddMember() (メンバー追加)
```

### データフロー図

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

Source Server     ───▶ Connect-DbaInstance     ───▶ SMO Server Object
    │                                                      │
    ▼                                                      ▼
Server.Roles      ───▶ Filter Custom Roles    ───▶ Role Collection
    │                                                      │
    ▼                                                      ▼
Role.Script()     ───▶ Execute on Target      ───▶ New Role Created
    │                                                      │
    ▼                                                      ▼
Get-DbaPermission ───▶ Grant Permissions      ───▶ Permissions Applied
    │                                                      │
    ▼                                                      ▼
EnumMemberNames() ───▶ AddMember()            ───▶ MigrationObject Output
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaServerRole.ps1 | `public/Copy-DbaServerRole.ps1` | ソース | メイン関数実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続共通関数 |
| Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | ソース | 権限取得関数 |
| dbatools.psd1 | `dbatools.psd1` | 設定 | モジュールマニフェスト |
| dbatools.psm1 | `dbatools.psm1` | ソース | モジュールルートスクリプト |
