# 画面設計書 121-コンピュータ証明書

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるコンピュータ証明書管理機能の設計仕様を定義する。SQL Server TLS暗号化に使用可能なX.509証明書の追加、取得、作成、削除、バックアップ、有効期限テスト機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：SQL Server の接続を暗号化するためには、サーバー認証機能を持つX.509証明書が必要である。本機能群は、Windows証明書ストアからSQL Server TLS暗号化に適した証明書を取得・管理し、証明書のライフサイクル全体（作成、追加、バックアップ、有効期限監視、削除）をPowerShellから一元的に管理することで、手動での証明書ストア操作を不要にする。特に、複数のSQL Serverホストにまたがる証明書管理や、Active Directory証明書サービスとの連携を自動化することで、セキュリティコンプライアンスの維持を効率化する。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドレットを実行してアクセスする。
- `Get-DbaComputerCertificate` - 証明書の取得
- `Add-DbaComputerCertificate` - 証明書の追加（インポート）
- `New-DbaComputerCertificate` - 証明書の新規作成
- `Remove-DbaComputerCertificate` - 証明書の削除
- `Backup-DbaComputerCertificate` - 証明書のバックアップ
- `Test-DbaComputerCertificateExpiration` - 有効期限のテスト

**主要な操作・処理内容**：
1. SQL Server TLS暗号化に適した証明書（Server Authentication拡張キー使用法を持つ）をローカルまたはリモートコンピュータの証明書ストアから取得
2. 証明書ファイル（.cer, .crt, .pfx）を証明書ストアにインポート（秘密鍵のエクスポート可否設定を含む）
3. 自己署名証明書またはActive Directory CA署名証明書の新規作成
4. 不要になった証明書の削除
5. 証明書のPFXファイルへのバックアップ（秘密鍵を含む）
6. 証明書の有効期限切れを事前に検出

**画面遷移**：本機能はCLIコマンドであり、GUI画面遷移は存在しない。関連コマンドとして`Set-DbaNetworkCertificate`でSQL Serverインスタンスに証明書を適用できる。

**権限による表示制御**：
- ローカルコンピュータの証明書操作には管理者権限が必要
- リモートコンピュータの操作にはPowerShellリモーティング権限とリモートマシンの管理者権限が必要
- Active Directory CA署名証明書の作成には、証明書テンプレートへの自動登録権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 595 | Get-DbaComputerCertificate | 主機能 | コンピュータ証明書の取得 |
| 589 | Add-DbaComputerCertificate | 主機能 | コンピュータ証明書の追加 |
| 603 | New-DbaComputerCertificate | 主機能 | コンピュータ証明書の作成 |
| 610 | Remove-DbaComputerCertificate | 主機能 | コンピュータ証明書の削除 |
| 26 | Backup-DbaComputerCertificate | 補助機能 | コンピュータ証明書のバックアップ |
| 619 | Test-DbaComputerCertificateExpiration | 補助機能 | 証明書有効期限のテスト |
| 604 | New-DbaComputerCertificateSigningRequest | 補助機能 | 証明書署名要求の生成 |

## 画面種別

CLI（コマンドラインインターフェース） - 複数のコマンドレットで構成

## URL/ルーティング

PowerShellコマンドレット:
- `Get-DbaComputerCertificate`
- `Add-DbaComputerCertificate`
- `New-DbaComputerCertificate`
- `Remove-DbaComputerCertificate`
- `Backup-DbaComputerCertificate`
- `Test-DbaComputerCertificateExpiration`

## 入出力項目

### Get-DbaComputerCertificate パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| ComputerName | DbaInstanceParameter[] | No | $env:COMPUTERNAME | 証明書を取得するコンピュータ名 |
| Credential | PSCredential | No | - | 代替資格情報 |
| Store | string[] | No | LocalMachine | 証明書ストアの場所 |
| Folder | string[] | No | My | 証明書フォルダ |
| Type | string | No | Service | フィルタタイプ（Service/All） |
| Path | string | No | - | 証明書ファイルのパス |
| Thumbprint | string[] | No | - | 取得する証明書のサムプリント |
| EnableException | switch | No | $false | 例外を有効化 |

### Add-DbaComputerCertificate パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| ComputerName | DbaInstance[] | No | $env:COMPUTERNAME | 証明書を追加するコンピュータ名 |
| Credential | PSCredential | No | - | 代替資格情報 |
| SecurePassword | SecureString | No | - | 証明書ファイルのパスワード |
| Certificate | X509Certificate2[] | No | - | 追加する証明書オブジェクト |
| Path | string | No | - | 証明書ファイルのパス |
| Store | string | No | LocalMachine | 証明書ストアの場所 |
| Folder | string | No | My | 証明書フォルダ |
| Flag | string[] | No | Exportable, PersistKeySet | インポートフラグ |
| EnableException | switch | No | $false | 例外を有効化 |

### New-DbaComputerCertificate パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| ComputerName | DbaInstance[] | No | $env:COMPUTERNAME | 証明書を作成するコンピュータ名 |
| Credential | PSCredential | No | - | 代替資格情報 |
| CaServer | string | No | - | 証明機関サーバー |
| CaName | string | No | - | 証明機関名 |
| ClusterInstanceName | string | No | - | クラスター仮想名 |
| SecurePassword | SecureString | No | - | 秘密鍵のパスワード |
| FriendlyName | string | No | SQL Server | 証明書のフレンドリ名 |
| CertificateTemplate | string | No | WebServer | 証明書テンプレート |
| KeyLength | int | No | 2048 | キー長（ビット） |
| Store | string | No | LocalMachine | 証明書ストア |
| Folder | string | No | My | 証明書フォルダ |
| Flag | string[] | No | Exportable, PersistKeySet | インポートフラグ |
| Dns | string[] | No | - | SAN DNSエントリ |
| SelfSigned | switch | No | $false | 自己署名証明書を作成 |
| HashAlgorithm | string | No | Sha256 | ハッシュアルゴリズム |
| MonthsValid | int | No | 12 | 自己署名証明書の有効月数 |
| EnableException | switch | No | $false | 例外を有効化 |

## 表示項目

### Get-DbaComputerCertificate 出力

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| 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 | 署名アルゴリズム |

### Add-DbaComputerCertificate / New-DbaComputerCertificate 出力

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| FriendlyName | string | 証明書のフレンドリ名 |
| DnsNameList | string[] | DNS名リスト |
| Thumbprint | string | サムプリント |
| NotBefore | DateTime | 有効期間開始日 |
| NotAfter | DateTime | 有効期間終了日 |
| Subject | string | サブジェクト |
| Issuer | string | 発行者 |

## イベント仕様

### 1-証明書取得（Get-DbaComputerCertificate）

指定されたコンピュータの証明書ストアからSQL Server TLS暗号化に適した証明書を取得する。

**処理フロー**:
1. コンピュータ名の解決
2. PowerShellリモーティングでターゲットコンピュータに接続
3. 証明書ストア（Cert:\Store\Folder）から証明書を列挙
4. Type=Serviceの場合、Server Authentication OID（1.3.6.1.5.5.7.3.1）を持つ証明書のみフィルタ
5. Thumbprint指定時は該当サムプリントの証明書のみ返却
6. 結果をパイプラインに出力

### 2-証明書追加（Add-DbaComputerCertificate）

証明書ファイルまたは証明書オブジェクトを指定されたコンピュータの証明書ストアにインポートする。

**処理フロー**:
1. Pathが指定された場合、ファイルをバイト配列として読み込み
2. X509Certificate2Collectionを使用して証明書チェーン全体をインポート
3. リモートコンピュータへPowerShellリモーティングで接続
4. スクリプトブロック内で証明書ストアを開き、証明書を追加
5. インポートされた証明書オブジェクトを返却

### 3-証明書作成（New-DbaComputerCertificate）

自己署名またはCA署名の新しい証明書を作成する。

**処理フロー**:
1. 英語OSロケールの確認（現在は英語のみサポート）
2. CA情報の自動検出（CaServer/CaNameが未指定の場合）
3. 証明書要求構成ファイル（.inf）の生成
4. certreqコマンドで証明書要求を作成
5. SelfSigned=trueの場合はローカルで自己署名、それ以外はCAに送信
6. 証明書をローカルストアにインストール
7. リモートコンピュータの場合はPFXとしてエクスポートしてリモートにインポート

### 4-証明書削除（Remove-DbaComputerCertificate）

指定されたサムプリントを持つ証明書を証明書ストアから削除する。

### 5-証明書バックアップ（Backup-DbaComputerCertificate）

証明書をPFXファイルとしてエクスポートする（秘密鍵を含む）。

### 6-有効期限テスト（Test-DbaComputerCertificateExpiration）

証明書の有効期限をチェックし、期限切れまたは期限切れ間近の証明書を検出する。

## データベース更新仕様

本機能はSQL Serverデータベースには直接アクセスしない。Windows証明書ストア（レジストリベース）に対して操作を行う。

### 操作別影響一覧

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Get-DbaComputerCertificate | Windows証明書ストア | READ | 証明書の読み取り |
| Add-DbaComputerCertificate | Windows証明書ストア | CREATE | 証明書の追加 |
| New-DbaComputerCertificate | Windows証明書ストア, AD CS | CREATE | 証明書の作成・登録 |
| Remove-DbaComputerCertificate | Windows証明書ストア | DELETE | 証明書の削除 |
| Backup-DbaComputerCertificate | ファイルシステム | CREATE | PFXファイルの作成 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 発生条件 |
|-------------|------|---------|---------|
| - | Error | "Path ($Path) does not exist." | 指定されたファイルパスが存在しない |
| - | Error | "Can't import certificate." | 証明書のインポートに失敗 |
| - | Error | "Issue connecting to computer" | リモートコンピュータへの接続失敗 |
| - | Warning | "UserProtected flag is only valid for localhost" | リモートでUserProtectedフラグを使用 |
| - | Error | "Currently, this command is only supported in English OS locales" | 非英語OSで証明書作成を試行 |
| - | Warning | "$computerResolved was not found to be an EC2 instance" | AWSメタデータ取得失敗 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが見つからない | エラーメッセージを出力し処理を中断 |
| 証明書インポート失敗 | 詳細エラーを出力し処理を中断 |
| リモート接続失敗 | 警告を出力し次のコンピュータの処理を継続 |
| 管理者権限不足 | エラーメッセージを出力し処理を中断 |
| CA接続失敗 | Active Directory CA情報取得エラーを出力 |
| 証明書テンプレートなし | 指定されたテンプレートが存在しない旨のエラー |

## 備考

- SQL Server TLS暗号化に使用する証明書は、Server Authentication拡張キー使用法（OID: 1.3.6.1.5.5.7.3.1）を持つ必要がある
- 証明書の秘密鍵はSQL Serverサービスアカウントがアクセスできる必要がある
- クラスター環境では各ノードに同じ証明書をインポートする必要がある
- 自己署名証明書はクライアントで信頼されないため、本番環境ではCA署名証明書を推奨

---

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

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

### 推奨読解順序

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

まず、証明書オブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | X509Certificate2 | .NETフレームワーク | 証明書を表す標準.NETクラス。Thumbprint, Subject, NotAfter等のプロパティ |

**読解のコツ**: PowerShellでは`[System.Security.Cryptography.X509Certificates.X509Certificate2]`クラスを使用。証明書ストアは`Cert:\`ドライブとしてアクセス可能。

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

Get-DbaComputerCertificateが最も基本的なコマンド。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaComputerCertificate.ps1 | `public/Get-DbaComputerCertificate.ps1` | 証明書取得のメインロジック |

**主要処理フロー**:
1. **117-214行**: スクリプトブロック定義 - リモート実行用の証明書取得ロジック
2. **127-132行**: Pathパラメータ処理 - ファイルからの証明書読み込み
3. **134-152行**: Get-CoreCertStore関数 - 証明書ストアを開く
4. **154-185行**: Get-CoreCertificate関数 - 証明書を取得し追加プロパティを付与
5. **216-241行**: processブロック - 各コンピュータに対してInvoke-Command2でリモート実行

#### Step 3: 証明書追加処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 証明書インポートロジック |

**主要処理フロー**:
- **176-223行**: Pathからファイル読み込み、X509Certificate2Collectionでチェーン全体をインポート
- **226-256行**: リモート実行用スクリプトブロック - 証明書ストアを開いて追加
- **258-323行**: processブロック - ローカル/リモートの分岐処理

#### Step 4: 証明書作成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | New-DbaComputerCertificate.ps1 | `public/New-DbaComputerCertificate.ps1` | 証明書生成ロジック |

**主要処理フロー**:
- **235-246行**: GetHexLength関数 - SAN拡張のバイナリエンコード用
- **248-285行**: Get-SanExt関数 - Subject Alternative Name拡張の生成
- **287-317行**: CA自動検出 - Active DirectoryからCA情報を取得
- **374-408行**: INFファイル生成 - certreq用の構成ファイル作成
- **410-443行**: certreqコマンド実行 - 証明書要求の生成と署名

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

```
Get-DbaComputerCertificate
    |
    +-- Invoke-Command2 (リモート実行)
           |
           +-- Get-CoreCertStore (証明書ストアを開く)
           |      +-- X509Store.Open()
           |
           +-- Get-CoreCertificate (証明書を取得)
                  +-- Where-Object (Server Authentication OIDでフィルタ)

Add-DbaComputerCertificate
    |
    +-- X509Certificate2Collection.Import() (証明書チェーン読み込み)
    |
    +-- Invoke-Command2 (リモート実行)
           +-- X509Store.Add() (証明書追加)

New-DbaComputerCertificate
    |
    +-- ADSI LDAP クエリ (CA自動検出)
    |
    +-- Set-Content/Add-Content (INFファイル生成)
    |
    +-- certreq -new (証明書要求作成)
    |
    +-- certreq -submit (CAに送信) または 自己署名
    |
    +-- certreq -accept (証明書インストール)
    |
    +-- Invoke-Command2 (リモートにインポート)
```

### データフロー図

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

ComputerName ─────────> Invoke-Command2 ──────────> X509Certificate2[]
Store/Folder ─────────> X509Store.Open() ─────────> (証明書オブジェクト)
Thumbprint ───────────> Where-Object ─────────────>

Path (PFXファイル) ───> X509Certificate2Collection.Import()
SecurePassword ───────> X509Store.Add() ──────────> インポート済み証明書

FriendlyName ─────────> INFファイル生成 ──────────>
KeyLength ────────────> certreq -new ─────────────> 新規証明書
CaServer/CaName ──────> certreq -submit ──────────>
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaComputerCertificate.ps1 | `public/Get-DbaComputerCertificate.ps1` | ソース | 証明書取得コマンド |
| Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | ソース | 証明書追加コマンド |
| New-DbaComputerCertificate.ps1 | `public/New-DbaComputerCertificate.ps1` | ソース | 証明書作成コマンド |
| Remove-DbaComputerCertificate.ps1 | `public/Remove-DbaComputerCertificate.ps1` | ソース | 証明書削除コマンド |
| Backup-DbaComputerCertificate.ps1 | `public/Backup-DbaComputerCertificate.ps1` | ソース | 証明書バックアップコマンド |
| Test-DbaComputerCertificateExpiration.ps1 | `public/Test-DbaComputerCertificateExpiration.ps1` | ソース | 有効期限テストコマンド |
| Invoke-Command2.ps1 | `internal/functions/Invoke-Command2.ps1` | 内部関数 | リモートコマンド実行ユーティリティ |
