# 機能設計書 548-Export-DbaUser

## 概要

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

### 本機能の処理概要

Export-DbaUserは、データベースユーザーの完全なセキュリティコンテキスト（CREATE USER文、ロールメンバーシップ、データベースレベル権限、オブジェクトレベル権限）を含む包括的なT-SQLスクリプトを生成する。テーブル、ビュー、ストアドプロシージャ、関数、アセンブリ、証明書、スキーマ、Service Brokerオブジェクトなど、サポートされるすべてのSQL Serverオブジェクトタイプに対する詳細な権限を含む。

**業務上の目的・背景**：データベースユーザーとその権限の移行は、環境間でのアプリケーション展開において重要な課題である。ユーザーを手動で再作成し、各オブジェクトに対する権限を個別に付与することは時間がかかり、エラーが発生しやすい。本機能により、ユーザーの完全なセキュリティ構成を自己完結したスクリプトとしてエクスポートし、ターゲット環境で確実に再作成できる。

**機能の利用シーン**：
- 環境間でのユーザー移行（開発→テスト→本番）
- コンプライアンス監査のためのセキュリティドキュメント化
- ディザスタリカバリ用のユーザー設定バックアップ
- アプリケーションユーザーのデプロイメントスクリプト作成
- テンプレートベースのユーザー作成自動化

**主要な処理内容**：
1. 対象データベースおよびユーザーの取得
2. ユーザーが所属するカスタムロールの定義スクリプト化
3. ユーザー定義のスクリプト化（CREATE USER）
4. データベースレベル権限の取得（EnumDatabasePermissions）
5. オブジェクトレベル権限の取得（EnumObjectPermissions）
6. 各種セキュアブルの権限収集
7. ファイルまたはパイプラインへの出力

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

**権限による制御**：対象データベースへのアクセス権限が必要。

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | - |
| InputObject | Database[] | No | パイプライン入力（Database） | - |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | 有効なPSCredential |
| Database | string[] | No | 対象データベース名 | - |
| ExcludeDatabase | string[] | No | 除外データベース名 | - |
| User | string[] | No | 対象ユーザー名 | - |
| DestinationVersion | string | No | ターゲットSQLバージョン | SQLServer2000-2022 |
| Path | string | No | 出力ディレクトリ | デフォルト: DbatoolsExport |
| FilePath | string | No | 出力ファイルパス | - |
| Encoding | string | No | 文字エンコーディング | UTF8等 |
| NoClobber | switch | No | 上書き禁止 | - |
| Append | switch | No | 追記モード | - |
| Passthru | switch | No | パイプライン出力 | - |
| Template | switch | No | テンプレートモード | - |
| EnableException | switch | No | 例外を有効化 | - |
| ScriptingOptionsObject | ScriptingOptions | No | カスタムスクリプトオプション | - |
| ExcludeGoBatchSeparator | switch | No | GO除外 | - |

### 入力データソース

- Get-DbaDatabase経由のデータベースオブジェクト
- Database.Usersコレクション
- sys.database_permissions
- 各種SMOコレクションのEnumObjectPermissions

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 入力処理
   └─ SqlInstance/InputObjectからデータベース取得
2. ユーザーループ処理
   └─ 各ユーザーに対してスクリプト生成
3. カスタムロール定義出力
   └─ ユーザーが所属するロールをScript()
4. ユーザー定義出力
   └─ CREATE USER文生成
5. データベース権限取得
   └─ EnumDatabasePermissions
6. オブジェクト権限取得
   └─ 各セキュアブルタイプ別にEnumObjectPermissions
7. 権限スクリプト構築
   └─ GRANT/DENY ON ... TO文生成
8. 出力処理
   └─ ファイル/パイプライン出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[データベース取得]
    B --> C[ユーザーループ]
    C --> D{Template?}
    D -->|Yes| E[プレースホルダー使用]
    D -->|No| F[実ユーザー名使用]
    E --> G[ロール定義出力]
    F --> G
    G --> H[ユーザー定義出力]
    H --> I[DB権限取得]
    I --> J[オブジェクト権限ループ]
    J --> K[権限タイプ判定]
    K --> L[GRANT/DENY文生成]
    L --> M{全オブジェクト完了?}
    M -->|No| J
    M -->|Yes| N[SQL結合]
    N --> O{Passthru?}
    O -->|Yes| P[パイプライン出力]
    O -->|No| Q[ファイル出力]
    P --> R{全ユーザー完了?}
    Q --> R
    R -->|No| C
    R -->|Yes| S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-548-01 | システムユーザー除外 | IsSystemObject=true、##で始まるユーザーは除外 | 常時 |
| BR-548-02 | ロール自己完結 | 依存関係回避のため、各ユーザーに必要なロール定義を含む | 常時 |
| BR-548-03 | テンプレートモード | {templateUser}と{templateLogin}でプレースホルダー置換 | Template指定時 |
| BR-548-04 | バージョン互換 | DestinationVersionでターゲット構文を制御 | 指定時 |
| BR-548-05 | Version80制限 | SQL 2000ではOBJECT::構文使用不可 | scriptVersion=Version80時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| DB権限取得 | sys.database_permissions | SELECT | データベース権限 |
| オブジェクト権限取得 | sys.database_permissions | SELECT | オブジェクト権限 |
| ロール取得 | sys.database_principals | SELECT | ロール情報 |
| ユーザー取得 | sys.database_principals | SELECT | ユーザー情報 |

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

読み取り専用。EnumObjectPermissionsメソッド経由でのSELECTのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server接続失敗 | 接続情報を確認 |
| - | バージョンエラー | ターゲットバージョン非互換 | 互換バージョンを指定 |

### リトライ仕様

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

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

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

## パフォーマンス要件

特に定義なし。多数の権限がある場合は処理時間が増加する可能性がある。EnumObjectPermissionsの呼び出し回数を最小化するため、コレクション別に一括取得。

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

- 対象データベースへの読み取りアクセス権限が必要
- 出力スクリプトにはセキュリティ構成が含まれる
- Templateモードで機密性の高いユーザー名をマスク可能

## 備考

- SQL Server 2000以上をサポート
- DestinationVersionで旧バージョン互換構文を生成可能
- 各ユーザースクリプトは自己完結（必要なロール定義を含む）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | 161-187行目のパラメータ定義 |
| 1-2 | Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | 195-217行目のバージョンマッピング |

**読解のコツ**: $versionsと$versionName辞書でSQLバージョンとCompatibilityLevelを相互変換。

#### Step 2: ロール定義出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | 355-363行目 |

**読解のコツ**: 依存関係回避のため、ユーザーが所属する各ロールの定義を毎回出力。コメントで設計意図を詳細に説明。

#### Step 3: オブジェクト権限取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | 413-477行目 |

**主要処理フロー**:
- **415行目**: $db.EnumObjectPermissions($dbuser.Name)
- **417-463行目**: 各コレクション別のEnumObjectPermissions
- **465-477行目**: バージョン依存処理（AsymmetricKeys等）

#### Step 4: 権限スクリプト構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | 479-563行目 |

**読解のコツ**: ObjectClass別に適切なセキュアブル構文（OBJECT::, SCHEMA::等）を使用。

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

```
Export-DbaUser
    │
    ├─ Get-DbaDatabase
    │
    ├─ New-DbaScriptingOption
    │
    ├─ Role.Script() (カスタムロール定義)
    │
    ├─ User.Script() (ユーザー定義)
    │
    ├─ Database.EnumDatabasePermissions() (DB権限)
    │
    ├─ Database.EnumObjectPermissions() (オブジェクト権限)
    │
    ├─ Collection.EnumObjectPermissions() (各コレクション)
    │   ├─ ApplicationRoles
    │   ├─ Assemblies
    │   ├─ Certificates
    │   ├─ DatabaseRoles
    │   └─ ... (多数のコレクション)
    │
    └─ Out-File
```

### データフロー図

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

SqlInstance/      ───▶ Get-DbaDatabase         ───▶ Database Objects
InputObject                                               │
    │                                                     ▼
Database.Users    ───▶ Filter by User param    ───▶ User Collection
    │                                                     │
    ▼                                                     ▼
Database.Roles    ───▶ Role.Script()           ───▶ CREATE ROLE T-SQL
    │                                                     │
    ▼                                                     ▼
User.Script()     ───▶ ScriptingOptions        ───▶ CREATE USER T-SQL
    │                                                     │
    ▼                                                     ▼
EnumPermissions() ───▶ Build GRANT/DENY        ───▶ Permission T-SQL
    │                                                     │
    ▼                                                     ▼
$outsql           ───▶ Join with GO            ───▶ FileInfo / String
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Export-DbaUser.ps1 | `public/Export-DbaUser.ps1` | ソース | メイン関数実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得 |
| New-DbaScriptingOption.ps1 | `public/New-DbaScriptingOption.ps1` | ソース | スクリプトオプション |
