# 機能設計書 618-Stop-DbaDbEncryption

## 概要

本ドキュメントは、SQL Serverインスタンス上の全ユーザーデータベースの透過的データ暗号化（TDE）を無効化するdbatools PowerShell関数 `Stop-DbaDbEncryption` の機能設計書である。

### 本機能の処理概要

**業務上の目的・背景**：透過的データ暗号化（TDE）が有効なデータベースを無効化する必要があるシナリオとして、インスタンスの廃止、TDEが不要な環境へのマイグレーション、複数データベースのセキュリティ設定の標準化などがある。本機能は、インスタンス上の暗号化されたすべてのユーザーデータベースに対してDisable-DbaDbEncryptionを呼び出し、各データベースの暗号化を無効化してDEKを削除する便利なラッパー関数である。

**機能の利用シーン**：
- インスタンス廃止時のTDE一括解除
- TDE不要環境へのマイグレーション準備
- 複数データベースの暗号化設定の一括変更
- セキュリティポリシー変更に伴う暗号化解除

**主要な処理内容**：
1. 対象インスタンスの全ユーザーデータベースを取得（システムDB除外）
2. 各データベースの暗号化状態を確認
3. 暗号化が有効なデータベースに対してDisable-DbaDbEncryptionを呼び出し
4. 暗号化が解除され、DEKが削除される
5. 並列処理オプションでパフォーマンスを向上

**関連システム・外部連携**：SQL Server Management Objects (SMO) を使用してSQL Serverインスタンスと連携する。

**権限による制御**：TDE無効化にはサーバー管理者権限（sysadmin）または同等の権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | データベース暗号化 | 補助機能 | TDE暗号化の停止 |

## 機能種別

データベース暗号化解除 - セキュリティ設定変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象のSQL Serverインスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効な資格情報オブジェクト |
| Parallel | switch | No | 並列処理を有効化（1-10スレッド） | - |
| EnableException | switch | No | 例外処理の有効化 | - |
| WhatIf | switch | No | 実行せずに処理内容を表示 | - |
| Confirm | switch | No | 実行前に確認プロンプトを表示 | - |

### 入力データソース

- SqlInstanceパラメータ: コマンドライン引数
- SqlCredential: Get-Credentialコマンドレットまたは事前定義の資格情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| DatabaseName | string | 処理されたデータベース名 |
| EncryptionEnabled | bool | 暗号化状態（処理後はfalse） |
| Status | string | 処理結果（Success/NotEncrypted/Failed） |
| Error | string | エラーメッセージ（失敗時のみ） |

### 出力先

PowerShellパイプライン - 各データベースの処理結果を出力

## 処理フロー

### 処理シーケンス

```
1. 対象データベースの取得
   └─ Get-DbaDatabase経由でシステムDBを除外
2. 順次処理または並列処理の選択
   └─ -Parallelスイッチの有無で分岐
3. 順次処理の場合
   ├─ 各データベースの暗号化状態を確認
   ├─ 暗号化有効ならDisable-DbaDbEncryptionを呼び出し
   └─ 結果オブジェクトを出力
4. 並列処理の場合
   ├─ runspaceプールを作成（1-10スレッド）
   ├─ 各データベースを並列で処理
   │   ├─ 暗号化無効化（EncryptionEnabled = false）
   │   ├─ 復号化完了を待機（最大120秒）
   │   └─ DEKを削除
   └─ 結果を収集して出力
5. リソースのクリーンアップ
   └─ runspaceプールを破棄
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Get-DbaDatabase]
    B --> C[システムDB除外]
    C --> D{Parallel?}
    D -->|No| E[順次処理ループ]
    D -->|Yes| F[runspaceプール作成]
    E --> G{暗号化有効?}
    G -->|No| H[スキップ - NotEncrypted出力]
    G -->|Yes| I[Disable-DbaDbEncryption]
    I --> J[結果出力]
    H --> K{次のDB?}
    J --> K
    K -->|Yes| G
    K -->|No| Z[終了]
    F --> L[並列タスクキュー]
    L --> M{タスク完了?}
    M -->|No| N[結果収集待ち]
    N --> M
    M -->|Yes| O[プール破棄]
    O --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | システムDB除外 | master、model、tempdb、msdb、resourceデータベースは自動的に除外 | 常時 |
| BR-002 | 暗号化未設定スキップ | 暗号化が有効でないデータベースはNotEncryptedステータスで出力 | EncryptionEnabled=false時 |
| BR-003 | 復号化待機 | 並列処理時、復号化完了を最大120秒待機 | -Parallel指定時 |
| BR-004 | DEK削除 | 暗号化無効化後にDEKを自動削除 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 暗号化無効化 | sys.databases | UPDATE | encryption_stateを変更 |
| DEK削除 | sys.dm_database_encryption_keys | DELETE | データベース暗号化キーを削除 |

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

#### sys.databases

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | is_encrypted | False | ALTER DATABASE SET ENCRYPTION OFFによる |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続失敗 | SQL Serverインスタンスに接続できない | Stop-Functionでエラー出力 |
| - | 無効化失敗 | 暗号化の無効化に失敗 | Stop-Functionでエラー出力、処理継続 |
| - | DEK削除失敗 | DEKの削除に失敗 | Stop-Functionでエラー出力、処理継続 |

### リトライ仕様

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

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

各データベースの暗号化無効化とDEK削除は独立した操作として実行される。

## パフォーマンス要件

- 大量のデータベースを処理する場合は -Parallel スイッチを使用
- 並列処理は1-10スレッドで実行（runspaceプール）
- 復号化処理自体はSQL Serverがバックグラウンドで実行
- 並列処理時は復号化完了を最大120秒待機

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

- 暗号化解除にはサーバー管理者権限が必要
- 暗号化解除後、データファイルは平文で保存される
- 証明書とマスターキーは削除されないため、再暗号化が可能

## 備考

- Disable-DbaDbEncryptionのラッパー関数
- 証明書とマスターキーは削除されず、必要に応じて他の用途に使用可能
- 暗号化解除処理はSQL Serverがバックグラウンドで実行するため、完了まで時間がかかる場合がある
- 並列処理時は各データベースに新しい接続を作成

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Database SMO | Microsoft.SqlServer.Management.Smo | EncryptionEnabled、HasDatabaseEncryptionKeyプロパティを理解 |

**読解のコツ**: Database.EncryptionEnabledプロパティを設定することでTDEの有効/無効を切り替える。Database.Alter()で変更を適用。

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

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

**主要処理フロー**:
1. **81-88行目**: パラメータブロック定義 - CmdletBinding属性でShouldProcess、ConfirmImpact=Highを設定
2. **89-94行目**: Get-DbaDatabase経由でシステムDBを除外して対象取得
3. **96-112行目**: 順次処理ループ
  - **103行目**: 暗号化有効ならDisable-DbaDbEncryption
  - **105-107行目**: 暗号化無効なら情報出力
4. **113-189行目**: 並列処理ロジック
  - **115-189行目**: $disableScript定義（暗号化無効化、待機、DEK削除）
  - **191-198行目**: runspaceプール作成
  - **200-226行目**: タスクキューイング
  - **228-251行目**: 結果収集ループ
  - **253-254行目**: プール破棄

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Disable-DbaDbEncryption.ps1 | `public/Disable-DbaDbEncryption.ps1` | 個別データベースの暗号化無効化 |
| 3-2 | Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | データベース取得 |

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

```
Stop-DbaDbEncryption
    │
    ├─ Get-DbaDatabase
    │      └─ システムDB除外フィルター
    │
    ├─ 順次処理パス
    │      └─ foreach database
    │             └─ Disable-DbaDbEncryption
    │
    └─ 並列処理パス
           ├─ runspaceプール作成
           ├─ foreach database (並列)
           │      ├─ Connect-DbaInstance
           │      ├─ db.EncryptionEnabled = false
           │      ├─ db.Alter()
           │      ├─ 復号化完了待機 (120秒)
           │      └─ DatabaseEncryptionKey.Drop()
           └─ Disconnect-DbaInstance
```

### データフロー図

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

SqlInstance      ───┬──▶ Get-DbaDatabase ───▶ ユーザーデータベースリスト
SqlCredential    ───┘                              │
                                                   ▼
                                           {Parallel?}
                                                   │
                           ┌───────────────────────┴───────────────────────┐
                           ▼                                               ▼
                    順次処理                                         並列処理
                           │                                               │
                    foreach db                                      runspaceプール
                           │                                               │
              Disable-DbaDbEncryption                          $disableScript実行
                           │                                               │
                           ▼                                               ▼
                    [PSCustomObject] ────────────────────────────▶ パイプライン出力
                    ComputerName
                    InstanceName
                    SqlInstance
                    DatabaseName
                    EncryptionEnabled
                    Status (並列時)
                    Error (並列時)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Stop-DbaDbEncryption.ps1 | `public/Stop-DbaDbEncryption.ps1` | ソース | メイン関数 |
| Start-DbaDbEncryption.ps1 | `public/Start-DbaDbEncryption.ps1` | ソース | TDE開始関数 |
| Disable-DbaDbEncryption.ps1 | `public/Disable-DbaDbEncryption.ps1` | ソース | 個別暗号化無効化関数 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得関数 |
| Stop-DbaDbEncryption.Tests.ps1 | `tests/Stop-DbaDbEncryption.Tests.ps1` | テスト | 単体テスト |
