# 機能設計書 567-New-DbaDbRole

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるNew-DbaDbRoleコマンドレットの機能設計を定義する。本機能は、SQL Serverデータベース内にカスタムデータベースロールを作成し、ロールベースのセキュリティ実装を支援する。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverのセキュリティ管理において、ロールベースアクセス制御（RBAC）は標準的なアプローチである。固定データベースロール（db_owner、db_datareader等）に加え、組織固有の権限セットを定義するカスタムロールを作成することで、きめ細かいアクセス制御が可能になる。本機能は、複数データベースに対して一貫したロール作成を自動化し、手動でのSSMSやT-SQL操作を不要にする。

**機能の利用シーン**：
- アプリケーション固有の権限セットを持つロール作成
- 複数データベースへの標準ロール一括展開
- 開発/本番環境間でのロール構成統一
- セキュリティポリシーに基づくロール構成の自動化
- データベース移行時のロール再作成

**主要な処理内容**：
1. SqlInstance指定時はGet-DbaDatabase経由でデータベースオブジェクト取得
2. パイプライン入力のデータベースオブジェクトも処理可能
3. 各データベースでロール名の重複チェック
4. SMO DatabaseRoleオブジェクトを作成
5. Owner設定（デフォルトはdbo）
6. Create()メソッドでロール作成実行

**関連システム・外部連携**：
- SQL Server Management Objects (SMO)のDatabaseRoleクラス
- Get-DbaDatabase経由でのデータベース取得

**権限による制御**：
- 対象データベースでのALTER ANY ROLE権限が必要
- db_securityadminまたはdb_ownerロールのメンバーは暗黙的に権限あり

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 37 | データベースロール管理 | 主機能 | データベースロールの作成 |

## 機能種別

データ作成（INSERT）/ セキュリティ管理 / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | InputObjectと排他使用 |
| SqlCredential | PSCredential | No | 接続用認証情報 | Windows/SQL認証対応 |
| Database | string[] | No | 対象データベース名 | ワイルドカード対応 |
| ExcludeDatabase | string[] | No | 除外データベース名 | 複数指定可 |
| Role | string[] | No | 作成するロール名 | 必須（値未指定時エラー） |
| Owner | string | No | ロール所有者 | デフォルトdbo |
| InputObject | Database[] | No | パイプラインからのDBオブジェクト | ValueFromPipeline |
| WhatIf | switch | No | 実行シミュレーション | 変更なし |
| Confirm | switch | No | 確認プロンプト | ConfirmImpact="Medium" |
| EnableException | switch | No | 例外を直接スローする | デフォルトは警告メッセージ |

### 入力データソース

- パイプライン入力：InputObjectパラメータがDatabaseオブジェクトを受け付ける
- SqlInstance指定：Get-DbaDatabase経由で対象データベース取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Name | string | ロール名 |
| Parent | string | データベース名（ParentNameから取得） |
| Owner | string | ロール所有者 |

### 出力先

- PowerShellパイプライン：Microsoft.SqlServer.Management.Smo.DatabaseRoleオブジェクト
- Select-DefaultViewで既定表示プロパティを設定

## 処理フロー

### 処理シーケンス

```
1. processブロックで入力検証
   └─ InputObjectとSqlInstanceの両方が未指定ならエラー
   └─ Roleパラメータ未指定ならエラー

2. SqlInstance指定時
   └─ Get-DbaDatabase経由でDatabaseオブジェクト取得
   └─ Database/ExcludeDatabaseでフィルタリング

3. InputObject（Database[]）に対してループ
   └─ IsAccessible=trueのみ処理

4. 各データベース・各ロール名に対してループ
   └─ 既存ロールチェック（存在すればエラー）
   └─ New-Object DatabaseRoleで作成
   └─ Owner設定
   └─ Create()実行
   └─ カスタムプロパティ追加
   └─ Select-DefaultView出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject/SqlInstance指定?}
    B -->|No| C[エラー終了]
    B -->|Yes| D{Role指定?}
    D -->|No| E[エラー終了]
    D -->|Yes| F{SqlInstance指定?}
    F -->|Yes| G[Get-DbaDatabase実行]
    F -->|No| H[InputObject使用]
    G --> I[InputObjectに追加]
    H --> I
    I --> J[IsAccessible=trueでフィルタ]
    J --> K[DBループ開始]
    K --> L[$db.Rolesで既存ロール取得]
    L --> M[Roleループ開始]
    M --> N{同名ロール存在?}
    N -->|Yes| O[エラー・次のロールへ]
    N -->|No| P[ShouldProcess確認]
    P --> Q{ShouldProcess=Yes?}
    Q -->|No| R{次のロールあり?}
    Q -->|Yes| S[New-Object DatabaseRole]
    S --> T[Name, Parent, Owner設定]
    T --> U[$newRole.Create実行]
    U --> V[Add-Member: カスタムプロパティ]
    V --> W[Select-DefaultView出力]
    W --> R
    O --> R
    R -->|Yes| M
    R -->|No| X{次のDBあり?}
    X -->|Yes| K
    X -->|No| Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 入力必須チェック | InputObjectまたはSqlInstanceが必須 | 処理開始時 |
| BR-002 | Role必須チェック | Roleパラメータが必須 | 処理開始時 |
| BR-003 | 重複チェック | 同名ロールが存在する場合はエラー | 各ロール作成前 |
| BR-004 | Ownerデフォルト | Owner未指定時はdbo | ロール作成時 |
| BR-005 | アクセス可能DBのみ | IsAccessible=trueのDBのみ処理 | DB処理時 |

### 計算ロジック

特段の計算ロジックなし。SMOオブジェクトを使用した標準的なロール作成。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ロール存在確認 | sys.database_principals | SELECT | 同名ロール存在確認 |
| ロール作成 | sys.database_principals | INSERT | 新規ロール作成 |

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

#### sys.database_principals（SMO経由）
| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, type, owning_principal_id | パラメータ値、type='R' | Create()で実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InputError | 入力エラー | InputObject/SqlInstance未指定 | エラーメッセージ表示後終了 |
| InputError | 入力エラー | Role未指定 | エラーメッセージ表示後終了 |
| ExistsError | 既存エラー | 同名ロール存在 | エラー出力後、次のロールへ継続 |
| CreateError | 作成エラー | Create()失敗 | エラー出力後、次へ継続 |

### リトライ仕様

リトライ機能は実装されていない。エラー発生時は次のロール/データベースへ処理を継続する。

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

- 各ロール作成は個別のDDL操作として実行
- 複数ロール/複数DB処理時、一部失敗しても他は継続
- 暗黙的なトランザクション制御

## パフォーマンス要件

- SMOを使用した軽量な操作
- 複数ロール/複数データベース指定時は順次処理
- Get-DbaDatabase呼び出しによる若干のオーバーヘッド

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

- ALTER ANY ROLE権限が必要
- 認証情報はPSCredentialオブジェクトを使用
- 作成されるロールにはデフォルトで権限なし（別途権限付与が必要）

## 備考

- 作成されるロールはユーザー定義ロール（固定ロールではない）
- 権限付与は別途Grant系コマンドで実行する必要あり
- メンバー追加はAdd-DbaDbRoleMember等で実行

---

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

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

### 推奨読解順序

#### Step 1: パラメータ定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | New-DbaDbRole.ps1 | `public/New-DbaDbRole.ps1` | パラメータ定義（92-102行目） |

**読解のコツ**: SqlInstanceとInputObjectの両方がオプショナルだが、どちらかは必須。processブロックでチェック。

**主要処理フロー**:
- **93-94行目**: SqlInstance/SqlCredential
- **95-96行目**: Database/ExcludeDatabase
- **97-99行目**: Role/Owner
- **100行目**: InputObject（ValueFromPipeline）

#### Step 2: 入力検証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaDbRole.ps1 | `public/New-DbaDbRole.ps1` | processブロック冒頭の検証（103-112行目） |

**主要処理フロー**:
- **104-107行目**: InputObjectとSqlInstance両方未指定チェック
- **109-112行目**: Role未指定チェック

#### Step 3: メイン処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaDbRole.ps1 | `public/New-DbaDbRole.ps1` | ロール作成処理（114-161行目） |

**主要処理フロー**:
- **114-117行目**: SqlInstance指定時のGet-DbaDatabase呼び出し
- **120行目**: IsAccessible=trueでフィルタ
- **122-127行目**: DBループ開始、既存ロール取得
- **129-131行目**: 同名ロール存在チェック
- **135-147行目**: DatabaseRoleオブジェクト作成とCreate実行
- **149-154行目**: Add-Memberでカスタムプロパティ追加

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

```
New-DbaDbRole
    │
    ├─ 入力検証
    │      ├─ InputObject/SqlInstance両方未指定 → エラー
    │      └─ Role未指定 → エラー
    │
    ├─ Get-DbaDatabase（SqlInstance指定時）
    │      └─ -Database, -ExcludeDatabase でフィルタ
    │
    ├─ InputObject.Where IsAccessible
    │
    └─ foreach $db
           ├─ $db.Roles（既存ロール取得）
           │
           └─ foreach $r in $Role
                  ├─ 既存チェック → エラー時継続
                  │
                  ├─ New-Object DatabaseRole
                  │      ├─ Name = $r
                  │      ├─ Parent = $db
                  │      └─ Owner = $Owner または "dbo"
                  │
                  ├─ $newRole.Create()
                  │
                  └─ Add-Member → Select-DefaultView
```

### データフロー図

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

SqlInstance ─────────────▶ Get-DbaDatabase ────────────────▶ $InputObject
Database                          │
ExcludeDatabase                   │
                                  ▼
InputObject ─────────────▶ Where IsAccessible ─────────────▶ フィルタ済みDB
                                  │
                                  ▼
Role ────────────────────▶ 既存ロールチェック ─────────────▶ 重複なし確認
                                  │
Owner ───────────────────▶ New-Object DatabaseRole ────────▶ $newRole
                                  │
                           $newRole.Create() ──────────────▶ DB作成完了
                                  │
                           Add-Member ─────────────────────▶ 拡張DatabaseRole
                                  │
                           Select-DefaultView ─────────────▶ 出力オブジェクト
```

### 関連ファイル一覧

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