# 機能設計書 568-New-DbaDbUser

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるNew-DbaDbUserコマンドレットの機能設計を定義する。本機能は、SQL Serverデータベース内にユーザーを作成し、SQLログインマッピング、包含ユーザー、Azure AD認証など多様な認証方式に対応したユーザープロビジョニングを実現する。

### 本機能の処理概要

**業務上の目的・背景**：データベースユーザーの作成は、SQL Server環境におけるアクセス管理の基本操作である。ログインからユーザーへのマッピング、包含データベースでの直接認証、クラウド環境でのAzure AD認証など、多様なシナリオに対応する必要がある。本機能は、これらの認証タイプをパラメータセットで整理し、一貫したインターフェースで複数データベースへのユーザー作成を自動化する。

**機能の利用シーン**：
- アプリケーションユーザーの一括作成
- ログインからデータベースユーザーへのマッピング設定
- 包含データベースでのSQLユーザー作成
- Azure AD統合環境でのAADユーザー作成
- 複数データベースへの同一ユーザー展開

**主要な処理内容**：
1. パラメータセットに基づいてUserTypeを決定（SqlUser/External/NoLogin）
2. SQL Serverインスタンスへの接続確立
3. Login指定時はログイン存在確認
4. 各データベースでスキーマ存在確認、既存ユーザーチェック
5. Force指定時は既存ユーザー削除
6. SMO Userオブジェクト作成、プロパティ設定
7. Create()メソッドでユーザー作成実行

**関連システム・外部連携**：
- SQL Server Management Objects (SMO)のUserクラス
- Get-DbaDatabase経由でのデータベース取得
- Azure Active Directory（ExternalProvider使用時）

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | 位置パラメータ1 |
| SqlCredential | PSCredential | No | 接続用認証情報 | Windows/SQL認証対応 |
| Database | string[] | No | 対象データベース名 | 複数指定可 |
| ExcludeDatabase | string[] | No | 除外データベース名 | 複数指定可 |
| IncludeSystem | switch | No | システムDBを含める | デフォルトは除外 |
| User | string | 条件付き必須 | ユーザー名 | パラメータセットにより必須/任意 |
| Login | string | 条件付き必須 | マッピング先ログイン名 | パラメータセットLoginで必須 |
| SecurePassword | SecureString | 条件付き必須 | 包含ユーザーのパスワード | パラメータセットContainedSQLUserで必須 |
| ExternalProvider | switch | 条件付き必須 | Azure AD認証使用 | パラメータセットContainedAADUserで必須 |
| DefaultSchema | string | No | 既定スキーマ | デフォルトdbo |
| Force | switch | No | 既存ユーザーを上書き | 削除後に再作成 |
| WhatIf | switch | No | 実行シミュレーション | 変更なし |
| Confirm | switch | No | 確認プロンプト | ConfirmImpact="Medium" |
| EnableException | switch | No | 例外を直接スローする | デフォルトは警告メッセージ |

### 入力データソース

- コンソール入力：必須パラメータとしてSqlInstanceを指定
- パラメータセット：Login/ContainedSQLUser/ContainedAADUser/NoLoginの4種類

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | データベース名 |
| Name | string | ユーザー名 |
| LoginType | string | ログインタイプ |
| Login | string | マッピング先ログイン名 |
| AuthenticationType | string | 認証タイプ |
| DefaultSchema | string | 既定スキーマ |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. beginブロックでパラメータセット確認とUserType決定
   └─ Login未指定時はUser=Loginとして設定
   └─ ExternalProvider → UserType = External
   └─ SecurePassword/Login → UserType = SqlUser
   └─ その他 → UserType = NoLogin

2. processブロックで各SqlInstanceに対して処理
   └─ Connect-DbaInstance

3. 接続後の検証
   └─ Login指定時はログイン存在確認

4. Get-DbaDatabase経由でデータベース取得
   └─ Database/ExcludeDatabase/ExcludeSystemでフィルタ
   └─ IsUpdateableのみ処理

5. 各データベースに対してループ
   └─ DefaultSchema存在確認
   └─ 既存ユーザーチェック（Force時は削除）
   └─ New-Object Userで作成
   └─ Login、UserType、DefaultSchema設定
   └─ Create()実行（SecurePassword有無で分岐）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[beginブロック: UserType決定]
    B --> C{ExternalProvider?}
    C -->|Yes| D[UserType=External]
    C -->|No| E{SecurePassword/Login?}
    E -->|Yes| F[UserType=SqlUser]
    E -->|No| G[UserType=NoLogin]
    D --> H[インスタンスループ開始]
    F --> H
    G --> H
    H --> I[Connect-DbaInstance]
    I --> J{Login指定?}
    J -->|Yes| K{ログイン存在?}
    K -->|No| L[エラー・次へ]
    K -->|Yes| M[Get-DbaDatabase]
    J -->|No| M
    M --> N[IsUpdateableでフィルタ]
    N --> O[DBループ開始]
    O --> P{DefaultSchema存在?}
    P -->|No| Q[エラー・次のDB]
    P -->|Yes| R{既存ユーザー存在?}
    R -->|Yes| S{Force?}
    S -->|Yes| T[既存ユーザー削除]
    S -->|No| U[エラー・次のDB]
    R -->|No| V[ShouldProcess確認]
    T --> V
    V --> W[New-Object User]
    W --> X[Login/UserType/DefaultSchema設定]
    X --> Y{SecurePassword?}
    Y -->|Yes| Z[Create with password]
    Y -->|No| AA[Create without password]
    Z --> AB[Add-Member]
    AA --> AB
    AB --> AC[Select-DefaultView出力]
    AC --> AD{次のDBあり?}
    Q --> AD
    U --> AD
    AD -->|Yes| O
    AD -->|No| AE{次のインスタンスあり?}
    L --> AE
    AE -->|Yes| H
    AE -->|No| AF[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パラメータセット | Login/ContainedSQLUser/ContainedAADUser/NoLoginの4パターン | 入力時 |
| BR-002 | User名デフォルト | Login指定時、User未指定ならLogin名を使用 | Login指定時 |
| BR-003 | ログイン存在確認 | Login指定時、サーバーにログインが存在する必要あり | 処理前 |
| BR-004 | スキーマ存在確認 | DefaultSchemaが指定データベースに存在する必要あり | 各DB |
| BR-005 | 既存チェック | 同名ユーザー存在時はForceなしでエラー | 各DB |
| BR-006 | DefaultSchemaデフォルト | 未指定時はdbo | ユーザー作成時 |

### 計算ロジック

**UserType決定ロジック**:
- ExternalProvider → [Microsoft.SqlServer.Management.Smo.UserType]::External
- SecurePassword or Login → [Microsoft.SqlServer.Management.Smo.UserType]::SqlUser
- その他 → [Microsoft.SqlServer.Management.Smo.UserType]::NoLogin

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ログイン確認 | sys.server_principals | SELECT | ログイン存在確認 |
| スキーマ確認 | sys.schemas | SELECT | スキーマ存在確認 |
| ユーザー存在確認 | sys.database_principals | SELECT | 同名ユーザー確認 |
| ユーザー削除 | sys.database_principals | DELETE | Force時の既存削除 |
| ユーザー作成 | sys.database_principals | INSERT | 新規ユーザー作成 |

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | インスタンス接続失敗 | 警告出力後、次のインスタンスへ継続 |
| LoginNotFound | ログイン未存在 | Login指定時にログイン未存在 | エラー出力後、次のインスタンスへ継続 |
| SchemaNotFound | スキーマ未存在 | DefaultSchema未存在 | エラー出力後、次のDBへ継続 |
| ExistsError | 既存エラー | 同名ユーザー存在＆Force未指定 | エラー出力後、次のDBへ継続 |
| DropError | 削除エラー | Force時の既存削除失敗 | エラー出力後、次のDBへ継続 |
| CreateError | 作成エラー | Create()失敗 | エラー出力後、次のDBへ継続 |

### リトライ仕様

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

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

- 各ユーザー作成は個別のDDL操作として実行
- Force時の削除と作成は別トランザクション
- 複数DB処理時、一部失敗しても他は継続

## パフォーマンス要件

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

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

- パスワードはSecureStringで受け渡し
- ALTER ANY USER権限が必要
- 認証情報はPSCredentialオブジェクトを使用
- 包含ユーザーの場合、パスワードはデータベース内に保存

## 備考

- パラメータセットを使用した高度なパラメータ検証
- コード内コメントは学習用サンプルとして詳細記載
- Azure AD認証はAzure SQL Database/Managed Instance向け

---

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

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

### 推奨読解順序

#### Step 1: パラメータセットを理解する

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

**読解のコツ**: 4つのパラメータセット（Login/NoLogin/ContainedSQLUser/ContainedAADUser）の構造を理解する。コード内コメントが学習用に詳細。

**主要処理フロー**:
- **161-166行目**: User（パラメータセットにより必須/任意）
- **168-169行目**: Login（パラメータセットLoginで必須）
- **171-173行目**: SecurePassword（パラメータセットContainedSQLUserで必須）
- **174-175行目**: ExternalProvider（パラメータセットContainedAADUserで必須）

#### Step 2: UserType決定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaDbUser.ps1 | `public/New-DbaDbUser.ps1` | beginブロック（187-209行目） |

**主要処理フロー**:
- **193-196行目**: Login指定時、User未指定ならLoginをUserに設定
- **200-208行目**: パラメータに基づきUserType決定（External/SqlUser/NoLogin）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaDbUser.ps1 | `public/New-DbaDbUser.ps1` | processブロック（212-294行目） |

**主要処理フロー**:
- **229-231行目**: Login指定時のログイン存在確認
- **237行目**: Get-DbaDatabase（ExcludeSystem指定）
- **239行目**: IsUpdateableでフィルタ
- **245-247行目**: DefaultSchema存在確認
- **251-263行目**: 既存ユーザーチェックとForce処理
- **265-291行目**: Userオブジェクト作成とCreate実行

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

```
New-DbaDbUser
    │
    ├─ beginブロック
    │      ├─ User = Login（未指定時）
    │      └─ UserType決定（External/SqlUser/NoLogin）
    │
    ├─ Connect-DbaInstance
    │
    ├─ $server.Logins[$Login]（ログイン存在確認）
    │
    ├─ Get-DbaDatabase
    │      └─ -ExcludeSystem:$(-not $IncludeSystem)
    │
    └─ foreach $db
           ├─ $db.Schemas[$DefaultSchema]（スキーマ確認）
           │
           ├─ $db.Users[$User]（既存確認）
           │      └─ Drop()（Force時）
           │
           ├─ New-Object User
           │      ├─ Parent = $db
           │      ├─ Name = $User
           │      ├─ Login = $Login
           │      ├─ UserType = $userType
           │      └─ DefaultSchema = $DefaultSchema
           │
           ├─ $newUser.Create($SecurePassword) または Create()
           │
           └─ Add-Member → Select-DefaultView
```

### データフロー図

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

Login ───────────────────▶ User名デフォルト決定 ───────────▶ $User
User                              │
                                  ▼
ExternalProvider ────────▶ UserType決定 ───────────────────▶ $userType
SecurePassword                    │
                                  │
SqlInstance ─────────────▶ Connect-DbaInstance ─────────────▶ $server
                                  │
Login ───────────────────▶ ログイン存在確認 ───────────────▶ 検証OK/エラー
                                  │
Database ────────────────▶ Get-DbaDatabase ────────────────▶ $databases
ExcludeDatabase                   │
IncludeSystem                     │
                                  ▼
DefaultSchema ───────────▶ スキーマ存在確認 ───────────────▶ 検証OK/エラー
                                  │
Force ───────────────────▶ 既存削除 ────────────────────────▶ 削除完了
                                  │
                           New-Object User ────────────────▶ $newUser
                                  │
SecurePassword ──────────▶ Create() ───────────────────────▶ ユーザー作成
                                  │
                           Select-DefaultView ─────────────▶ 出力オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaDbUser.ps1 | `public/New-DbaDbUser.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
