# 機能設計書 619-Test-DbaComputerCertificateExpiration

## 概要

本ドキュメントは、SQL Serverコンピュータ上の期限切れまたは期限間近のSSL/TLS証明書を特定するdbatools PowerShell関数 `Test-DbaComputerCertificateExpiration` の機能設計書である。

### 本機能の処理概要

**業務上の目的・背景**：SSL/TLS証明書の有効期限切れは、SQL Serverへのセキュアな接続障害を引き起こす重大な問題である。特にネットワーク暗号化に使用される証明書が期限切れになると、クライアント接続が失敗する。本機能は、SQL Serverネットワーク暗号化に使用される可能性のある証明書をスキャンし、指定した日数内に期限切れとなる証明書を事前に特定することで、DBAがプロアクティブに対応できるようにする。

**機能の利用シーン**：
- 定期的な証明書有効期限の監視
- 証明書更新計画の策定
- 複数サーバーの証明書状態の一括確認
- コンプライアンス監査対応

**主要な処理内容**：
1. ターゲットコンピュータの証明書ストアをスキャン
2. SQL Server用証明書（Service）またはSQL Server使用中の証明書のみを対象
3. 各証明書の有効期限をしきい値と比較
4. 期限切れまたは期限間近の証明書を詳細情報付きで出力

**関連システム・外部連携**：
- Windows証明書ストア（LocalMachine\My等）
- Get-DbaComputerCertificateまたはGet-DbaNetworkCertificateを使用

**権限による制御**：証明書ストアへの読み取りアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 121 | コンピュータ証明書 | 補助機能 | 証明書有効期限のテスト |

## 機能種別

監視・検証 - 証明書有効期限チェック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | 対象のコンピュータ（デフォルト: localhost） | 有効なコンピュータ名 |
| Credential | PSCredential | No | リモートコンピュータへのアクセス用資格情報 | 有効な資格情報オブジェクト |
| Store | string[] | No | 証明書ストアの場所（デフォルト: LocalMachine） | 有効なストア名 |
| Folder | string[] | No | 証明書フォルダ（デフォルト: My） | 有効なフォルダ名 |
| Path | string | No | 証明書ファイルのファイルシステムパス | 有効なパス |
| Type | string | No | 検査する証明書の種類（All/Service/SQL Server）（デフォルト: Service） | All/Service/SQL Server |
| Thumbprint | string[] | No | 特定のサムプリントでフィルター | 有効なサムプリント |
| Threshold | int | No | 期限切れ警告のしきい値日数（デフォルト: 30） | 正の整数 |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- ComputerNameパラメータ: コマンドライン引数（デフォルトは$env:COMPUTERNAME）
- Credential: Get-Credentialコマンドレットまたは事前定義の資格情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | 証明書が保存されているコンピュータ名 |
| Store | string | 証明書ストアの場所 |
| Folder | string | 証明書フォルダ |
| Name | string | 証明書のフレンドリ名 |
| DnsNameList | string[] | 証明書に関連付けられたDNS名 |
| Thumbprint | string | 証明書のサムプリント（SHA-1ハッシュ） |
| NotBefore | datetime | 証明書の有効開始日時 |
| NotAfter | datetime | 証明書の有効期限日時 |
| Subject | string | 証明書のサブジェクト識別名 |
| Issuer | string | 証明書の発行者識別名 |
| Algorithm | string | 署名アルゴリズム |
| ExpiredOrExpiring | bool | 期限切れまたは期限間近かどうか（常にtrue） |
| Note | string | 有効期限に関する説明メッセージ |

### 出力先

PowerShellパイプライン - 期限切れまたは期限間近の証明書のみを出力。条件を満たす証明書がない場合は出力なし。

## 処理フロー

### 処理シーケンス

```
1. 各コンピュータに対するループ処理
   └─ Write-Message でログ出力
2. 証明書タイプに応じた取得処理
   ├─ Type="SQL Server"の場合
   │   └─ Get-DbaNetworkCertificate で取得
   └─ Type="Service"または"All"の場合
       └─ Get-DbaComputerCertificate で取得
3. 各証明書に対するループ処理
   └─ 有効期限までの日数を計算
4. しきい値との比較
   └─ 期限までの日数 < Threshold の場合
       ├─ 既に期限切れの場合は専用メッセージ
       └─ 期限間近の場合は残り日数を表示
5. プロパティの追加と出力
   └─ ExpiredOrExpiring、Noteプロパティを追加
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コンピュータループ開始]
    B --> C{Type?}
    C -->|SQL Server| D[Get-DbaNetworkCertificate]
    C -->|Service/All| E[Get-DbaComputerCertificate]
    D --> F[証明書リスト取得]
    E --> F
    F --> G[証明書ループ開始]
    G --> H{証明書残り?}
    H -->|No| I[次のコンピュータへ]
    H -->|Yes| J[有効期限日数計算]
    J --> K{日数 < Threshold?}
    K -->|No| L[次の証明書へ]
    K -->|Yes| M{既に期限切れ?}
    M -->|Yes| N[期限切れメッセージ設定]
    M -->|No| O[残り日数メッセージ設定]
    N --> P[プロパティ追加]
    O --> P
    P --> Q[結果出力]
    Q --> L
    L --> H
    I --> R{コンピュータ残り?}
    R -->|Yes| B
    R -->|No| Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトしきい値 | Thresholdが未指定の場合、30日をデフォルトとして使用 | Threshold未指定時 |
| BR-002 | デフォルトストア | Storeが未指定の場合、LocalMachineを使用 | Store未指定時 |
| BR-003 | デフォルトフォルダ | Folderが未指定の場合、Myを使用 | Folder未指定時 |
| BR-004 | 条件付き出力 | 期限切れまたは期限間近の証明書のみ出力（条件を満たさない場合は出力なし） | 常時 |
| BR-005 | メッセージ分岐 | 既に期限切れの場合と期限間近の場合でNoteの内容が異なる | 常時 |

### 計算ロジック

```
有効期限日数 = 証明書.NotAfter.Date - 現在日時
ExpiredOrExpiring = (有効期限日数 < Threshold)
Note =
  - 期限切れの場合: "This certificate has expired and is no longer valid"
  - 期限間近の場合: "This certificate expires in X days"
```

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

本機能はデータベースに直接影響を与えない。証明書ストアの読み取りのみを行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続失敗 | リモートコンピュータに接続できない | Stop-Functionでエラー出力 |
| - | 証明書取得失敗 | 証明書ストアにアクセスできない | Stop-Functionでエラー出力 |

### リトライ仕様

リトライ機能なし - エラー発生時は処理を中断

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

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

## パフォーマンス要件

特に定義されていない。証明書ストアの読み取りは通常高速に完了する。

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

- 証明書ストアへの読み取り権限が必要
- 証明書の秘密鍵にはアクセスしない
- リモートコンピュータへのアクセスにはCredentialパラメータを使用

## 備考

- Type="SQL Server"を使用すると、SQL Serverインスタンスで現在設定されている証明書のみを対象とする
- Type="Service"は、SQL Serverに適した証明書（秘密鍵を持つもの）を対象とするが、IISなど他のサービスでも使用される可能性がある
- Pathパラメータを使用すると、証明書ストアではなくファイルシステム上の証明書ファイルを検査可能
- 監視スクリプトに組み込んで定期実行することを推奨

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | X509Certificate2 | System.Security.Cryptography.X509Certificates | 証明書オブジェクトの構造、NotAfterプロパティを理解 |

**読解のコツ**: NotAfterプロパティは証明書の有効期限を示すDateTimeで、現在日時との差分で残り日数を計算する。

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

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

**主要処理フロー**:
1. **96-109行目**: パラメータブロック定義 - Type、Threshold等のデフォルト値設定
2. **110-111行目**: 各コンピュータに対するループ開始
3. **113-136行目**: Type判定と証明書取得
  - **114-116行目**: Type="SQL Server"の場合、Get-DbaNetworkCertificate
  - **117-135行目**: それ以外の場合、Get-DbaComputerCertificate
4. **138行目**: 取得した証明書数をログ出力
5. **139-151行目**: 各証明書の期限チェック
  - **141行目**: 有効期限日数の計算
  - **142-150行目**: しきい値との比較とNote設定
6. **148-150行目**: ExpiredOrExpiring、Noteプロパティ追加と出力

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaNetworkCertificate.ps1 | `public/Get-DbaNetworkCertificate.ps1` | SQL Server用証明書の取得 |
| 3-2 | Get-DbaComputerCertificate.ps1 | `public/Get-DbaComputerCertificate.ps1` | コンピュータ証明書の取得 |

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

```
Test-DbaComputerCertificateExpiration
    │
    ├─ foreach ComputerName
    │      │
    │      ├─ Type判定
    │      │      ├─ "SQL Server"
    │      │      │      └─ Get-DbaNetworkCertificate
    │      │      │
    │      │      └─ "Service"/"All"
    │      │             └─ Get-DbaComputerCertificate
    │      │
    │      └─ foreach Certificate
    │             ├─ 有効期限日数計算
    │             ├─ しきい値比較
    │             ├─ Add-Member (ExpiredOrExpiring, Note)
    │             └─ Select-DefaultView
    │
    └─ エラー処理
           └─ Stop-Function
```

### データフロー図

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

ComputerName     ───┬──▶ Type判定 ───▶ 証明書取得関数選択
Credential       ───┤                         │
Store            ───┤                         │
Folder           ───┤                         ▼
Path             ───┤                  証明書リスト
Type             ───┤                         │
Thumbprint       ───┤                         │
Threshold        ───┘                         ▼
                                       foreach Certificate
                                              │
                                       有効期限日数計算
                                       (NotAfter - 現在日時)
                                              │
                                              ▼
                                       {日数 < Threshold?}
                                              │
                                    ┌─────────┴─────────┐
                                    │No                 │Yes
                                    ▼                   ▼
                                 スキップ         プロパティ追加
                                                 ExpiredOrExpiring
                                                 Note
                                                       │
                                                       ▼
                                                [証明書オブジェクト] ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Test-DbaComputerCertificateExpiration.ps1 | `public/Test-DbaComputerCertificateExpiration.ps1` | ソース | メイン関数 |
| Get-DbaNetworkCertificate.ps1 | `public/Get-DbaNetworkCertificate.ps1` | ソース | SQL Server用証明書取得 |
| Get-DbaComputerCertificate.ps1 | `public/Get-DbaComputerCertificate.ps1` | ソース | コンピュータ証明書取得 |
| Test-DbaComputerCertificateExpiration.Tests.ps1 | `tests/Test-DbaComputerCertificateExpiration.Tests.ps1` | テスト | 単体テスト |
