# 機能設計書 123-Get-DbaExtendedProtection

## 概要

本ドキュメントは、SQL Serverのネットワーク設定から拡張保護（Extended Protection）の認証設定を取得するGet-DbaExtendedProtection機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaExtendedProtectionは、SQL ServerインスタンスのExtended Protection設定をWindowsレジストリから取得する機能である。Extended Protectionは、資格情報リレー攻撃を防止するためのWindows認証強化機能である。

**業務上の目的・背景**：Extended Protectionは、チャネルバインディングとサービスプリンシパル名の検証により認証セキュリティを強化する。DBAは、複数のSQL Serverインスタンスにわたってこの設定を監査し、セキュリティポリシーへの準拠状況を確認する必要がある。SQL Server Configuration Managerで手動確認する代わりに、本機能でプログラム的に一括確認が可能。

**機能の利用シーン**：
- セキュリティ監査でのExtended Protection設定一括確認
- コンプライアンス準拠状況のレポート作成
- 複数インスタンスの設定比較
- セキュリティ強化計画の現状把握

**主要な処理内容**：
1. 対象コンピュータ名の解決（Resolve-DbaNetworkName）
2. WMI経由でSQL Serverサービス情報取得（Invoke-ManagedComputerCommand）
3. レジストリパス（REGROOT）の特定
4. PowerShellリモーティングでレジストリ値を読み取り
5. 数値設定（0, 1, 2）をテキスト説明（Off, Allowed, Required）に変換して出力

**関連システム・外部連携**：Windowsレジストリ、WMI (Windows Management Instrumentation)、PowerShellリモーティング

**権限による制御**：対象コンピュータへの管理者権限が必要。ローカルホストの場合は管理者として実行（RunAs admin）が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コンソール/ターミナル | 主画面 | コマンド実行と結果表示 |

## 機能種別

データ取得(SELECT) / セキュリティ監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス（デフォルト: $env:COMPUTERNAME） | ValueFromPipeline |
| Credential | PSCredential | No | リモートコンピュータへのWindows資格情報 | - |
| EnableException | switch | No | 例外を直接スローするか | - |

### 入力データソース

- SQL Serverインスタンス名（コンピュータ名を自動解決）
- Windowsレジストリ（HKEY_LOCAL_MACHINE\...\MSSQLServer\SuperSocketNetLib\ExtendedProtection）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全修飾インスタンス名 |
| ExtendedProtection | string | Extended Protection設定（"数値 - テキスト"形式、例: "1 - Allowed"） |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力

## 処理フロー

### 処理シーケンス

```
1. ローカルホストの場合は管理者権限を確認
   └─ Test-ElevationRequirement

2. コンピュータ名を解決
   └─ Resolve-DbaNetworkName（失敗時はTurboモードで再試行）

3. WMI経由でSQL Serverサービス情報を取得
   └─ Invoke-ManagedComputerCommand

4. レジストリパス（REGROOT）を抽出
   └─ AdvancedPropertiesからREGROOT値を取得

5. PowerShellリモーティングでレジストリ読み取り
   └─ Invoke-Command2でスクリプトブロック実行

6. 設定値を数値とテキストの組み合わせで出力
   └─ 0=Off, 1=Allowed, 2=Required
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ローカルホスト?}
    B -->|Yes| C[管理者権限チェック]
    B -->|No| D[コンピュータ名解決]
    C --> D
    D --> E{解決成功?}
    E -->|No| F[Turboモードで再試行]
    F --> G{再解決成功?}
    G -->|No| H[Stop-Function、次へ続行]
    E -->|Yes| I[WMI経由でサービス情報取得]
    G -->|Yes| I
    I --> J{REGROOT取得成功?}
    J -->|No| K[Stop-Function、次へ続行]
    J -->|Yes| L[レジストリ値読み取り]
    L --> M[設定値変換]
    M --> N[PSCustomObject出力]
    N --> O[終了]
    H --> O
    K --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 設定値マッピング | 0=Off, 1=Allowed, 2=Required | 全ての出力 |
| BR-002 | ローカル管理者必須 | ローカルホストの場合は管理者権限が必要 | IsLocalHost判定時 |
| BR-003 | VSNAME優先 | VSNAMEが空の場合はinstance名を使用 | クラスター環境 |

### 計算ロジック

- **ExtendedProtection出力**: `"$extendedProtection - $(switch文)"`形式で数値とテキストを結合

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | SQL Serverへの直接接続なし（レジストリ読み取りのみ） |

### レジストリアクセス詳細

#### HKEY_LOCAL_MACHINE\...\MSSQLServer\SuperSocketNetLib

| 操作 | 項目（値名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| 読み取り | ExtendedProtection | レジストリパスが存在する場合 | DWORD値（0, 1, 2） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | 名前解決エラー | コンピュータ名の解決失敗 | Stop-Function後に次のインスタンスへ続行 |
| ObjectNotFound | インスタンス未検出 | VSNAMEが見つからない | Stop-Function後に次のインスタンスへ続行 |
| - | リモート接続エラー | PowerShellリモーティング失敗 | Stop-Function後に次のインスタンスへ続行 |

### リトライ仕様

- Resolve-DbaNetworkName失敗時はTurboモードで再試行

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- WMIとレジストリアクセスのため、リモートサーバーでは数秒かかる可能性
- 複数インスタンス指定時は順次処理

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

- 対象コンピュータへの管理者権限が必要
- Credentialパラメータで代替Windows資格情報を指定可能
- SQL Server認証は使用しない（Windowsレベルのアクセス）
- SupportsShouldProcess対応（-WhatIfで確認可能）

## 備考

- この機能はSQL Serverに直接接続せず、Windowsレジストリを読み取る
- SQL Server Configuration ManagerのNetwork Configuration > Protocols > Propertiesで確認できる設定と同等

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaExtendedProtection.ps1 | `public/Get-DbaExtendedProtection.ps1` | 関数の全体構造とパラメータ定義 |

**主要処理フロー**:
1. **65-71行目**: パラメータ定義（CmdletBinding、SupportsShouldProcess）
2. **76-78行目**: ローカルホストの管理者権限チェック（Test-ElevationRequirement）
3. **80-88行目**: コンピュータ名解決（Resolve-DbaNetworkName、Turboモード）
4. **90-94行目**: WMIでSQLサービス情報取得
5. **96-115行目**: REGROOT、VSNAME、InstanceName抽出
6. **124-134行目**: レジストリ読み取りスクリプトブロック
7. **136-141行目**: Invoke-Command2でリモート実行

**読解のコツ**:
- Invoke-ManagedComputerCommandは内部関数でWMIを経由してSQL Server関連情報を取得
- REGROOTはSQL Serverのインスタンス固有レジストリパスを示す
- switch文で設定値を人間が読みやすいテキストに変換（132行目）

#### Step 2: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Resolve-DbaNetworkName | `functions/Resolve-DbaNetworkName.ps1` | コンピュータ名解決ロジック |
| 2-2 | Invoke-ManagedComputerCommand | `functions/Invoke-ManagedComputerCommand.ps1` | WMI経由のサービス情報取得 |
| 2-3 | Invoke-Command2 | `functions/Invoke-Command2.ps1` | PowerShellリモーティングラッパー |

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

```
Get-DbaExtendedProtection
    │
    ├─ Test-ElevationRequirement (ローカルの場合)
    │
    ├─ Resolve-DbaNetworkName (コンピュータ名解決)
    │      └─ Turboモード (失敗時)
    │
    ├─ Invoke-ManagedComputerCommand (WMI)
    │      └─ SQL Serverサービス情報取得
    │
    └─ Invoke-Command2 (PowerShellリモーティング)
           └─ レジストリ読み取りスクリプトブロック
                 └─ Get-ItemProperty (ExtendedProtection値)
```

### データフロー図

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

SqlInstance    ───▶  Resolve-DbaNetworkName    ───▶
                           │
                     Invoke-ManagedComputerCommand ───▶
                           │
                     REGROOT抽出              ───▶
                           │
                     Invoke-Command2           ───▶  レジストリ値取得
                           │
                     設定値変換               ───▶  PSCustomObject
                           │                       (ComputerName,
                                                    InstanceName,
                                                    SqlInstance,
                                                    ExtendedProtection)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaExtendedProtection.ps1 | `public/Get-DbaExtendedProtection.ps1` | ソース | メイン関数定義 |
| Get-DbaExtendedProtection.Tests.ps1 | `tests/Get-DbaExtendedProtection.Tests.ps1` | テスト | 単体・統合テスト |
| Resolve-DbaNetworkName.ps1 | `functions/Resolve-DbaNetworkName.ps1` | ソース | コンピュータ名解決 |
| Invoke-ManagedComputerCommand.ps1 | `functions/Invoke-ManagedComputerCommand.ps1` | ソース | WMIコマンド実行 |
| Invoke-Command2.ps1 | `functions/Invoke-Command2.ps1` | ソース | リモートコマンド実行 |
