# 機能設計書 589-Add-DbaComputerCertificate

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Add-DbaComputerCertificate`コマンドレットに関する機能設計書です。本機能はX.509証明書をローカルまたはリモートコンピュータのWindows証明書ストアにインポートします。

### 本機能の処理概要

`Add-DbaComputerCertificate`は、X.509証明書（秘密鍵付きのパスワード保護された.pfxファイルを含む）を指定されたWindows証明書ストアにインポートします。SQL Server TLS/SSL暗号化のセットアップ、可用性グループの証明書要件、Service Brokerセキュリティ構成に不可欠です。

**業務上の目的・背景**：SQL Serverの暗号化通信、Transparent Data Encryption (TDE)、Service Broker、可用性グループなど、多くの機能で証明書が必要です。証明書のインポートは手動で行うと複雑でエラーが発生しやすいため、本機能はこれらの操作を自動化し、複数サーバーへの一括デプロイを可能にします。

**機能の利用シーン**：
- SQL Server TLS/SSL暗号化のセットアップ
- 可用性グループの証明書要件への対応
- Service Brokerセキュリティ構成
- クラスタノードへの証明書展開
- Let's Encrypt証明書のインポート
- カスタムCA証明書のインストール

**主要な処理内容**：
1. 証明書ファイルの読み込み（パスまたはパイプラインから）
2. X509Certificate2Collectionを使用した証明書チェーン全体のインポート
3. PowerShellリモーティングによるリモートコンピュータへのインストール
4. 指定されたストアとフォルダへの証明書追加
5. インポートされた証明書オブジェクトの返却

**関連システム・外部連携**：Windows証明書ストア、PowerShellリモーティング（Invoke-Command2）を使用します。

**権限による制御**：LocalMachineストアへの書き込みには管理者権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 121 | コンピュータ証明書 | 主機能 | コンピュータ証明書の追加 |

## 機能種別

CRUD操作（Create） / セキュリティ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstance[] | No | 証明書をインストールする対象コンピュータ | デフォルト: localhost |
| Credential | PSCredential | No | リモートコンピュータ接続用の資格情報 | - |
| SecurePassword | SecureString | No | PFXファイルのパスワード | - |
| Certificate | X509Certificate2[] | No | パイプラインからの証明書オブジェクト | - |
| Path | string | No | 証明書ファイルのローカルパス | ファイル存在確認 |
| Store | string | No | 証明書ストア（LocalMachine/CurrentUser） | デフォルト: LocalMachine |
| Folder | string | No | 証明書フォルダ（My/Root/CA等） | デフォルト: My |
| Flag | string[] | No | 秘密鍵の保存フラグ | ValidateSet制約 |
| EnableException | switch | No | 例外をスローするモード | - |

### 入力データソース

- ローカルファイルシステムからの証明書ファイル（.cer, .crt, .pfx, .p12）
- パイプラインからのX509Certificate2オブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FriendlyName | string | 証明書のフレンドリ名 |
| DnsNameList | Collection | 証明書が有効なDNS名（SAN） |
| Thumbprint | string | 証明書のSHA-1ハッシュ（一意識別子） |
| NotBefore | DateTime | 証明書の有効開始日時 |
| NotAfter | DateTime | 証明書の有効期限日時 |
| Subject | string | 証明書のサブジェクト識別名 |
| Issuer | string | 証明書の発行者識別名 |

### 出力先

PowerShellパイプラインへのSystem.Security.Cryptography.X509Certificates.X509Certificate2オブジェクトの出力

## 処理フロー

### 処理シーケンス

```
1. フラグの処理（beginブロック）
   └─ NonExportable指定時はExportableを除外
   └─ LocalMachineの場合はMachineKeySetを使用

2. 証明書ファイルの読み込み（Pathパラメータ時）
   └─ File.ReadAllBytesでバイト配列として読み込み
   └─ X509Certificate2Collectionでチェーン全体をインポート
   └─ SecurePasswordをプレーンテキストに変換
   └─ 再エクスポートでリモート転送用データ作成

3. 各コンピュータへの処理
   └─ UserProtected+リモートの場合はスキップ
   └─ Invoke-Command2でリモートスクリプト実行

4. リモートスクリプトブロック
   └─ X509Certificate2Collectionで証明書インポート
   └─ 指定ストア/フォルダを開く
   └─ 各証明書を追加
   └─ インポートされた証明書を返却

5. 結果出力
   └─ Select-DefaultViewで主要プロパティを表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{NonExportable指定?}
    B -->|Yes| C[Exportable除外、MachineKeySet設定]
    B -->|No| D[フラグをカンマ結合]
    C --> E{Path指定?}
    D --> E
    E -->|Yes| F[ファイル読み込み]
    E -->|No| G{Certificate指定?}
    F --> H[X509Certificate2Collectionでインポート]
    H --> I[SecurePassword変換]
    I --> J[PFX再エクスポート]
    J --> K[各ComputerNameループ]
    G -->|Yes| K
    G -->|No| L[エラー終了]
    K --> M{UserProtected+リモート?}
    M -->|Yes| N[スキップ]
    M -->|No| O[Invoke-Command2実行]
    O --> P[リモート: 証明書インポート]
    P --> Q[リモート: ストア追加]
    Q --> R[Select-DefaultView出力]
    R --> S{次のコンピュータ?}
    N --> S
    S -->|Yes| K
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-589-01 | UserProtected制限 | UserProtectedフラグはlocalhostでのみ使用可能（プロンプト表示のため） | UserProtected指定時 |
| BR-589-02 | NonExportable処理 | NonExportable指定時はExportableを除外 | NonExportable指定時 |
| BR-589-03 | チェーンインポート | PFXファイルの場合、中間証明書を含む完全なチェーンをインポート | PFXファイル時 |
| BR-589-04 | デフォルト設定 | Store=LocalMachine、Folder=My、Flag=Exportable,PersistKeySet | パラメータ未指定時 |

### 計算ロジック

特になし

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

本機能はSQL Serverデータベースへの操作を行いません。Windows証明書ストアへの操作を行います。

### 証明書ストア操作

| 操作 | 対象ストア | 操作種別 | 概要 |
|-----|-----------|---------|------|
| 証明書追加 | Cert:\Store\Folder | Add | 証明書をストアに追加 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | FileNotFoundError | 証明書ファイルが存在しない | Stop-Function |
| - | ImportError | 証明書インポート失敗 | Stop-Function |
| - | RemoteError | リモート実行失敗 | Stop-Function、次のコンピュータへ |
| - | InputError | CertificateもPathも未指定 | Stop-Function |

### リトライ仕様

リトライ処理なし。各コンピュータは独立して処理されます。

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

Windows証明書ストア操作は個別に実行されます。ロールバック機能はありません。

## パフォーマンス要件

特に規定なし。

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

- LocalMachineストアへの書き込みには管理者権限が必要
- SecureStringからプレーンテキストへの変換はメモリ上で行われ、使用後は即座にクリア
- PowerShellリモーティングは暗号化された接続を使用
- SupportsShouldProcess実装（ConfirmImpact = "Low"）

## 備考

- X509Certificate2Collectionを使用して証明書チェーン全体をインポート
- Let's Encrypt証明書など、中間証明書を含むPFXファイルに対応
- Set-DbaNetworkCertificateと組み合わせてSQL Server暗号化を設定可能

---

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

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

### 推奨読解順序

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

フラグの処理と証明書コレクションの扱いを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 155-168行目: フラグ処理 |
| 1-2 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 182-219行目: 証明書ファイル読み込み |

**読解のコツ**: NonExportable指定時の処理と、MachineKeySetの自動設定に注意してください。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 139-153行目: パラメータ定義 |

**主要処理フロー**:
1. **141行目**: ComputerName（デフォルト: $env:COMPUTERNAME）
2. **144行目**: SecurePassword
3. **145-146行目**: Certificate、Path
4. **147-150行目**: Store、Folder、Flag

#### Step 3: 証明書ファイルの処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 176-223行目: Path指定時の処理 |

**主要処理フロー**:
- **184行目**: File.ReadAllBytesでバイト配列読み込み
- **187行目**: X509Certificate2Collectionでインポート
- **193-198行目**: SecureStringをプレーンテキストに変換
- **204行目**: チェーン全体をインポート
- **208行目**: PFX形式で再エクスポート（リモート転送用）

#### Step 4: リモートスクリプトブロック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | 226-255行目: リモート実行スクリプト |

**主要処理フロー**:
- **236-237行目**: X509Certificate2Collectionでインポート
- **240-241行目**: ストアを開く
- **244-249行目**: 各証明書を追加
- **254行目**: インポートされた証明書を返却

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

```
Add-DbaComputerCertificate
    │
    ├─ [System.IO.File]::ReadAllBytes()
    │      └─ 証明書ファイル読み込み
    │
    ├─ X509Certificate2Collection.Import()
    │      └─ 証明書チェーンのインポート
    │
    ├─ X509Certificate2Collection.Export()
    │      └─ PFX形式で再エクスポート
    │
    └─ Invoke-Command2
           ├─ X509Certificate2Collection.Import()
           │      └─ リモートでの証明書インポート
           │
           ├─ X509Store.Add()
           │      └─ ストアへの証明書追加
           │
           └─ Get-ChildItem Cert:\
                  └─ インポートされた証明書取得
```

### データフロー図

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

Path ──────────────────▶ File.ReadAllBytes ────────────▶ $fileBytes
                              │
SecurePassword ────────▶ SecureStringToGlobalAllocUnicode ▶ $plainPassword
                              │
                         X509Certificate2Collection.Import ▶ $certCollection
                              │
                         Export(PFX) ──────────────────▶ $collectionData
                              │
ComputerName ──────────▶ Invoke-Command2 ──────────────┐
                              │                         │
                         リモート: Import/Store.Add ───▶ X509Certificate2[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Add-DbaComputerCertificate.ps1 | `public/Add-DbaComputerCertificate.ps1` | ソース | メイン処理 |
| Set-DbaNetworkCertificate.ps1 | `public/Set-DbaNetworkCertificate.ps1` | ソース | SQL Server証明書設定（関連） |
| Get-DbaComputerCertificate.ps1 | `public/Get-DbaComputerCertificate.ps1` | ソース | 証明書取得（関連） |
