# 画面設計書：AG権限管理

## 1. 基本情報

| 項目 | 内容 |
|------|------|
| 画面ID | 6 |
| 画面名 | AG権限管理 |
| 画面種別 | CLI（コマンドラインインターフェース） |
| カテゴリ | AvailabilityGroup |
| 関連ファイル | public/Grant-DbaAgPermission.ps1, public/Revoke-DbaAgPermission.ps1 |

## 2. 概要・目的

AG権限管理は、SQL Server AlwaysOn可用性グループおよびデータベースミラーリングエンドポイントに対する権限を管理するPowerShellコマンド群です。

本コマンド群により以下の操作が可能です：
- 可用性グループに対する権限付与・取り消し（Alter、Control、TakeOwnership、ViewDefinition）
- データベースミラーリングエンドポイントに対する権限付与・取り消し（Connect等）
- 自動シーディングに必要なCreateAnyDatabase権限の管理

## 3. 主要機能

### 3.1 Grant-DbaAgPermission

可用性グループまたはエンドポイントに権限を付与します。

**入力パラメータ：**

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | - | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | いいえ | - | 代替認証情報 |
| Login | string[] | 条件付き | - | 権限を付与するログイン名 |
| AvailabilityGroup | string[] | 条件付き | - | 対象可用性グループ名 |
| Type | string[] | はい | - | 権限タイプ（Endpoint/AvailabilityGroup） |
| Permission | string[] | いいえ | Connect | 付与する権限 |
| InputObject | Login[] | 条件付き | - | パイプライン入力用ログインオブジェクト |
| EnableException | switch | いいえ | false | 例外を有効化 |

**対応権限：**

| タイプ | 対応権限 |
|--------|---------|
| AvailabilityGroup | Alter, Control, TakeOwnership, ViewDefinition, CreateAnyDatabase |
| Endpoint | Connect, Alter, Control, CreateSequence, Delete, Execute, Impersonate, Insert, Receive, References, Select, Send, TakeOwnership, Update, ViewChangeTracking, ViewDefinition |

**出力プロパティ：**

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | SQL Serverインスタンス名 |
| Name | string | ログイン名 |
| Permission | string | 付与された権限 |
| Type | string | 操作タイプ（Grant） |
| Status | string | 操作ステータス（Success） |

### 3.2 Revoke-DbaAgPermission

可用性グループまたはエンドポイントから権限を取り消します。

**入力パラメータ：**

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | - | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | いいえ | - | 代替認証情報 |
| Login | string[] | 条件付き | - | 権限を取り消すログイン名 |
| AvailabilityGroup | string[] | 条件付き | - | 対象可用性グループ名 |
| Type | string[] | はい | - | 権限タイプ（Endpoint/AvailabilityGroup） |
| Permission | string[] | いいえ | Connect | 取り消す権限 |
| InputObject | Login[] | 条件付き | - | パイプライン入力用ログインオブジェクト |
| EnableException | switch | いいえ | false | 例外を有効化 |

**出力プロパティ：**

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | SQL Serverインスタンス名 |
| Name | string | ログイン名 |
| Permission | string | 取り消された権限 |
| Type | string | 操作タイプ（Revoke） |
| Status | string | 操作ステータス（Success） |

## 4. 処理フロー

### 4.1 Grant-DbaAgPermission

```
[開始]
   ↓
[パラメータ検証]
   ├── SqlInstanceまたはInputObjectの必須チェック
   ├── Type=Endpoint時はLogin必須
   ├── Type=AvailabilityGroup時はAvailabilityGroup必須
   ↓
[インスタンス接続]
   ├── Connect-DbaInstanceで接続
   ↓
[CreateAnyDatabase処理]（Permission含む場合）
   ├── GrantAvailabilityGroupCreateDatabasePrivilege()実行
   ├── server.Alter()
   ↓
[ログイン処理]
   ├── Get-DbaLoginで既存ログイン取得
   ├── 存在しない場合はNew-DbaLoginで作成
   ↓
[権限付与]
   ├── [Endpointの場合]
   │     ├── DatabaseMirroringエンドポイント取得
   │     ├── ObjectPermissionSet作成
   │     └── endpoint.Grant()実行
   │
   └── [AvailabilityGroupの場合]
         ├── Get-DbaAvailabilityGroupでAG取得
         ├── ObjectPermissionSet作成
         └── ag.Grant()実行
   ↓
[結果出力]
   ↓
[終了]
```

### 4.2 Revoke-DbaAgPermission

```
[開始]
   ↓
[パラメータ検証]
   ├── SqlInstanceまたはInputObjectの必須チェック
   ├── SqlInstance使用時はLogin必須
   ├── Type=AvailabilityGroup時はAvailabilityGroup必須
   ↓
[インスタンス接続]
   ├── Connect-DbaInstanceで接続
   ↓
[CreateAnyDatabase処理]（Permission含む場合）
   ├── ALTER AVAILABILITY GROUP GRANT CREATE ANY DATABASE実行
   ↓
[ログイン処理]
   ├── Get-DbaLoginで既存ログイン取得
   ├── 存在しない場合はNew-DbaLoginで作成
   ↓
[権限取り消し]
   ├── [Endpointの場合]
   │     ├── DatabaseMirroringエンドポイント取得
   │     ├── ObjectPermissionSet作成
   │     └── endpoint.Revoke()実行
   │
   └── [AvailabilityGroupの場合]
         ├── Get-DbaAvailabilityGroupでAG取得
         ├── ObjectPermissionSet作成
         └── ag.Revoke()実行
   ↓
[結果出力]
   ↓
[終了]
```

## 5. SMOメソッドマッピング

| 操作 | SMOメソッド | 説明 |
|------|------------|------|
| CreateAnyDatabase付与 | Server.GrantAvailabilityGroupCreateDatabasePrivilege() | AG自動シーディング権限 |
| エンドポイント権限付与 | Endpoint.Grant() | エンドポイントへの権限付与 |
| エンドポイント権限取り消し | Endpoint.Revoke() | エンドポイントからの権限取り消し |
| AG権限付与 | AvailabilityGroup.Grant() | AGへの権限付与 |
| AG権限取り消し | AvailabilityGroup.Revoke() | AGからの権限取り消し |

## 6. バリデーションルール

### 6.1 パラメータ検証

| 条件 | エラーメッセージ | コマンド |
|------|----------------|---------|
| SqlInstanceもInputObjectも未指定 | "You must supply either -SqlInstance or an Input Object" | 両方 |
| Type=EndpointでLogin未指定 | "You must specify one or more logins when using the Endpoint type together with the SqlInstance parameter." | Grant |
| Type=AvailabilityGroupでAG未指定 | "You must specify at least one availability group when using the AvailabilityGroup type." | 両方 |

### 6.2 権限制限

| タイプ | サポート権限 | 非サポート権限エラー |
|--------|------------|---------------------|
| AvailabilityGroup | Alter, Control, TakeOwnership, ViewDefinition | "$perm not supported by availability groups" |
| Endpoint | Connect, Alter, Control等 | "$perm not supported by endpoints"（CreateAnyDatabase） |

## 7. エラーハンドリング

| エラー条件 | 処理 |
|-----------|------|
| パラメータ不足 | Stop-Functionで処理中断 |
| 接続エラー | Stop-Functionでエラー記録、次のインスタンスへ |
| ログイン作成失敗 | Stop-Functionで処理中断 |
| 権限付与/取り消し失敗 | Stop-Functionでエラー記録、次へ継続 |
| エンドポイント未存在 | Stop-Functionでエラー記録、次へ継続 |

## 8. 特殊処理

### 8.1 Windowsログイン自動作成

指定されたログインが存在しない場合、Windowsログインとして自動的に作成されます（Grant-DbaAgPermission Lines 141-150）。

```powershell
if ($account -notin $InputObject.Name) {
    $InputObject += New-DbaLogin -SqlInstance $server -Login $account -EnableException
}
```

### 8.2 CreateAnyDatabase権限

CreateAnyDatabase権限は特別な処理が必要で、SMOの`GrantAvailabilityGroupCreateDatabasePrivilege()`メソッドを使用します（Lines 128-137）。

```powershell
if ($Permission -contains "CreateAnyDatabase") {
    $server.GrantAvailabilityGroupCreateDatabasePrivilege($ag)
    $server.Alter()
}
```

## 9. 使用例

### 9.1 CreateAnyDatabase権限付与

```powershell
Grant-DbaAgPermission -SqlInstance sql2017a -Type AvailabilityGroup -AvailabilityGroup SharePoint -Permission CreateAnyDatabase
```

### 9.2 複数AGへのCreateAnyDatabase権限付与（確認あり）

```powershell
Grant-DbaAgPermission -SqlInstance sql2017a -Type AvailabilityGroup -AvailabilityGroup ag1, ag2 -Permission CreateAnyDatabase -Confirm
```

### 9.3 エンドポイントへのConnect権限付与

```powershell
Get-DbaLogin -SqlInstance sql2017a | Out-GridView -Passthru | Grant-DbaAgPermission -Type EndPoint
```

### 9.4 権限取り消し

```powershell
Revoke-DbaAgPermission -SqlInstance sql2017a -Type AvailabilityGroup -AvailabilityGroup SharePoint -Login ad\spservice -Permission CreateAnyDatabase
```

### 9.5 エンドポイント権限取り消し

```powershell
Get-DbaLogin -SqlInstance sql2017a | Out-GridView -Passthru | Revoke-DbaAgPermission -Type EndPoint
```

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

### 10.1 理解の順序

1. **Grant-DbaAgPermission.ps1** - 権限付与の基本構造を理解
2. **Revoke-DbaAgPermission.ps1** - 権限取り消しの類似パターンを確認

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

```
Grant-DbaAgPermission
├── Test-Bound (Line 107)
├── Stop-Function (Lines 108, 113, 118, 134, 146, 161, 167, 182, 193, 209)
├── Connect-DbaInstance (Line 124)
├── GrantAvailabilityGroupCreateDatabasePrivilege() (Line 131)
├── server.Alter() (Line 132)
├── Get-DbaLogin (Line 140)
├── New-DbaLogin (Line 144)
├── server.Endpoints.Refresh() (Line 157)
├── New-Object ObjectPermissionSet (Lines 170, 197)
├── endpoint.Grant() (Line 171)
├── Get-DbaAvailabilityGroup (Line 189)
└── ag.Grant() (Line 198)

Revoke-DbaAgPermission
├── Test-Bound (Line 112)
├── Stop-Function (Lines 113, 118, 123, 139, 150, 165, 171, 186, 197, 213)
├── Connect-DbaInstance (Line 130)
├── server.Query() (Line 137)
├── Get-DbaLogin (Line 144)
├── New-DbaLogin (Line 148)
├── server.Endpoints.Refresh() (Line 161)
├── New-Object ObjectPermissionSet (Lines 174, 201)
├── endpoint.Revoke() (Line 175)
├── Get-DbaAvailabilityGroup (Line 193)
└── ag.Revoke() (Line 202)
```

### 10.3 データフロー図

```
[ユーザー入力]
     │
     ├─ SqlInstance + Login/AvailabilityGroup
     │        │
     │        └── Connect-DbaInstance ──────────┐
     │                                           │
     └─ InputObject (パイプライン) ──────────────┤
                                                 │
                                                 ↓
                           [ログインオブジェクト / AGオブジェクト]
                                                 │
              ┌──────────────────────────────────┼──────────────────────────────────┐
              │                                  │                                  │
    [Type=Endpoint]                  [Type=AvailabilityGroup]              [CreateAnyDatabase]
              │                                  │                                  │
   Endpoints取得                    Get-DbaAvailabilityGroup     GrantAvailabilityGroupCreateDatabasePrivilege()
              │                                  │                                  │
   endpoint.Grant()                        ag.Grant()                        server.Alter()
   endpoint.Revoke()                       ag.Revoke()                              │
              │                                  │                                  │
              └──────────────────────────────────┼──────────────────────────────────┘
                                                 │
                                          [結果出力]
                                    ComputerName, InstanceName,
                                    SqlInstance, Name, Permission,
                                    Type, Status
```

### 10.4 関連ファイル一覧

| ファイルパス | 役割 | 行数 |
|-------------|------|------|
| public/Grant-DbaAgPermission.ps1 | 権限付与 | 217 |
| public/Revoke-DbaAgPermission.ps1 | 権限取り消し | 221 |
| public/Get-DbaLogin.ps1 | ログイン取得（依存） | - |
| public/New-DbaLogin.ps1 | ログイン作成（依存） | - |
| public/Get-DbaAvailabilityGroup.ps1 | AG取得（依存） | - |

### 10.5 重要コードポイント

#### ObjectPermissionSet作成（Grant-DbaAgPermission.ps1: Lines 170, 197）
```powershell
$bigperms = New-Object Microsoft.SqlServer.Management.Smo.ObjectPermissionSet([Microsoft.SqlServer.Management.Smo.ObjectPermission]::$perm)
```

#### AG権限付与（Grant-DbaAgPermission.ps1: Line 198）
```powershell
$ag.Grant($bigperms, $account.Name)
```

#### 権限検証（Grant-DbaAgPermission.ps1: Lines 192-194）
```powershell
if ($perm -notin 'Alter', 'Control', 'TakeOwnership', 'ViewDefinition') {
    Stop-Function -Message "$perm not supported by availability groups" -Continue
}
```

## 11. 権限要件

| 操作 | 必要な権限 |
|------|----------|
| Grant-DbaAgPermission | CONTROL権限またはsysadmin固定サーバーロール |
| Revoke-DbaAgPermission | CONTROL権限またはsysadmin固定サーバーロール |

## 12. 関連コマンド

- Get-DbaLogin - ログイン取得
- New-DbaLogin - ログイン作成
- Get-DbaAvailabilityGroup - 可用性グループ取得
- Get-DbaEndpoint - エンドポイント取得
- Add-DbaAgReplica - レプリカ追加（権限付与を自動実行）
- Add-DbaAgDatabase - DBをAGに追加（権限付与が必要な場合あり）
