# 機能設計書 537-Add-DbaDbRoleMember

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるAdd-DbaDbRoleMember機能の設計仕様を定義するものである。この機能はデータベースユーザーまたはロールをデータベースロールのメンバーとして追加し、SQL Serverインスタンス全体でセキュリティを管理する。

### 本機能の処理概要

**業務上の目的・背景**：データベースセキュリティ管理において、ユーザーやロールをデータベースロール（db_datareader、db_datawriter、db_owner等）に追加する作業は頻繁に発生する。本機能は、手動でT-SQLコマンドを実行したりSSMSで操作する代わりに、PowerShellから一括でロールメンバーシップを管理できるようにする。複数のデータベース、インスタンスに対して一括操作が可能。

**機能の利用シーン**：
- 新規ユーザーへの権限付与
- アプリケーション展開時の権限設定自動化
- セキュリティ標準化（組織全体でのロール割り当て統一）
- CI/CDパイプラインでのデータベース権限設定
- 大規模環境での一括権限管理

**主要な処理内容**：
1. 入力タイプの判定（DbaInstanceParameter、Server、Database、DatabaseRole）
2. Get-DbaDbRole経由でのデータベースロールオブジェクト取得
3. メンバーシップ検証（ユーザー/ロール存在確認、重複確認）
4. AddMember()メソッドによるメンバー追加

**関連システム・外部連携**：
- SQL Server Management Objects (SMO) - DatabaseRole.AddMember()
- Get-DbaDbRole - データベースロールオブジェクト取得

**権限による制御**：
- 対象ロールに対するALTER権限
- db_securityadminまたはdb_ownerロールのメンバーシップ

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 37 | データベースロール管理 | 補助機能 | ロールメンバーの追加 |

## 機能種別

データ作成処理（INSERT / ADD）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | No | 対象SQL Serverインスタンス。パイプライン入力可能 | 有効なSQL Server接続文字列 |
| SqlCredential | PSCredential | No | SQL Server接続用の代替認証情報 | 有効なPSCredentialオブジェクト |
| Database | string[] | No | 対象データベース名。ワイルドカード対応 | - |
| Role | string[] | No | 対象データベースロール名 | - |
| Member | string[] | Yes | 追加するユーザーまたはロール名 | データベース内に存在すること |
| InputObject | object[] | No | パイプライン入力（Server、Database、DatabaseRole） | - |
| EnableException | switch | No | 例外を呼び出し元にスローする | - |

### 入力データソース

- パラメータ入力（コマンドライン引数）
- パイプライン入力（DbaInstanceParameter、Server、Database、DatabaseRole）

## 出力仕様

### 出力データ

なし（メンバー追加操作のため出力オブジェクトなし）

### 出力先

なし

## 処理フロー

### 処理シーケンス

```
1. 入力検証（processブロック）
   ├─ InputObjectまたはSqlInstanceの存在確認
   └─ SqlInstance指定時はInputObjectに設定

2. 入力タイプ別処理
   ├─ DbaInstanceParameter → Get-DbaDbRole呼び出し
   ├─ Server → Get-DbaDbRole呼び出し
   ├─ Database → Get-DbaDbRole呼び出し（パイプ経由）
   └─ DatabaseRole → 直接使用

3. ロールパラメータ検証
   └─ Roleパラメータ未指定かつDatabaseRole以外の場合はエラー

4. ロールループ処理
   └─ メンバーループ処理
       ├─ メンバー存在確認（Users/Roles）
       ├─ 既存メンバーシップ確認
       ├─ ShouldProcess確認
       └─ AddMember()メソッド実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject or SqlInstance?}
    B -->|なし| C[エラー: 入力必須]
    B -->|あり| D{入力タイプ判定}
    D -->|DbaInstanceParameter| E[Get-DbaDbRole]
    D -->|Server| F[Get-DbaDbRole]
    D -->|Database| G[Get-DbaDbRole via pipe]
    D -->|DatabaseRole| H[直接使用]
    E --> I[dbRoles取得]
    F --> I
    G --> I
    H --> I
    I --> J{Role指定必須?}
    J -->|Yes/未指定| K[エラー: Role必須]
    J -->|OK| L[foreach dbRole]
    L --> M[EnumMembers取得]
    M --> N[foreach newMember]
    N --> O{Users内に存在?}
    O -->|Yes| P{既にメンバー?}
    O -->|No| Q{Roles内に存在?}
    Q -->|Yes| R{既にメンバー?}
    Q -->|No| S[警告: 存在しない]
    P -->|Yes| T[スキップ]
    P -->|No| U[AddMember - User]
    R -->|Yes| V[スキップ]
    R -->|No| W[AddMember - Role]
    S --> X{次のメンバー?}
    T --> X
    U --> X
    V --> X
    W --> X
    X -->|Yes| N
    X -->|No| Y{次のロール?}
    Y -->|Yes| L
    Y -->|No| Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 入力必須 | InputObjectまたはSqlInstanceが必須 | 常時 |
| BR-002 | メンバー必須 | Memberパラメータは必須 | 常時 |
| BR-003 | ロール必須条件 | DatabaseRole以外の入力時はRole指定必須 | DatabaseRole以外の入力時 |
| BR-004 | メンバー存在確認 | MemberはUsers またはRoles内に存在すること | 常時 |
| BR-005 | 重複チェック | 既にメンバーの場合はスキップ | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メンバー追加 | sys.database_role_members | INSERT | ロールメンバーシップ追加 |

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

#### sys.database_role_members

SMO DatabaseRole.AddMember()メソッド経由で以下相当のDDLが実行される：
```sql
ALTER ROLE [ロール名] ADD MEMBER [メンバー名]
```

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 入力不足 | InputObject/SqlInstance両方なし | パイプまたはパラメータで入力 |
| - | ロール未指定 | DatabaseRole以外でRole未指定 | Roleパラメータを指定 |
| - | メンバー不存在 | MemberがDB内に存在しない | 有効なユーザー/ロールを指定 |
| - | 権限不足 | ALTER権限なし | 必要な権限を付与 |

### リトライ仕様

明示的なリトライ処理は実装されていない。メンバー不存在時は警告を出力して次のメンバー処理を継続。

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

SMO DatabaseRole.AddMember()メソッドが内部的にトランザクションを管理する。

## パフォーマンス要件

- メンバー追加は通常即座に完了
- 多数のメンバーを一括追加する場合は順次処理

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

- ALTER ANY ROLEまたは対象ロールへのALTER権限が必要
- ConfirmImpact=Highにより、デフォルトで確認プロンプトが表示される
- ロールへのメンバー追加はデータベース権限に直接影響

## 備考

- ユーザーとロールの両方をメンバーとして追加可能
- EnumMembers()で既存メンバーを確認してから追加
- db_datareader、db_datawriterなど組み込みロールにも対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Add-DbaDbRoleMember.ps1 | `public/Add-DbaDbRoleMember.ps1` | 出力なし（追加操作）- .OUTPUTSセクション確認 |

**読解のコツ**: 追加操作のため出力オブジェクトはない。処理結果はVerboseメッセージまたは警告で示される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Add-DbaDbRoleMember.ps1 | `public/Add-DbaDbRoleMember.ps1` | param()ブロック（92-105行目）でパラメータ定義確認 |

**主要処理フロー**:
1. **107行目**: processブロック開始
2. **108-111行目**: InputObject/SqlInstance存在チェック
3. **117-140行目**: 入力タイプ別のswitch処理
4. **142-145行目**: Roleパラメータ必須チェック
5. **147-173行目**: ロール/メンバーループとAddMember処理

#### Step 3: メンバー追加ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaDbRoleMember.ps1 | `public/Add-DbaDbRoleMember.ps1` | 147-173行目のメンバー追加処理 |

**主要処理フロー**:
- **152行目**: EnumMembers()で既存メンバー取得
- **154-161行目**: Users内存在確認と追加処理
- **162-168行目**: Roles内存在確認と追加処理
- **169-171行目**: 存在しない場合の警告出力

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

```
Add-DbaDbRoleMember
    │
    ├─ 入力タイプ判定（GetType().FullName）
    │      ├─ DbaInstanceParameter
    │      ├─ Server
    │      ├─ Database
    │      └─ DatabaseRole
    │
    ├─ Get-DbaDbRole（ロールオブジェクト取得）
    │      └─ Database + Role フィルタ
    │
    └─ foreach dbRole
           ├─ EnumMembers()（既存メンバー取得）
           │
           └─ foreach newMember
                  ├─ db.Users.Name（ユーザー存在確認）
                  ├─ db.Roles.Name（ロール存在確認）
                  ├─ members -notcontains（重複確認）
                  ├─ ShouldProcess確認
                  └─ AddMember()（メンバー追加）
```

### データフロー図

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

SqlInstance ─────────▶ 入力タイプ判定
      or                      │
InputObject ─────────────────┤
(Server/Database/            │
 DatabaseRole)               ▼
                       Get-DbaDbRole ─────────────▶ DatabaseRole[]
                              │
Role[] ──────────────────────┤
                              │
Member[] ────────────────────┤
                              ▼
                       EnumMembers()
                              │
                              ▼
                       存在確認
                       (Users/Roles) ─────────────▶ 警告（存在しない場合）
                              │
                              ▼
                       重複確認 ───────────────────▶ スキップ（既存の場合）
                              │
                              ▼
                       AddMember() ───────────────▶ (なし)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Add-DbaDbRoleMember.ps1 | `public/Add-DbaDbRoleMember.ps1` | ソース | メイン機能実装 |
| Get-DbaDbRole.ps1 | `public/Get-DbaDbRole.ps1` | ソース | データベースロール取得 |
