# 機能設計書 16-Grant-DbaAgPermission

## 概要

本ドキュメントは、可用性グループおよびデータベースミラーリングエンドポイントに対する特定の権限をログインに付与するGrant-DbaAgPermissionコマンドの機能設計書です。

### 本機能の処理概要

Grant-DbaAgPermissionは、SQL Serverログインに対して可用性グループ権限（Alter, Control, TakeOwnership, ViewDefinition）およびデータベースミラーリングエンドポイント権限（Connect, Alter, Control等）を付与するPowerShellコマンドレットです。高可用性およびディザスタリカバリシナリオの設定において、サービスアカウントやユーザーがAGリソースを管理または接続するために必要なアクセス権を設定します。

**業務上の目的・背景**：可用性グループを構成する際、各レプリカ間で通信するためにはデータベースミラーリングエンドポイントへのConnect権限が必要です。また、AG管理操作を行うためには適切なAGレベル権限が必要です。このコマンドは、複数サーバーにまたがるAG展開を簡素化し、必要な権限設定を自動化します。Windowsログインは対象インスタンスに存在しない場合、自動的に作成されます。

**機能の利用シーン**：
- 可用性グループの初期セットアップ時の権限付与
- 新規レプリカ追加時のエンドポイント権限設定
- サービスアカウント変更時の権限再設定
- 自動シーディング有効化（CreateAnyDatabase権限）
- セキュリティ監査後の権限修正

**主要な処理内容**：
1. 指定されたSQL Serverインスタンスに接続
2. 権限タイプに応じた処理分岐（Endpoint/AvailabilityGroup）
3. CreateAnyDatabase権限の場合はGrantAvailabilityGroupCreateDatabasePrivilege呼び出し
4. ログインが存在しない場合は自動作成
5. 指定された権限をエンドポイントまたはAGに付与
6. 結果オブジェクトを出力

**関連システム・外部連携**：
- SQL Server SMO (Server Management Objects)
- SQL Server可用性グループインフラストラクチャ
- データベースミラーリングエンドポイント
- SQL Serverセキュリティサブシステム（ログイン管理）

**権限による制御**：sysadmin固定サーバーロールのメンバーシップ、またはCONTROL SERVER権限とALTER ANY LOGIN権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | PowerShellコンソール/ISE | 主画面 | コマンド実行 |
| - | SSMSセキュリティプロパティ | 参照画面 | 権限設定の視覚的確認 |

## 機能種別

権限付与（Grant）/ セキュリティ設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | インスタンス接続可能性検証 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | 有効なPSCredentialオブジェクト |
| Login | string[] | No | 権限を付与するログイン名 | なし |
| AvailabilityGroup | string[] | No | 権限付与対象の可用性グループ名 | Type=AvailabilityGroup時は必須 |
| Type | string[] | Yes | 権限タイプ（Endpoint/AvailabilityGroup） | ValidateSet検証 |
| Permission | string[] | No | 付与する権限（デフォルト：Connect） | ValidateSet検証 |
| InputObject | Login[] | No | パイプライン入力用ログインオブジェクト | Microsoft.SqlServer.Management.Smo.Login型 |
| EnableException | switch | No | 例外を有効化 | なし |
| WhatIf | switch | No | 実行シミュレーション | なし |
| Confirm | switch | No | 実行前確認 | なし |

### 入力データソース

- PowerShellパラメータ入力
- パイプラインからのLoginオブジェクト（Get-DbaLogin出力）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Name | string | 権限を付与されたログイン名 |
| Permission | string | 付与された権限タイプ |
| Type | string | 操作タイプ（常に"Grant"） |
| Status | string | 操作結果（"Success"） |

### 出力先

- PowerShellパイプライン（標準出力）
- オブジェクト型：PSCustomObject
- 注意：CreateAnyDatabase権限付与時は出力なし

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ SqlInstanceまたはInputObjectの必須チェック
2. タイプ別バリデーション
   ├─ Endpoint + SqlInstance時：Login必須
   └─ AvailabilityGroup時：AvailabilityGroup必須
3. インスタンス接続
   └─ Connect-DbaInstanceでサーバーオブジェクト取得
4. CreateAnyDatabase権限処理
   └─ GrantAvailabilityGroupCreateDatabasePrivilege呼び出し
5. ログイン取得/作成
   └─ 存在しない場合はNew-DbaLoginで自動作成
6. 権限付与
   ├─ Endpoint：エンドポイントオブジェクトのGrant()メソッド
   └─ AvailabilityGroup：AGオブジェクトのGrant()メソッド
7. 結果出力
   └─ PSCustomObjectでステータス出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance or InputObject?}
    B -->|Neither| C[Stop-Function: エラー]
    B -->|OK| D{Type = Endpoint & SqlInstance & !Login?}
    D -->|Yes| E[Stop-Function: Login必須エラー]
    D -->|No| F{Type = AvailabilityGroup & !AG?}
    F -->|Yes| G[Stop-Function: AG必須エラー]
    F -->|No| H[Connect-DbaInstance]
    H --> I{CreateAnyDatabase権限?}
    I -->|Yes| J[GrantAvailabilityGroupCreateDatabasePrivilege]
    J --> K[server.Alter]
    I -->|No| L{Login指定あり?}
    K --> L
    L -->|Yes| M[Get-DbaLogin]
    M --> N{ログイン存在?}
    N -->|No| O[New-DbaLogin]
    N -->|Yes| P[InputObjectに追加]
    O --> P
    L -->|No| P
    P --> Q{Type = Endpoint?}
    Q -->|Yes| R[エンドポイント取得]
    R --> S{エンドポイント存在?}
    S -->|No| T[Stop-Function: エンドポイントなし]
    S -->|Yes| U[endpoint.Grant]
    U --> V[結果出力]
    Q -->|No| W[Get-DbaAvailabilityGroup]
    W --> X[ag.Grant]
    X --> V
    V --> Y[終了]
    C --> Y
    E --> Y
    G --> Y
    T --> Y
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パラメータ排他 | SqlInstanceとInputObjectの少なくとも一方が必須 | 常時 |
| BR-02 | Endpoint時Login必須 | Type=EndpointかつSqlInstance使用時はLogin必須 | Endpoint指定時 |
| BR-03 | AG時AG名必須 | Type=AvailabilityGroup時はAvailabilityGroup必須 | AG指定時 |
| BR-04 | ログイン自動作成 | 指定Loginが存在しない場合は自動作成 | Login指定時 |
| BR-05 | AG権限制限 | AGはAlter/Control/TakeOwnership/ViewDefinitionのみ対応 | AG権限付与時 |
| BR-06 | CreateAnyDatabase特殊処理 | 専用API（GrantAvailabilityGroupCreateDatabasePrivilege）使用 | CreateAnyDatabase時 |

### 計算ロジック

特になし（権限付与操作のため）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 権限付与 | sys.server_permissions | INSERT | エンドポイント/AG権限レコード追加 |
| ログイン作成 | sys.server_principals | INSERT | 新規ログイン作成時 |
| AG特権付与 | 内部メタデータ | UPDATE | CreateAnyDatabase特権設定 |

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

本コマンドはSMOを使用し、Grant()メソッドやGrantAvailabilityGroupCreateDatabasePrivilege()メソッドを呼び出します。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンス接続失敗 | 接続情報・ネットワーク確認 |
| - | ParameterValidation | 必須パラメータ未指定 | パラメータ指定を確認 |
| - | EndpointNotFound | DatabaseMirroringエンドポイントなし | エンドポイント作成 |
| - | PermissionNotSupported | 非対応権限指定 | 対応権限を確認 |
| - | LoginCreationFailed | ログイン作成失敗 | ログイン作成権限確認 |

### リトライ仕様

リトライ機能なし

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

SMOのAlter()メソッドによる暗黙的トランザクション管理。Grant()操作は個別にコミットされる。

## パフォーマンス要件

- 単一権限付与：1秒以内
- 複数ログイン・複数権限：ログイン数×権限数に比例

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

- sysadmin権限またはCONTROL SERVER + ALTER ANY LOGIN権限が必要
- Windows認証/SQL認証/AD認証対応
- SqlCredentialによる資格情報の安全な受け渡し
- ShouldProcess対応によるWhatIf/Confirm機能

## 備考

- CreateAnyDatabase権限はSQL Server 2016以上の自動シーディング機能に必要
- Windowsログインは自動作成されるが、SQL Serverログインは事前作成が必要

---

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

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

### 推奨読解順序

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

ObjectPermissionSetが権限を表現するデータ構造です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Grant-DbaAgPermission.ps1 | `public/Grant-DbaAgPermission.ps1` | 出力PSCustomObject構造（172-180行目、199-207行目） |

**読解のコツ**: 権限付与には2つのパス（Endpoint/AvailabilityGroup）があり、それぞれ異なる処理フローを持ちます。ObjectPermissionSetの作成方法に注目してください。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Grant-DbaAgPermission.ps1 | `public/Grant-DbaAgPermission.ps1` | processブロック（106-216行目）がメイン処理 |

**主要処理フロー**:
1. **107-120行目**: パラメータ検証
2. **122-138行目**: インスタンス接続とCreateAnyDatabase権限処理
3. **139-151行目**: ログイン取得/作成処理
4. **154-186行目**: Endpoint権限付与処理
5. **188-214行目**: AvailabilityGroup権限付与処理

#### Step 3: 依存コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaLogin.ps1 | `public/Get-DbaLogin.ps1` | ログイン取得 |
| 3-2 | New-DbaLogin.ps1 | `public/New-DbaLogin.ps1` | ログイン自動作成 |
| 3-3 | Get-DbaAvailabilityGroup.ps1 | `public/Get-DbaAvailabilityGroup.ps1` | AG情報取得 |

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

```
Grant-DbaAgPermission
    │
    ├─ Test-Bound (パラメータ検証)
    │
    ├─ Connect-DbaInstance
    │
    ├─ server.GrantAvailabilityGroupCreateDatabasePrivilege (CreateAnyDatabase時)
    │
    ├─ Get-DbaLogin
    │
    ├─ New-DbaLogin (ログイン不存在時)
    │
    ├─ [Endpoint処理]
    │      ├─ server.Endpoints.Refresh
    │      ├─ ObjectPermissionSet作成
    │      └─ endpoint.Grant
    │
    └─ [AvailabilityGroup処理]
           ├─ Get-DbaAvailabilityGroup
           ├─ ObjectPermissionSet作成
           └─ ag.Grant
```

### データフロー図

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

SqlInstance ───▶ Connect-DbaInstance ───▶ server object
                                                │
Login ─────────▶ Get-DbaLogin/New-DbaLogin ────┼───▶ login objects
                                                │
Permission ────▶ ObjectPermissionSet作成 ──────┤
                                                │
Type ──────────▶ 処理分岐 ─────────────────────┤
                     │                          │
           ┌─────────┴─────────┐                │
           ▼                   ▼                │
    [Endpoint処理]     [AG処理]                 │
           │                   │                │
           └─────────┬─────────┘                │
                     ▼                          ▼
              Grant()呼び出し ────────▶ PSCustomObject出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Grant-DbaAgPermission.ps1 | `public/Grant-DbaAgPermission.ps1` | ソース | メインコマンド実装 |
| Get-DbaLogin.ps1 | `public/Get-DbaLogin.ps1` | ソース | ログイン取得 |
| New-DbaLogin.ps1 | `public/New-DbaLogin.ps1` | ソース | ログイン作成 |
| Get-DbaAvailabilityGroup.ps1 | `public/Get-DbaAvailabilityGroup.ps1` | ソース | AG情報取得 |
| Revoke-DbaAgPermission.ps1 | `public/Revoke-DbaAgPermission.ps1` | ソース | 権限取り消しコマンド（関連） |
