# 機能設計書 561-Get-DbaPermission

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるGet-DbaPermissionコマンドレットの機能設計を定義する。本機能は、SQL Serverインスタンスおよびデータベースにおける明示的権限と暗黙的権限を包括的に取得するセキュリティ監査機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：企業のデータベース環境では、セキュリティコンプライアンスの確保と定期的な権限監査が必要不可欠である。本機能は、SQL Serverに対する権限設定を一元的に可視化し、誰がどのような権限を持っているかを迅速に把握することで、セキュリティリスクの早期発見と権限管理の効率化を実現する。また、システム移行時の権限レプリケーションや、トラブルシューティングにおけるアクセス権問題の調査にも活用される。

**機能の利用シーン**：
- セキュリティ監査レポート作成時に全権限情報を収集する場合
- 新規環境へのセキュリティ設定移行を計画する際の現状把握
- アクセス権限問題のトラブルシューティング時
- コンプライアンス要件への適合確認作業
- 不要な権限付与の洗い出しとクリーンアップ計画

**主要な処理内容**：
1. SQL Serverインスタンスへの接続確立（SQL Server 2005以降が必要）
2. サーバーレベル権限の取得（オプション、-IncludeServerLevelスイッチ使用時）
3. 各データベースへのアクセス可否確認
4. sys.database_permissionsからの明示的権限情報取得
5. 固定ロール（db_owner、db_datareader等）からの暗黙的権限情報生成
6. dboユーザー、db_ownerロールメンバー、スキーマ所有者の暗黙的CONTROL権限取得
7. 取得した権限情報にGRANT/REVOKEステートメントを付加して出力

**関連システム・外部連携**：
- SQL Server Management Objects (SMO)を使用したデータベース接続
- sys.server_permissions、sys.database_permissions等のシステムビューへのクエリ実行
- sys.fn_builtin_permissions関数による組み込み権限情報の参照

**権限による制御**：
- 対象インスタンスへの接続権限が必要
- サーバーレベル権限取得には、sys.server_permissionsへのSELECT権限が必要
- データベースレベル権限取得には、各データベースへのアクセス権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 71 | 権限取得 | 主機能 | SQL Server権限の取得 |

## 機能種別

データ取得（SELECT）/ セキュリティ監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可、複数指定可 |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証、AD認証対応 |
| Database | object[] | No | 対象データベース名 | ワイルドカード対応、複数指定可 |
| ExcludeDatabase | object[] | No | 除外データベース名 | ワイルドカード対応、複数指定可 |
| IncludeServerLevel | switch | No | サーバーレベル権限を含める | 指定時のみサーバー権限を出力 |
| ExcludeSystemObjects | switch | No | システムオブジェクト権限を除外 | major_id > 0でフィルタ |
| EnableException | switch | No | 例外を直接スローする | デフォルトは警告メッセージ表示 |

### 入力データソース

- パイプライン入力：SqlInstanceパラメータがValueFromPipelineを受け付ける
- 対話入力：PowerShellコンソールからのパラメータ指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名（既定はMSSQLSERVER） |
| SqlInstance | string | 完全なSQL Serverインスタンス名（computer\instance形式） |
| Database | string | データベース名（サーバーレベル権限は空文字） |
| PermState | string | 権限状態：GRANT、DENY、REVOKE（暗黙的権限は空文字） |
| PermissionName | string | 権限名（SELECT、CONTROL、CONNECT等） |
| SecurableType | string | セキュリティ保護可能オブジェクトの種別 |
| Securable | string | セキュリティ保護可能オブジェクトの名前 |
| Grantee | string | 権限を持つプリンシパル名 |
| GranteeType | string | プリンシパルの種別（LOGIN、USER、ROLE等） |
| RevokeStatement | string | 権限取り消し用T-SQLステートメント |
| GrantStatement | string | 権限付与用T-SQLステートメント |

### 出力先

- PowerShellパイプライン：System.Data.DataRowオブジェクトとして出力
- 後続のPowerShellコマンドへの入力、ファイル出力、画面表示等に利用可能

## 処理フロー

### 処理シーケンス

```
1. beginブロックでSQLクエリ文字列を構築
   └─ ExcludeSystemObjectsスイッチに応じてWHERE句を追加
   └─ サーバーレベル権限用SQLとデータベースレベル権限用SQLを定義

2. processブロックで各SqlInstanceに対して処理
   └─ Connect-DbaInstanceで接続確立（最低バージョン9=SQL Server 2005）

3. IncludeServerLevelが指定されている場合
   └─ サーバーレベル権限SQLを実行して出力

4. データベースリストの取得とフィルタリング
   └─ Databaseパラメータで包含フィルタ適用
   └─ ExcludeDatabaseパラメータで除外フィルタ適用

5. 各データベースに対してループ処理
   └─ IsAccessible確認（アクセス不可の場合はスキップ）
   └─ データベースレベル権限SQLを実行して出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ文字列構築]
    B --> C{ExcludeSystemObjects?}
    C -->|Yes| D[WHERE major_id > 0 追加]
    C -->|No| E[WHERE句なし]
    D --> F[インスタンスループ開始]
    E --> F
    F --> G[Connect-DbaInstance]
    G --> H{接続成功?}
    H -->|No| I[警告出力・次へ]
    H -->|Yes| J{IncludeServerLevel?}
    J -->|Yes| K[サーバー権限SQL実行・出力]
    J -->|No| L[データベースリスト取得]
    K --> L
    L --> M[Database/ExcludeDatabaseフィルタ適用]
    M --> N[データベースループ開始]
    N --> O{IsAccessible?}
    O -->|No| P[警告出力・次のDB]
    O -->|Yes| Q[DB権限SQL実行・出力]
    Q --> R{次のDBあり?}
    P --> R
    R -->|Yes| N
    R -->|No| S{次のインスタンスあり?}
    I --> S
    S -->|Yes| F
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最低バージョン要件 | SQL Server 2005以降が必要 | 接続時 |
| BR-002 | 暗黙的権限出力 | 固定ロールやdbo等の暗黙的権限も出力 | 常時 |
| BR-003 | アクセス不可DB除外 | IsAccessible=falseのDBはスキップ | 各DB処理時 |
| BR-004 | システムオブジェクト除外 | major_id=0のオブジェクトを除外 | ExcludeSystemObjects指定時 |

### 計算ロジック

**固定サーバーロール権限マッピング**：
- bulkadmin → ADMINISTER BULK OPERATIONS
- dbcreator → CREATE ANY DATABASE
- diskadmin → ALTER RESOURCES
- processadmin → ALTER ANY CONNECTION, ALTER SERVER STATE
- sysadmin → CONTROL SERVER
- securityadmin → ALTER ANY LOGIN
- serveradmin → ALTER ANY ENDPOINT, ALTER RESOURCES, ALTER SERVER STATE, ALTER SETTINGS, SHUTDOWN, VIEW SERVER STATE
- setupadmin → ALTER ANY LINKED SERVER

**固定データベースロール権限マッピング**：
- db_accessadmin → ALTER ANY USER, CREATE SCHEMA
- db_backupoperator → BACKUP DATABASE, BACKUP LOG, CHECKPOINT
- db_datareader/db_denydatareader → SELECT
- db_datawriter/db_denydatawriter → INSERT, DELETE, UPDATE
- db_ddladmin → 各種DDL関連権限
- db_owner → CONTROL
- db_securityadmin → ALTER ANY APPLICATION ROLE, ALTER ANY ROLE, CREATE SCHEMA, VIEW DEFINITION

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| サーバー権限取得 | sys.server_permissions | SELECT | サーバーレベル明示的権限 |
| サーバー権限取得 | sys.server_principals | SELECT | プリンシパル情報結合 |
| サーバー権限取得 | sys.fn_builtin_permissions | SELECT | 組み込み権限参照 |
| DB権限取得 | sys.database_permissions | SELECT | データベースレベル明示的権限 |
| DB権限取得 | sys.database_principals | SELECT | DBプリンシパル情報 |
| DB権限取得 | sys.database_role_members | SELECT | ロールメンバーシップ |
| DB権限取得 | sys.schemas | SELECT | スキーマ所有者情報 |
| DB権限取得 | sys.databases | SELECT | DB所有者情報 |

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

#### sys.server_permissions
| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | state_desc, permission_name, class_desc, major_id, grantee_principal_id | 全レコード対象 | サーバー権限の基本情報 |

#### sys.database_permissions
| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | state_desc, permission_name, class_desc, major_id, minor_id, grantee_principal_id | ExcludeSystemObjects時はmajor_id > 0 | DB権限の基本情報 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | インスタンス接続失敗 | 警告出力後、次のインスタンスへ継続 |
| ExecutionError | 実行エラー | SQLクエリ実行失敗 | 警告出力後、次のデータベースへ継続 |
| AccessError | アクセスエラー | DB IsAccessible=false | 警告出力後、次のデータベースへ継続 |

### リトライ仕様

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

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

読み取り専用操作のため、明示的なトランザクション制御は行わない。各クエリはSQL Server側の既定のトランザクション分離レベルで実行される。

## パフォーマンス要件

- 大規模データベース環境でも効率的に動作するよう、T-SQLクエリで結果を一括取得
- パイプライン出力により、結果を逐次処理可能
- データベースが多数ある場合でも、各DBに対して個別にクエリを実行して段階的に出力

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

- 認証情報はPSCredentialオブジェクトを使用し、平文パスワードを扱わない
- Connect-DbaInstanceを通じてWindows認証、SQL認証、Azure AD認証に対応
- 出力にはGRANT/REVOKEステートメントが含まれるため、出力ファイルの取り扱いに注意が必要
- 権限情報は機密性が高いため、適切なアクセス制御が必要

## 備考

- SQL Server 2005以降が必要（MinimumVersion 9でチェック）
- Azure SQL Databaseでの動作検証は個別に必要
- 出力されるGRANT/REVOKEステートメントはそのまま実行可能なT-SQL

---

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

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

### 推奨読解順序

#### Step 1: パラメータ定義とクエリ構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | パラメータ定義（111-121行目）とbeginブロックでのSQL構築 |

**読解のコツ**: beginブロック（122-324行目）でサーバー権限用SQL（$ServPermsql）とデータベース権限用SQL（$DBPermsql）が構築されている。SQL文字列内で$ExcludeSystemObjectssql変数が埋め込まれている点に注目。

**主要処理フロー**:
1. **122-126行目**: ExcludeSystemObjectsスイッチに応じてWHERE句を構築
2. **127-183行目**: サーバーレベル権限取得用SQLを定義（UNION ALLで明示的権限と固定ロール権限を結合）
3. **185-323行目**: データベースレベル権限取得用SQLを定義（4つのUNION ALLで構成）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | processブロック（326-365行目）のインスタンスループ処理 |

**主要処理フロー**:
- **327-332行目**: 各SqlInstanceに対してConnect-DbaInstanceで接続
- **334-337行目**: IncludeServerLevel指定時にサーバー権限SQLを実行・出力
- **339-347行目**: データベースリスト取得とフィルタリング
- **349-363行目**: 各データベースに対してアクセス可否確認後、権限SQLを実行・出力

#### Step 3: SQLクエリの詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | $ServPermsql内のUNION ALL構造（127-183行目） |
| 3-2 | Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | $DBPermsql内の4段階UNION ALL構造（185-323行目） |

**サーバー権限SQL構造**:
- 前半部分：sys.server_permissionsから明示的権限を取得
- 後半部分：固定サーバーロール（sysadmin, dbcreator等）の暗黙的権限をマッピング

**DB権限SQL構造**:
1. sys.database_permissionsからの明示的権限
2. 固定DBロール（db_owner, db_datareader等）の暗黙的権限
3. dboユーザー（DATABASE OWNER）のCONTROL権限
4. db_ownerロールメンバーのCONTROL権限
5. スキーマ所有者のCONTROL権限

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

```
Get-DbaPermission
    │
    ├─ Connect-DbaInstance（接続確立）
    │      └─ MinimumVersion 9（SQL Server 2005以降を要求）
    │
    ├─ $server.Query($ServPermsql)（サーバー権限取得、IncludeServerLevel時のみ）
    │
    ├─ $server.Databases（データベースリスト取得）
    │      ├─ Where-Object Name -In $Database（包含フィルタ）
    │      └─ Where-Object Name -NotIn $ExcludeDatabase（除外フィルタ）
    │
    └─ $db.ExecuteWithResults($DBPermsql)（各DBの権限取得）
           └─ Tables.Rows（結果行をパイプライン出力）
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance ─────────────▶ 接続オブジェクト
                                  │
IncludeServerLevel ──────▶ 条件分岐 ──────────────────────▶ サーバー権限DataRow
                                  │
Database ────────────────▶ フィルタ処理 ──────────────────▶ 対象DBリスト
ExcludeDatabase                   │
                                  │
ExcludeSystemObjects ────▶ WHERE句構築 ─────┐
                                            │
                           ▼                ▼
                     各DB権限SQL実行 ─────────▶ DB権限DataRow
                           │
                           ▼
                     パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaPermission.ps1 | `public/Get-DbaPermission.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
