# 機能設計書 546-Export-DbaServerRole

## 概要

本ドキュメントは、サーバーレベルロールを権限およびメンバーシップ情報とともにT-SQLスクリプトとして生成するPowerShell関数`Export-DbaServerRole`の機能設計書である。

### 本機能の処理概要

Export-DbaServerRoleは、サーバーレベルロールの完全な定義（CREATE SERVER ROLE文、GRANT/DENY/REVOKE権限、ロールメンバー）を含む実行可能なT-SQLスクリプトを生成する。sys.server_permissionsを照会してすべてのロール権限を取得し、別のインスタンスでサーバーロールを再作成するためのスクリプトを生成する。

**業務上の目的・背景**：サーバーレベルのセキュリティ構成は、サーバー移行やディザスタリカバリ時に手動で再作成することが困難である。ユーザー定義サーバーロール（SQL Server 2012以降）は、カスタムの権限セットを定義するために広く使用されており、これらの設定を正確に再作成する必要がある。本機能により、サーバーロールの完全な定義をスクリプト化し、移行や復旧を容易にする。

**機能の利用シーン**：
- SQL Serverインスタンス間でのサーバーロール移行
- ディザスタリカバリ用のセキュリティ構成バックアップ
- 複数環境でのセキュリティポリシー標準化
- コンプライアンス監査のためのセキュリティドキュメント化

**主要な処理内容**：
1. 対象サーバーロールの取得（フィルタリング対応）
2. SMO ScriptingOptionsを使用したロール定義のスクリプト化
3. sys.server_permissionsからの権限情報取得
4. ロールメンバーシップの追加（オプション）
5. ファイルまたはパイプラインへの出力

**関連システム・外部連携**：SQL Server Management Objects (SMO)を使用。

**権限による制御**：サーバーロール情報へのアクセス権限が必要。

## 関連画面

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

## 機能種別

帳票出力 / セキュリティ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | 有効なPSCredential |
| InputObject | object[] | No | パイプライン入力（サーバーロール/サーバー） | - |
| ScriptingOptionsObject | ScriptingOptions | No | SMOスクリプトオプション | - |
| ServerRole | string[] | No | 対象ロール名 | - |
| ExcludeServerRole | string[] | No | 除外ロール名 | - |
| ExcludeFixedRole | switch | No | 固定ロールを除外 | - |
| IncludeRoleMember | switch | No | メンバーシップを含める | - |
| Path | string | No | 出力ディレクトリ | デフォルト: DbatoolsExport |
| FilePath | string | No | 出力ファイルパス | - |
| Passthru | switch | No | パイプライン出力 | - |
| BatchSeparator | string | No | バッチ区切り文字 | デフォルト: GO |
| NoClobber | switch | No | 上書き禁止 | - |
| Append | switch | No | 追記モード | - |
| NoPrefix | switch | No | ヘッダーコメント除外 | - |
| Encoding | string | No | 文字エンコーディング | UTF8等 |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- Get-DbaServerRoleで取得したサーバーロールオブジェクト
- sys.server_permissionsシステムビュー
- sys.server_principalsシステムビュー
- sys.endpoints（エンドポイント権限用）
- sys.availability_groups（可用性グループ権限用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Passthru時 | string | T-SQLスクリプト文字列 |
| ファイル出力時 | FileInfo | 生成されたスクリプトファイル情報 |

### 出力先

- ファイル出力: Path/FilePathで指定されたSQLスクリプトファイル
- Passthru: PowerShellパイプライン

## 処理フロー

### 処理シーケンス

```
1. エクスポートディレクトリ検証
   └─ Test-ExportDirectory
2. ScriptingOptions初期化
   └─ 未指定時はデフォルトオプション設定
3. InputObject処理
   └─ DbaInstanceParameter/Server/ServerRole判定
4. Azure SQL Database除外
   └─ ServerType判定
5. ロールループ処理
   └─ 各ロールに対してスクリプト生成
6. ロール定義スクリプト化（SQL 2012以上）
   └─ $role.Script()
7. 権限スクリプト生成
   └─ roleSQLクエリで権限取得
8. メンバーシップスクリプト生成（オプション）
   └─ ALTER SERVER ROLE ... ADD MEMBER文
9. 出力処理
   └─ ファイル/パイプライン出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[エクスポートディレクトリ検証]
    B --> C[ScriptingOptions初期化]
    C --> D{InputObject種別}
    D -->|DbaInstanceParameter| E[Get-DbaServerRole呼び出し]
    D -->|Server| F[Get-DbaServerRole呼び出し]
    D -->|ServerRole| G[直接処理]
    E --> H[ロールループ]
    F --> H
    G --> H
    H --> I{Azure SQL DB?}
    I -->|Yes| J[スキップ]
    I -->|No| K{SQL 2012以上?}
    K -->|Yes| L[ロール定義スクリプト化]
    K -->|No| M[権限のみ処理]
    L --> N[権限取得・スクリプト生成]
    M --> N
    N --> O{IncludeRoleMember?}
    O -->|Yes| P[メンバーシップスクリプト]
    O -->|No| Q[roleCollection追加]
    P --> Q
    Q --> R{全ロール完了?}
    R -->|No| H
    R -->|Yes| S[出力処理]
    S --> T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-546-01 | Azure SQL非対応 | SqlAzureDatabaseはサポート外 | 常時 |
| BR-546-02 | SQL 2012以上でロール定義 | VersionMajor 11以上でScript()使用 | ロール定義出力時 |
| BR-546-03 | 固定ロール除外 | ExcludeFixedRole時は固定ロール除外 | オプション指定時 |
| BR-546-04 | 権限クラス判定 | ログイン/サーバーロール/エンドポイント/可用性グループで異なる構文 | 権限出力時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 権限取得 | sys.server_permissions | SELECT | ロール権限の読み取り |
| エンドポイント | sys.endpoints | SELECT | エンドポイント権限用 |
| 可用性グループ | sys.availability_groups | SELECT | AG権限用 |
| プリンシパル | sys.server_principals | SELECT | ログイン/ロール情報 |

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

#### sys.server_permissions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | state, permission_name, class, major_id | grantee = ロール名 | 複雑なJOINクエリ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | 接続情報を確認 |
| - | Azure非対応 | SqlAzureDatabase | オンプレミスSQL Serverを使用 |

### リトライ仕様

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

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

読み取り専用操作のためトランザクション不要。

## パフォーマンス要件

特に定義なし。

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

- サーバーレベル情報へのアクセス権限が必要
- 出力スクリプトにはセキュリティ構成が含まれる

## 備考

- SQL Server 2012以上でユーザー定義サーバーロールをサポート
- SQL Server 2008以前では固定ロールのメンバーシップのみ出力可能
- John Eisbrener氏の実装を拡張

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Export-DbaServerRole.ps1 | `public/Export-DbaServerRole.ps1` | 142-165行目のパラメータ定義 |
| 1-2 | Export-DbaServerRole.ps1 | `public/Export-DbaServerRole.ps1` | 178-223行目のroleSQLクエリ |

**読解のコツ**: roleSQLは権限のclass値（100/101/105/108）によりログイン、サーバーロール、エンドポイント、可用性グループを判定。

#### Step 2: InputObject処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Export-DbaServerRole.ps1 | `public/Export-DbaServerRole.ps1` | 255-274行目のInputObject種別判定 |

#### Step 3: ロール処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Export-DbaServerRole.ps1 | `public/Export-DbaServerRole.ps1` | 276-327行目のロール処理 |

**主要処理フロー**:
- **279-281行目**: Azure SQL DB除外
- **285-286行目**: SQL 2012以上でScript()
- **288-305行目**: 権限スクリプト生成
- **308-312行目**: メンバーシップスクリプト

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

```
Export-DbaServerRole
    │
    ├─ Test-ExportDirectory
    │
    ├─ New-DbaScriptingOption
    │
    ├─ Get-DbaServerRole
    │
    ├─ ServerRole.Script()
    │
    ├─ Server.Query($roleSQL)
    │
    └─ Out-File
```

### データフロー図

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

SqlInstance/      ───▶ Get-DbaServerRole       ───▶ ServerRole Objects
InputObject                                               │
    │                                                     ▼
    ▼
ServerRole        ───▶ Script($ScriptingOptions) ───▶ CREATE SERVER ROLE
    │                                                     │
    ▼                                                     ▼
sys.server_       ───▶ Query($roleSQL)         ───▶ GRANT/DENY/REVOKE
permissions                                               │
    │                                                     ▼
    ▼
roleCollection    ───▶ Join with BatchSeparator ───▶ FileInfo / String
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Export-DbaServerRole.ps1 | `public/Export-DbaServerRole.ps1` | ソース | メイン関数実装 |
| Get-DbaServerRole.ps1 | `public/Get-DbaServerRole.ps1` | ソース | サーバーロール取得 |
| New-DbaScriptingOption.ps1 | `public/New-DbaScriptingOption.ps1` | ソース | スクリプトオプション |
| Test-ExportDirectory.ps1 | `private/functions/Test-ExportDirectory.ps1` | ソース | ディレクトリ検証 |
