# 機能設計書 575-Remove-DbaDbRoleMember

## 概要

本ドキュメントは、SQL Serverデータベースロールからユーザーを削除する `Remove-DbaDbRoleMember` 機能の設計仕様を定義するものです。

### 本機能の処理概要

`Remove-DbaDbRoleMember` は、SQL Serverデータベースロールからメンバー（ユーザー）を削除するdbatools PowerShellコマンドレットです。db_datareader、db_datawriter、db_ownerなどの組み込みロールおよびカスタムデータベースロールからユーザーを削除できます。複数のロールや複数のユーザーを一度に処理できるため、大規模な権限変更作業を効率化します。

**業務上の目的・背景**：組織の人事異動、プロジェクト終了、セキュリティポリシーの変更などにより、ユーザーのデータベースアクセス権限を削減する必要があります。本機能により、複数インスタンス・複数データベースにわたるロールメンバーシップを一括で管理できます。

**機能の利用シーン**：
- 従業員の部署異動時の権限剥奪
- プロジェクト終了時のアクセス権限クリーンアップ
- セキュリティ監査後の過剰権限の削除
- 定期的な権限レビューと調整

**主要な処理内容**：
1. 入力オブジェクトタイプの判定（インスタンス、データベース、ロール）
2. Get-DbaDbRoleによる対象ロールの取得
3. EnumMembers()によるロールメンバーの列挙
4. 指定ユーザーがメンバーかどうかの確認
5. DropMember()メソッドによるメンバー削除

**関連システム・外部連携**：SQL Server SMOライブラリ、Get-DbaDbRole、Get-DbaDatabase との連携。

**権限による制御**：ALTER ANY ROLE権限または対象ロールに対するALTER権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SSMSデータベースロールメンバー管理画面 | 参照画面 | GUIでのロールメンバー削除に相当する操作 |

## 機能種別

CRUD操作（Delete / ロールメンバーシップ管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | No* | 対象のSQL Serverインスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効なPSCredentialオブジェクト |
| Database | String[] | No | 対象データベース | - |
| Role | String[] | No | 対象ロール | ロール指定またはロールオブジェクトパイプ必須 |
| User | String[] | Yes | 削除対象ユーザー | 必須パラメータ |
| InputObject | Object[] | No* | パイプライン入力 | サーバー/DB/ロールオブジェクト |
| EnableException | Switch | No | 例外を有効化するスイッチ | - |

*SqlInstanceまたはInputObjectのいずれかが必須

### 入力データソース

- PowerShellコマンドライン入力
- パイプライン入力（サーバー、データベース、ロールオブジェクト）

## 出力仕様

### 出力データ

本機能は出力オブジェクトを返しません。処理結果はVerboseメッセージで通知されます。

### 出力先

- コンソール（Write-Message経由）

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ InputObjectまたはSqlInstanceの指定を確認
2. 入力オブジェクトタイプ判定
   ├─ DbaInstanceParameter → Get-DbaDbRoleで取得
   ├─ Server → Get-DbaDbRoleで取得
   ├─ Database → Get-DbaDbRoleで取得
   └─ DatabaseRole → 直接使用
3. Roleパラメータ検証
   └─ DatabaseRoleパイプ以外ではRole指定必須
4. ロールループ
   ├─ EnumMembers()でメンバー取得
   └─ ユーザーループ
       ├─ メンバーシップ確認
       ├─ ShouldProcess確認
       └─ DropMember()実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject or SqlInstance指定?}
    B -->|No| C[エラー: 入力必須]
    B -->|Yes| D[入力タイプ判定]
    D --> E{タイプ?}
    E -->|DbaInstanceParameter| F[Get-DbaDbRole呼び出し]
    E -->|Server| F
    E -->|Database| G[パイプ経由Get-DbaDbRole]
    E -->|DatabaseRole| H[直接使用]
    E -->|その他| I[エラー: 無効な入力]
    F --> J{Roleパラメータ確認}
    G --> J
    H --> K[ロールループ開始]
    J --> L{Role指定 or DatabaseRole?}
    L -->|No| M[エラー: Role必須]
    L -->|Yes| K
    K --> N[EnumMembers取得]
    N --> O[ユーザーループ開始]
    O --> P{ユーザーがメンバー?}
    P -->|No| Q[スキップ]
    P -->|Yes| R{ShouldProcess確認}
    R -->|No| S[スキップ]
    R -->|Yes| T[DropMember実行]
    T --> U[Verboseログ]
    Q --> V{次のユーザー?}
    S --> V
    U --> V
    V -->|Yes| O
    V -->|No| W{次のロール?}
    W -->|Yes| K
    W -->|No| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | メンバーシップ確認 | DropMember前にEnumMembersでメンバーシップを確認 | 常時 |
| BR-002 | 非メンバースキップ | メンバーでないユーザーはスキップ | 常時 |
| BR-003 | ロール指定必須 | DatabaseRoleパイプ以外ではRoleパラメータ必須 | InputTypeがDatabaseRole以外 |

### 計算ロジック

特に計算ロジックはありません。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メンバー削除 | sys.database_role_members | DELETE | ロールメンバーシップの削除 |

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

#### sys.database_role_members

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | role_principal_id, member_principal_id | 対象ロールとユーザーのID | SMO DropMember()で実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InputError | 入力エラー | SqlInstanceもInputObjectも未指定 | いずれかを指定 |
| InvalidInputType | タイプエラー | サポートされない入力タイプ | 正しいオブジェクトをパイプ |
| RoleRequired | ロール未指定 | DatabaseRoleパイプ以外でRole未指定 | Roleを指定 |

### リトライ仕様

エラー発生時はStop-Functionで処理を中断し、次の処理へ継続します。

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

SMOのDropMember()メソッドによる暗黙的トランザクションで処理されます。

## パフォーマンス要件

通常のメンバー削除は1秒以内で完了します。多数のユーザー・ロールを処理する場合は処理時間が増加します。

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

- ALTER ANY ROLE権限または対象ロールへのALTER権限が必要
- ConfirmImpact=Highによるデフォルト確認プロンプト
- 監査ログによる操作追跡を推奨

## 備考

- Userパラメータは必須
- パイプライン入力による柔軟な操作が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DatabaseRole (SMO) | Microsoft.SqlServer.Management.Smo | SMOのDatabaseRoleクラスとEnumMembers() |

**読解のコツ**: EnumMembers()はロールのメンバー名を文字列配列として返します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Remove-DbaDbRoleMember.ps1 | `public/Remove-DbaDbRoleMember.ps1` | 関数定義とパラメータバインディング |

**主要処理フロー**:
1. **91-103行目**: パラメータ定義（Userは必須）
2. **105-109行目**: 入力検証
3. **115-138行目**: 入力タイプ別のロール取得

#### Step 3: 入力タイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaDbRoleMember.ps1 | `public/Remove-DbaDbRoleMember.ps1` | switch文による入力タイプ判定 |

**主要処理フロー**:
- **116-138行目**: switch文で4種類の入力タイプを処理
- **118-121行目**: DbaInstanceParameter → Get-DbaDbRole
- **126-128行目**: Database → パイプ経由Get-DbaDbRole
- **130-132行目**: DatabaseRole → 直接使用

#### Step 4: メンバー削除処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Remove-DbaDbRoleMember.ps1 | `public/Remove-DbaDbRoleMember.ps1` | EnumMembersとDropMember |

**主要処理フロー**:
- **140-143行目**: Role未指定チェック
- **145-161行目**: ロール・ユーザーループ
- **151行目**: EnumMembers()でメンバー取得
- **154行目**: メンバーシップ確認（$members -contains $username）
- **157行目**: DropMember($username)実行

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

```
Remove-DbaDbRoleMember
    │
    ├─ Get-DbaDbRole (入力タイプに応じて)
    │
    ├─ DatabaseRole.EnumMembers()
    │      └─ メンバー一覧取得
    │
    └─ DatabaseRole.DropMember($username)
           └─ メンバー削除
```

### データフロー図

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

SqlInstance ─────────▶ タイプ判定 ──────────▶ Get-DbaDbRole
        or                                         │
InputObject                                        │
(Server/DB/Role)                                   ▼
                                             ロールコレクション
                                                   │
User[] ──────────────────────────────────────────▶ ロールごとの処理
                                                   │
                                           EnumMembers()
                                                   │
                                           メンバーシップ確認
                                                   │
                                           DropMember($user)
                                                   │
                                                   ▼
                                           Verboseメッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaDbRoleMember.ps1 | `public/Remove-DbaDbRoleMember.ps1` | ソース | メイン関数定義 |
| Get-DbaDbRole.ps1 | `public/Get-DbaDbRole.ps1` | ソース | ロール取得 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | インスタンス接続 |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理 |
| Write-Message.ps1 | `private/functions/Write-Message.ps1` | ソース | メッセージ出力 |
