# 機能設計書 594-Enable-DbaForceNetworkEncryption

## 概要

本ドキュメントは、SQL ServerのForce Network Encryption設定を有効化するPowerShellコマンドレット `Enable-DbaForceNetworkEncryption` の機能設計書である。

### 本機能の処理概要

本機能は、SQL Server Configuration Managerで設定されるForce Network Encryption（強制ネットワーク暗号化）設定をWindowsレジストリを直接変更することで有効化するコマンドレットである。

**業務上の目的・背景**：セキュリティポリシーやコンプライアンス要件により、SQL Serverへのすべてのクライアント接続を暗号化する必要がある場合が増加している。Force Encryptionを有効化すると、クライアント側の暗号化設定に関係なく、すべての接続がTLS暗号化される。通常はSQL Server Configuration Managerを使用して手動設定するが、本コマンドを使用することで複数サーバーへの一括設定やインフラストラクチャ自動化スクリプトへの組み込みが可能になる。

**機能の利用シーン**：
- 本番環境のセキュリティ強化（ネットワーク盗聴対策）
- コンプライアンス要件への対応（PCI-DSS、HIPAA等）
- セキュリティ監査前の設定標準化
- インフラストラクチャの自動プロビジョニング

**主要な処理内容**：
1. 管理者権限の確認（Test-ElevationRequirement）
2. Resolve-DbaNetworkNameでコンピュータ名を解決
3. Invoke-ManagedComputerCommandでSQL Server WMIサービス情報を取得
4. レジストリパス（REGROOT）とインスタンス情報を抽出
5. Invoke-Command2でリモートレジストリのForceEncryption値をtrueに設定
6. 設定変更結果を返却
7. SQL Serverサービス再起動が必要である旨の警告メッセージを出力

**関連システム・外部連携**：WindowsレジストリとPowerShellリモーティングを使用。SQL Server WMI Providerを介してSQL Serverサービス情報を取得する。

**権限による制御**：対象サーバーのローカル管理者権限が必要。PowerShellリモーティング（WinRM）が有効である必要がある。SQL Serverの権限は不要（レジストリ操作のため）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Configuration Manager | 参照画面 | SQL Server Network Configuration でForce Encryption設定を確認 |
| - | PowerShellコンソール | 主画面 | コマンドの実行および結果表示 |

## 機能種別

設定変更処理 / レジストリ操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス（デフォルト: localhost） | 有効なSQL Serverインスタンス名 |
| Credential | PSCredential | No | リモートコンピュータ接続用のWindows資格情報 | 有効なPSCredentialオブジェクト |
| EnableException | switch | No | 例外を直接スローするフラグ | - |
| WhatIf | switch | No | 実際の変更を行わずに動作を表示 | - |
| Confirm | switch | No | 変更前に確認プロンプトを表示 | - |

### 入力データソース

- SqlInstanceパラメータ：ユーザー指定のSQL Serverインスタンス名（デフォルトは環境変数$env:COMPUTERNAME）
- Credential：Windows認証用の資格情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverが稼働するコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名（例: MSSQLSERVER, SQL2008R2SP2） |
| SqlInstance | string | 完全なSQL Serverインスタンス識別子 |
| ForceEncryption | bool | Force Encryption設定の現在状態（処理後はtrue） |
| CertificateThumbprint | string | SQL Serverインスタンスに割り当てられた証明書のサムプリント（未設定の場合は空） |

### 出力先

- PowerShellパイプライン：PSCustomObjectとして出力

## 処理フロー

### 処理シーケンス

```
1. 管理者権限チェック
   └─ Test-ElevationRequirement で昇格確認
2. ホスト名解決
   └─ Resolve-DbaNetworkName でFQDNを取得
   └─ 失敗時は-Turboモードでリトライ
3. SQL Server WMI情報取得
   └─ Invoke-ManagedComputerCommand でサービス情報取得
   └─ DisplayNameで対象インスタンスをフィルタ
4. レジストリパス抽出
   └─ AdvancedPropertiesからREGROOT, VSNAME取得
   └─ 空の場合は代替パース処理
5. レジストリ変更実行
   └─ ShouldProcess確認
   └─ Invoke-Command2 でリモート実行
   └─ ForceEncryption = $true に設定
6. 結果返却
   └─ 新しい設定値と証明書情報を出力
7. 再起動警告メッセージ出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Test-ElevationRequirement]
    B --> C{管理者権限?}
    C -->|No| D[警告出力して継続]
    C -->|Yes| E[Resolve-DbaNetworkName]
    D --> E
    E --> F{解決成功?}
    F -->|No| G[Turboモードでリトライ]
    G --> H{解決成功?}
    H -->|No| I[Stop-Function: 解決失敗]
    F -->|Yes| J[Invoke-ManagedComputerCommand]
    H -->|Yes| J
    J --> K{WMI取得成功?}
    K -->|No| L[Stop-Function: アクセス失敗]
    K -->|Yes| M[REGROOT/VSNAME抽出]
    M --> N{REGROOTが空?}
    N -->|Yes| O[代替パース処理]
    N -->|No| P[ShouldProcess確認]
    O --> Q{パース成功?}
    Q -->|No| R[Stop-Function: インスタンス未検出]
    Q -->|Yes| P
    P --> S{実行確認?}
    S -->|No| T[次のインスタンス]
    S -->|Yes| U[Invoke-Command2でレジストリ変更]
    U --> V{変更成功?}
    V -->|No| W[Stop-Function: リモート接続失敗]
    V -->|Yes| X[結果出力]
    X --> Y[再起動警告メッセージ]
    Y --> T
    T --> Z{次のインスタンスあり?}
    Z -->|Yes| B
    Z -->|No| AA[終了]
    I --> T
    L --> T
    R --> T
    W --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 管理者権限要求 | 対象サーバーのローカル管理者権限が必要 | 常時 |
| BR-002 | サービス再起動必須 | 設定変更後はSQL Serverサービスの再起動が必要 | 設定変更成功時 |
| BR-003 | デフォルトインスタンス | SqlInstance未指定時はlocalhostをデフォルト使用 | パラメータ未指定時 |
| BR-004 | 低影響設定 | ConfirmImpact="Low"でデフォルト確認なし | インタラクティブ実行時 |
| BR-005 | 証明書推奨 | Force Encryption有効化時は有効な証明書の設定を推奨 | セキュリティベストプラクティス |

### 計算ロジック

該当なし

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

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

本機能はWindowsレジストリを操作するため、SQL Serverデータベースへの直接的な影響はない。

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| レジストリ変更 | HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\{REGROOT}\MSSQLServer\SuperSocketNetLib | UPDATE | ForceEncryptionキーをtrueに設定 |

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

該当なし（レジストリ操作のため）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | Stop-Function | ホスト名解決に失敗 | DNS設定を確認、正しいコンピュータ名を指定 |
| ObjectNotFound | Stop-Function | 指定インスタンスが見つからない | インスタンス名を確認 |
| - | Stop-Function | WMIアクセス失敗 | WMI設定とファイアウォールを確認 |
| - | Stop-Function | PowerShellリモーティング失敗 | WinRM設定を確認 |

### リトライ仕様

- ホスト名解決失敗時は-Turboモードで1回リトライ

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

レジストリ操作のためトランザクションは適用されない。設定変更は即時反映されるが、SQL Serverサービスへの適用にはサービス再起動が必要。

## パフォーマンス要件

- PowerShellリモーティングのレイテンシに依存
- 通常は数秒以内に完了

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

- ローカル管理者権限が必要（レジストリ変更のため）
- PowerShellリモーティング（WinRM）が有効である必要がある
- Force Encryptionを有効化すると、すべてのクライアント接続が暗号化される
- 有効な証明書が設定されていない場合、SQL Serverは自己署名証明書を使用（警告が発生する場合あり）
- 証明書が期限切れの場合、接続に問題が発生する可能性がある
- 変更後はSQL Serverサービスの再起動が必要（メッセージで警告）

## 備考

- 設定変更後はSQL Serverサービスの再起動が必要（コマンドは再起動を行わない）
- SQL Server接続権限ではなくWindows管理者権限が必要
- 証明書のサムプリントも出力に含まれるため、現在の暗号化設定を確認可能
- 証明書が設定されていない場合でもForce Encryptionは有効化可能（自己署名証明書使用）

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造と、レジストリパスの構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Enable-DbaForceNetworkEncryption.ps1 | `public/Enable-DbaForceNetworkEncryption.ps1` | 140-146行目のPSCustomObject定義 |

**読解のコツ**: レジストリパスは `HKLM\{REGROOT}\MSSQLServer\SuperSocketNetLib` の形式で、REGROOTはSQL Serverインスタンスごとに異なる。Disable-DbaForceNetworkEncryptionと同じ構造を使用。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Enable-DbaForceNetworkEncryption.ps1 | `public/Enable-DbaForceNetworkEncryption.ps1` | 関数定義全体の構造 |

**主要処理フロー**:
1. **70-77行目**: パラメータ定義（CmdletBinding, SupportsShouldProcess）
2. **78-80行目**: process ブロック開始、インスタンスループ
3. **82行目**: 管理者権限チェック（Test-ElevationRequirement）
4. **84-90行目**: ホスト名解決処理

#### Step 3: WMI情報取得とレジストリパス抽出を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Enable-DbaForceNetworkEncryption.ps1 | `public/Enable-DbaForceNetworkEncryption.ps1` | WMI情報取得とREGROOT抽出 |

**主要処理フロー**:
- **96-100行目**: Invoke-ManagedComputerCommandでWMIサービス情報取得
- **102-103行目**: AdvancedPropertiesからREGROOT, VSNAME抽出
- **104-110行目**: DisplayNameからインスタンス名を抽出
- **113-123行目**: REGROOT空の場合の代替パース処理

#### Step 4: レジストリ変更処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Enable-DbaForceNetworkEncryption.ps1 | `public/Enable-DbaForceNetworkEncryption.ps1` | リモートレジストリ変更 |

**主要処理フロー**:
- **132-147行目**: ScriptBlockでレジストリ変更処理を定義
- **133行目**: レジストリパス構築
- **134行目**: 現在の証明書サムプリント取得
- **137行目**: ForceEncryption = $true に設定
- **138行目**: 変更後の値を確認
- **149-156行目**: ShouldProcess確認とInvoke-Command2実行
- **151行目**: Select-ObjectでPSComputerName等を除外
- **152行目**: 成功時の警告メッセージ（再起動必要）

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

```
Enable-DbaForceNetworkEncryption
    │
    ├─ Test-ElevationRequirement
    │      └─ 管理者権限チェック
    │
    ├─ Resolve-DbaNetworkName
    │      └─ FQDN解決
    │      └─ (失敗時) -Turbo モードでリトライ
    │
    ├─ Invoke-ManagedComputerCommand
    │      └─ SQL Server WMI Provider経由でサービス情報取得
    │
    └─ Invoke-Command2
           └─ PowerShellリモーティングでレジストリ変更
           └─ Set-ItemProperty -Name ForceEncryption -Value $true
```

### データフロー図

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

SqlInstance ───────────▶ Resolve-DbaNetworkName ───▶ FullComputerName
                                │
                                ▼
                        Invoke-ManagedComputerCommand
                                │
                                ▼
                        WMI Services情報 ───▶ REGROOT, VSNAME
                                │
                                ▼
                        Invoke-Command2
                                │
                                ▼
                        Registry: ForceEncryption = true
                                │
                                ▼
                        PSCustomObject ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Enable-DbaForceNetworkEncryption.ps1 | `public/Enable-DbaForceNetworkEncryption.ps1` | ソース | メイン機能実装 |
| Disable-DbaForceNetworkEncryption.ps1 | `public/Disable-DbaForceNetworkEncryption.ps1` | ソース | 対となる無効化機能 |
| Get-DbaForceNetworkEncryption.ps1 | `public/Get-DbaForceNetworkEncryption.ps1` | ソース | 設定取得機能 |
| Enable-DbaForceNetworkEncryption.Tests.ps1 | `tests/Enable-DbaForceNetworkEncryption.Tests.ps1` | テスト | 単体・統合テスト |
