# 機能設計書 226-Set-DbaExtendedProtection

## 概要

本ドキュメントは、SQL Serverネットワークプロトコルの拡張保護（Extended Protection for Authentication）設定を構成するdbatools PowerShellコマンドレット「Set-DbaExtendedProtection」の機能設計書である。

### 本機能の処理概要

Set-DbaExtendedProtectionは、SQL ServerのネットワークプロトコルレベルでExtended Protection設定を変更するコマンドレットである。Windowsレジストリを直接変更し、Off（無効）、Allowed（許可）、Required（必須）の3つのレベルを設定できる。これにより、認証リレー攻撃からの保護を強化できる。

**業務上の目的・背景**：Extended Protectionは、中間者攻撃（man-in-the-middle attack）を防ぐためのセキュリティ機能である。信頼できないネットワーク経由での接続時や、セキュリティ要件が厳しい環境では、この機能を有効にすることが推奨される。ただし、古いクライアントアプリケーションはExtended Protectionに対応していない場合があるため、慎重な設定が必要である。

**機能の利用シーン**：
- セキュリティ監査要件への対応
- 信頼できないネットワークからの接続保護
- コンプライアンス要件の実装
- セキュリティポリシーの一括適用

**主要な処理内容**：
1. ターゲットコンピュータの名前解決
2. SQL Server WMIサービス情報の取得
3. レジストリパスの特定
4. PowerShellリモーティングによるレジストリ値の設定
5. 設定結果の出力

**関連システム・外部連携**：Windowsレジストリ、WMI、PowerShellリモーティングを使用。SQL Server Configuration Managerと同等の設定を行う。

**権限による制御**：ターゲットサーバーへの管理者権限が必要。ローカル実行時はRunAs管理者が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールからの直接実行 |

## 機能種別

サーバー設定変更（レジストリ更新）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | デフォルト: $env:COMPUTERNAME |
| Credential | PSCredential | No | Windowsリモート認証用資格情報 | - |
| Value | object | No | 設定値（0/Off, 1/Allowed, 2/Required） | ValidateSet |
| EnableException | switch | No | 例外有効化フラグ | - |

### 入力データソース

- PowerShellコマンドライン入力
- パイプライン入力（SqlInstanceプロパティ経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | レジストリ変更を行ったコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| ExtendedProtection | string | 設定値と説明（例: "2 - Required"） |

### 出力先

PowerShellパイプライン（標準出力）

## 処理フロー

### 処理シーケンス

```
1. Value変換
   └─ 文字列（Off/Allowed/Required）を整数（0/1/2）に変換

2. 各SqlInstanceに対するループ
   └─ ローカルホストの場合は昇格権限チェック

3. コンピュータ名の解決
   └─ Resolve-DbaNetworkName使用

4. WMIによるSQL Serverサービス情報取得
   └─ Invoke-ManagedComputerCommand使用
   └─ REGROOTからレジストリパスを取得

5. レジストリ設定
   └─ Invoke-Command2でリモート実行
   └─ Set-ItemPropertyでExtendedProtection値を設定

6. 結果の出力
   └─ 設定後の値を取得して出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Value変換]
    B --> C[各SqlInstanceに対してループ]
    C --> D{ローカルホスト?}
    D -->|Yes| E[昇格権限チェック]
    D -->|No| F[コンピュータ名解決]
    E --> F
    F --> G{解決成功?}
    G -->|No| H[エラー出力・継続]
    G -->|Yes| I[WMI情報取得]
    I --> J{取得成功?}
    J -->|No| K[エラー出力・継続]
    J -->|Yes| L[レジストリパス特定]
    L --> M{ShouldProcess確認}
    M -->|No| N[スキップ]
    M -->|Yes| O[Invoke-Command2実行]
    O --> P{成功?}
    P -->|No| Q[エラー出力・継続]
    P -->|Yes| R[結果出力]
    R --> S{次のインスタンス?}
    N --> S
    H --> S
    K --> S
    Q --> S
    S -->|Yes| C
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 管理者権限必須 | ローカル実行時はRunAs管理者が必要 | IsLocalHost = true |
| BR-002 | 即時反映 | 設定変更は新規接続から即座に有効 | 常時 |
| BR-003 | 再起動不要 | SQL Serverサービスの再起動は不要 | 常時 |
| BR-004 | Windows Server専用 | SQL Server on WindowsのみサポートSQL Server on Linuxは非対応 | 常時 |

### 計算ロジック

Value変換テーブル：
- "Off" → 0
- "Allowed" → 1
- "Required" → 2

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-----|---------|------|
| レジストリ更新 | HKLM\...\SuperSocketNetLib\ExtendedProtection | UPDATE | Set-ItemPropertyによる値変更 |

### レジストリ詳細

| レジストリパス | 値名 | データ型 | 値 |
|--------------|------|---------|-----|
| HKEY_LOCAL_MACHINE\{REGROOT}\MSSQLServer\SuperSocketNetLib | ExtendedProtection | REG_DWORD | 0, 1, or 2 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ElevationRequired | ローカル実行時に管理者権限なし | 管理者として実行 |
| - | ResolveFailed | コンピュータ名解決失敗 | ネットワーク接続を確認 |
| - | WMIAccessFailed | WMI接続失敗 | 資格情報とWMIサービスを確認 |
| - | RemotingFailed | PowerShellリモーティング失敗 | WinRMサービスを確認 |
| - | RegistryAccessFailed | レジストリアクセス失敗 | 権限を確認 |

### リトライ仕様

リトライ処理は実装されていない。名前解決にはTurboモードでのフォールバックがある。

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

レジストリ操作はトランザクションサポートなし。Set-ItemPropertyは即座に反映される。

## パフォーマンス要件

特に定義されていない。レジストリ変更は軽量な操作である。

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

- ターゲットサーバーへの管理者権限が必要
- PowerShellリモーティング（WinRM）が有効である必要がある
- Requiredに設定すると古いクライアントが接続できなくなる可能性
- 設定変更は即座に有効になるため注意が必要

## 備考

- SQL Server Configuration Managerのプロパティ設定と同等の機能
- この設定はSQL Serverインスタンスではなく、Windowsサーバーへのアクセスが必要
- WhatIfとConfirmパラメータをサポート
- デフォルト値は"Off"

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造とValue変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaExtendedProtection.ps1 | `public/Set-DbaExtendedProtection.ps1` | 出力オブジェクトの構造（46-56行目の.OUTPUTSセクション） |
| 1-2 | Set-DbaExtendedProtection.ps1 | `public/Set-DbaExtendedProtection.ps1` | beginブロックのValue変換（93-96行目） |

**読解のコツ**: ValidateSetで文字列と数値の両方を許可している点に注目（88行目）。

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

processブロック内のメイン処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaExtendedProtection.ps1 | `public/Set-DbaExtendedProtection.ps1` | processブロック（98-172行目） |

**主要処理フロー**:
1. **100-104行目**: ローカルホスト判定と昇格権限チェック
2. **106-114行目**: Resolve-DbaNetworkNameでコンピュータ名解決
3. **116-120行目**: Invoke-ManagedComputerCommandでWMI情報取得
4. **122-141行目**: REGROOTとVSNAMEの取得
5. **151-162行目**: ScriptBlockによるレジストリ設定
6. **163-170行目**: Invoke-Command2でリモート実行

#### Step 3: レジストリ設定ロジックを理解する

ScriptBlockの内容を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaExtendedProtection.ps1 | `public/Set-DbaExtendedProtection.ps1` | ScriptBlock（151-162行目） |

**主要処理フロー**:
- **152行目**: レジストリパス構築
- **153行目**: Set-ItemPropertyで値設定
- **154行目**: Get-ItemPropertyで設定後の値取得
- **156-161行目**: 結果PSCustomObject構築

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

```
Set-DbaExtendedProtection
    │
    ├─ Test-ElevationRequirement (ローカル時)
    │
    ├─ Resolve-DbaNetworkName
    │      └─ コンピュータ名解決
    │
    ├─ Invoke-ManagedComputerCommand
    │      └─ WMIによるSQL Server情報取得
    │      └─ $wmi.Services
    │
    └─ Invoke-Command2
           └─ PowerShellリモーティング実行
           └─ Set-ItemProperty (レジストリ更新)
           └─ Get-ItemProperty (設定値取得)
```

### データフロー図

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

SqlInstance ─────────┐
Credential ──────────┤
Value ───────────────┼──▶ Value変換 (Off/Allowed/Required → 0/1/2)
                     │         │
                     │         ▼
                     │    Test-ElevationRequirement
                     │         │
                     │         ▼
                     │    Resolve-DbaNetworkName
                     │         │
                     │         ▼
                     │    Invoke-ManagedComputerCommand
                     │    (WMI: REGROOT, VSNAME取得)
                     │         │
                     │         ▼
                     │    Invoke-Command2
                     │    (Set-ItemProperty)
                     │         │
                     │         ▼
                     └──▶ PSCustomObject
                          (ComputerName, InstanceName,
                           SqlInstance, ExtendedProtection)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaExtendedProtection.ps1 | `public/Set-DbaExtendedProtection.ps1` | ソース | メインコマンドレット実装 |
| Get-DbaExtendedProtection.ps1 | `public/Get-DbaExtendedProtection.ps1` | ソース | Extended Protection設定取得（関連機能） |
| Resolve-DbaNetworkName.ps1 | `public/Resolve-DbaNetworkName.ps1` | ソース | コンピュータ名解決 |
| Invoke-ManagedComputerCommand.ps1 | `private/functions/Invoke-ManagedComputerCommand.ps1` | ソース | WMIコマンド実行 |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | PowerShellリモーティング |
