# 機能設計書 616-Set-DbaNetworkCertificate

## 概要

本ドキュメントは、SQL Serverインスタンスのネットワーク証明書を設定するdbatools PowerShell関数 `Set-DbaNetworkCertificate` の機能設計書である。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverは、クライアント接続を保護するためにSSL/TLS証明書を使用してネットワーク通信を暗号化できる。本機能は、SQL Server Configuration Managerで行う証明書設定操作をPowerShellから実行可能にする。証明書の設定に加えて、サービスアカウントに証明書の秘密鍵への読み取り権限を自動的に付与する。これにより、SSL暗号化の構成作業を自動化し、複数インスタンスへの一括設定が可能になる。

**機能の利用シーン**：
- 新規証明書のSQL Serverへの適用
- Let's Encryptなどの自動更新証明書のローテーション
- Active Directory CAが発行した証明書の設定
- 複数インスタンスへのSSL設定の一括適用

**主要な処理内容**：
1. 証明書オブジェクトまたはサムプリントからサムプリントを取得
2. ターゲットコンピュータのSQL Serverサービス情報を取得
3. レジストリからSuperSocketNetLib設定を特定
4. 証明書の秘密鍵へのサービスアカウント読み取り権限を付与
5. レジストリに証明書サムプリントを設定
6. 必要に応じてSQL Serverサービスを再起動

**関連システム・外部連携**：
- WMI（Windows Management Instrumentation）を使用してSQL Serverサービス情報を取得
- PowerShellリモーティングを使用してリモートコンピュータのレジストリおよびファイルシステムを操作
- Windowsレジストリ（HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server）
- 証明書ストア（LocalMachine）

**権限による制御**：ターゲットコンピュータのレジストリ、WMIサービス、および証明書秘密鍵への管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 131 | ネットワーク証明書 | 主機能 | ネットワーク証明書の設定 |

## 機能種別

システム設定変更 - レジストリ操作、ファイルシステム権限操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス（デフォルト: localhost） | 有効なインスタンス名 |
| Credential | PSCredential | No | リモートコンピュータへのアクセス用資格情報 | 有効な資格情報オブジェクト |
| Certificate | X509Certificate2 | 条件付き | 設定する証明書オブジェクト（パイプライン入力可） | 有効な証明書オブジェクト |
| Thumbprint | string | 条件付き | 設定する証明書のサムプリント | 有効なサムプリント文字列 |
| RestartService | switch | No | 設定後にSQL Serverサービスを自動再起動 | - |
| EnableException | switch | No | 例外処理の有効化 | - |
| WhatIf | switch | No | 実行せずに処理内容を表示 | - |
| Confirm | switch | No | 実行前に確認プロンプトを表示 | - |

### 入力データソース

- SqlInstanceパラメータ: コマンドライン引数（デフォルトは$env:COMPUTERNAME）
- Certificate: New-DbaComputerCertificateなどからのパイプライン入力
- Thumbprint: 事前に取得済みの証明書サムプリント
- Credential: Get-Credentialコマンドレットまたは事前定義の資格情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | 証明書が設定されたコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名（VSNAME） |
| ServiceAccount | string | SQL Serverサービスアカウント |
| CertificateThumbprint | string | 設定された証明書のサムプリント（小文字） |
| Notes | string | 実行されたアクション（権限付与、旧証明書の置換など） |

### 出力先

PowerShellパイプライン - 呼び出し元のスクリプトまたはコンソールに出力

## 処理フロー

### 処理シーケンス

```
1. 入力パラメータの検証
   └─ CertificateまたはThumbprintの必須チェック
2. サムプリントの取得
   └─ Certificateオブジェクトからサムプリントを抽出
3. 管理者権限の確認
   └─ Test-ElevationRequirement
4. SQL Serverサービス情報の取得
   └─ Invoke-ManagedComputerCommandでWMI経由
5. レジストリパスの特定
   └─ REGROOT、VSNAME、ServiceAccountの取得
6. リモート証明書操作
   └─ Invoke-Command2でPowerShellリモーティング
      ├─ 証明書の存在確認
      ├─ 秘密鍵パスの特定
      ├─ サービスアカウントへの読み取り権限付与
      └─ レジストリへのサムプリント設定
7. 必要に応じてサービス再起動
   └─ RestartService指定時にRestart-DbaService呼び出し
8. 結果オブジェクトの出力
   └─ PSCustomObjectとして結果を出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Certificate/Thumbprint指定?}
    B -->|No| C[エラー: 必須パラメータ]
    B -->|Yes| D[サムプリント取得]
    C --> Z[終了]
    D --> E[管理者権限確認]
    E --> F[WMI経由でサービス情報取得]
    F --> G{取得成功?}
    G -->|No| H[エラー: アクセス失敗]
    G -->|Yes| I[REGROOTとVSNAME取得]
    H --> Z
    I --> J{ShouldProcess?}
    J -->|No| K[次のインスタンスへ]
    J -->|Yes| L[リモート証明書操作実行]
    L --> M[証明書存在確認]
    M --> N{存在する?}
    N -->|No| O[警告: 証明書なし]
    N -->|Yes| P[秘密鍵パス特定]
    O --> K
    P --> Q{パス特定成功?}
    Q -->|No| R[警告: パス不明]
    Q -->|Yes| S[サービスアカウントに権限付与]
    R --> K
    S --> T[レジストリにサムプリント設定]
    T --> U[結果オブジェクト出力]
    U --> V{RestartService?}
    V -->|Yes| W[Restart-DbaService]
    V -->|No| X[再起動必要の警告]
    W --> K
    X --> K
    K --> Y{インスタンス残り?}
    Y -->|Yes| E
    Y -->|No| Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パラメータ必須 | CertificateまたはThumbprintのいずれかが必須 | 常時 |
| BR-002 | サムプリント小文字 | レジストリに設定されるサムプリントは小文字に変換される | 常時 |
| BR-003 | 権限自動付与 | サービスアカウントとサービスSIDに証明書秘密鍵の読み取り権限を自動付与 | 常時 |
| BR-004 | サービス再起動 | 証明書変更はサービス再起動後に有効化 | 常時 |

### 計算ロジック

特になし

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

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

本機能はデータベースに直接影響を与えない。レジストリ設定とファイルシステム権限の変更を行う。

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| 証明書設定 | Windowsレジストリ | UPDATE | SuperSocketNetLib\Certificateの値を設定 |
| 権限付与 | 証明書秘密鍵 | UPDATE | サービスアカウントに読み取り権限を付与 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | CertificateもThumbprintも未指定 | Stop-Functionでエラー出力 |
| - | 証明書不存在 | 指定されたサムプリントの証明書がない | 警告を出力、処理継続 |
| - | 秘密鍵パス不明 | 秘密鍵のパスを特定できない | 警告を出力、処理継続 |
| - | アクセス失敗 | WMIまたはレジストリにアクセスできない | Stop-Functionでエラー出力、処理継続 |

### リトライ仕様

リトライ機能なし - エラー発生時は次のインスタンスの処理を継続

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

レジストリ操作およびファイルシステム権限操作にトランザクション機能はない。変更は即座に適用される。

## パフォーマンス要件

特に定義されていない。レジストリおよびACL操作は通常高速に完了する。

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

- ターゲットコンピュータへの管理者権限が必要
- PowerShellリモーティングが有効である必要がある
- Credentialパラメータで異なるドメインのサーバーにアクセス可能
- 証明書には秘密鍵が必要
- RSA、ECDSA、DSAアルゴリズムの証明書をサポート

## 備考

- New-DbaComputerCertificateからのパイプライン入力をサポート
- 証明書設定後はSQL Serverサービスの再起動が必要（RestartServiceスイッチで自動化可能）
- NT SERVICE\MSSQLSERVER（またはNT SERVICE\MSSQL$InstanceName）のService SIDにも権限が付与される
- 参考URL: https://www.itprotoday.com/sql-server/7-steps-ssl-encryption

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | レジストリ構造 | `HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\[REGROOT]\MSSQLServer\SuperSocketNetLib` | SQL Serverネットワーク設定のレジストリ構造を理解する |
| 1-2 | 秘密鍵パス | `%ProgramData%\Microsoft\Crypto\RSA\MachineKeys\` または `%ProgramData%\Microsoft\Crypto\Keys\` | 証明書秘密鍵の保存場所を理解する |

**読解のコツ**: 秘密鍵のパスは証明書の種類（RSA/ECDSA/DSA）とPowerShellのバージョン（Core/Desktop）によって異なる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaNetworkCertificate.ps1 | `public/Set-DbaNetworkCertificate.ps1` | メイン関数の入口とパラメータ定義を確認 |

**主要処理フロー**:
1. **82-95行目**: パラメータブロック定義 - CmdletBinding属性でShouldProcess、ConfirmImpact=Lowを設定、ParameterSetでCertificateとThumbprintを分離
2. **100-105行目**: パラメータ検証とサムプリント取得
3. **112-126行目**: 各インスタンスに対するループ、WMI経由でサービス情報取得
4. **156-249行目**: リモートスクリプトブロック定義
  - **165-173行目**: 証明書の存在確認
  - **176-212行目**: 秘密鍵パスの特定（RSA/ECDSA/DSAアルゴリズム対応）
  - **220-223行目**: サービスアカウントへの権限付与
  - **225-226行目**: レジストリへのサムプリント設定
5. **251-258行目**: リモート実行とサービス再起動処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Invoke-ManagedComputerCommand | `private/functions/Invoke-ManagedComputerCommand.ps1` | WMI操作の仕組みを理解 |
| 3-2 | Invoke-Command2 | `private/functions/Invoke-Command2.ps1` | PowerShellリモーティングの仕組みを理解 |
| 3-3 | Restart-DbaService | `public/Restart-DbaService.ps1` | サービス再起動の仕組みを理解 |

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

```
Set-DbaNetworkCertificate
    │
    ├─ パラメータ検証
    │      └─ Certificate/Thumbprint必須チェック
    │
    ├─ Test-ElevationRequirement
    │      └─ 管理者権限確認
    │
    ├─ Invoke-ManagedComputerCommand
    │      └─ WMI.Services取得
    │
    ├─ ShouldProcess (確認処理)
    │
    ├─ Invoke-Command2 (リモート実行)
    │      ├─ Get-ChildItem Cert:\LocalMachine
    │      ├─ Get-Acl / Set-Acl (秘密鍵権限)
    │      └─ Set-ItemProperty (レジストリ)
    │
    └─ Restart-DbaService (オプション)
```

### データフロー図

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

SqlInstance     ───┬──▶ Invoke-ManagedComputerCommand ───▶ サービス情報
Credential      ───┤                                           │
Certificate     ───┤                                           │
Thumbprint      ───┘                                           │
                                                               ▼
                                                    Invoke-Command2
                                               (リモート証明書操作)
                                                        │
                                                        ├─ 証明書検索
                                                        ├─ 秘密鍵パス特定
                                                        ├─ ACL権限付与
                                                        └─ レジストリ設定
                                                               │
                                                               ▼
                                                        [PSCustomObject] ───▶ パイプライン出力
                                                        ComputerName
                                                        InstanceName
                                                        SqlInstance
                                                        ServiceAccount
                                                        CertificateThumbprint
                                                        Notes
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaNetworkCertificate.ps1 | `public/Set-DbaNetworkCertificate.ps1` | ソース | メイン関数 |
| Remove-DbaNetworkCertificate.ps1 | `public/Remove-DbaNetworkCertificate.ps1` | ソース | ネットワーク証明書削除関数 |
| Get-DbaNetworkCertificate.ps1 | `public/Get-DbaNetworkCertificate.ps1` | ソース | ネットワーク証明書取得関数 |
| New-DbaComputerCertificate.ps1 | `public/New-DbaComputerCertificate.ps1` | ソース | 証明書作成関数 |
| Restart-DbaService.ps1 | `public/Restart-DbaService.ps1` | ソース | サービス再起動関数 |
| Set-DbaNetworkCertificate.Tests.ps1 | `tests/Set-DbaNetworkCertificate.Tests.ps1` | テスト | 単体テスト |
