# 機能設計書 591-Disable-DbaDbEncryption

## 概要

本ドキュメントは、SQL ServerデータベースのTransparent Data Encryption (TDE) を無効化するPowerShellコマンドレット `Disable-DbaDbEncryption` の機能設計書である。

### 本機能の処理概要

本機能は、SQL Serverデータベースに設定されているTransparent Data Encryption (TDE) を無効化し、暗号化キーを削除するコマンドレットである。

**業務上の目的・背景**：データベースの廃止作業やTDE不要環境への移行、暗号化によるパフォーマンス問題のトラブルシューティング時に、TDE暗号化を解除する必要がある。手動でTDEを無効化する場合、暗号化状態の監視、復号完了の待機、暗号化キーの削除といった複数のステップが必要となるが、本コマンドはこれらを自動化して一括処理する。

**機能の利用シーン**：
- 本番環境から開発・テスト環境へのデータベース移行時にTDEを解除する場合
- データベースの廃止・削除前の準備作業
- TDE暗号化によるCPUオーバーヘッドを調査するためのトラブルシューティング
- 規制要件の変更に伴う暗号化方式の見直し

**主要な処理内容**：
1. SqlInstanceパラメータ使用時はGet-DbaDatabase経由で対象データベースを取得
2. 各データベースのEncryptionEnabledプロパティをfalseに設定
3. Alter()メソッドを実行して変更を適用
4. 復号処理の完了（EncryptionStateがUnencryptedになるまで）をループ監視
5. NoEncryptionKeyDropスイッチが指定されていない場合、Remove-DbaDbEncryptionKeyでDEKを削除
6. 処理結果をパイプラインに出力

**関連システム・外部連携**：SQL Server Management Objects (SMO) を使用してSQL Serverインスタンスに接続し、データベースの暗号化設定を変更する。

**権限による制御**：対象データベースに対するCONTROL DATABASE権限またはALTER DATABASE権限が必要。masterデータベースの証明書を操作する場合は追加の権限が必要となる場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio | 参照画面 | データベースプロパティのオプションページでTDE状態を確認 |
| - | PowerShellコンソール | 主画面 | コマンドの実行および結果表示 |

## 機能種別

データ更新処理 / 状態変更処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | 有効なSQL Serverインスタンス名 |
| SqlCredential | PSCredential | No | 接続用の代替資格情報 | 有効なPSCredentialオブジェクト |
| Database | string[] | No* | TDEを無効化するデータベース名 | SqlInstance使用時は必須 |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | No | Get-DbaDatabase等からのパイプライン入力 | SMO Databaseオブジェクト |
| NoEncryptionKeyDrop | switch | No | DEK削除を抑制するフラグ | - |
| EnableException | switch | No | 例外を直接スローするフラグ | - |
| WhatIf | switch | No | 実際の変更を行わずに動作を表示 | - |
| Confirm | switch | No | 変更前に確認プロンプトを表示 | - |

### 入力データソース

- SqlInstanceパラメータ：ユーザー指定のSQL Serverインスタンス名
- InputObject：Get-DbaDatabase等の他のdbatoolsコマンドからのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverが稼働するコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス識別子 |
| DatabaseName | string | TDEを無効化したデータベース名（Nameプロパティのエイリアス） |
| EncryptionEnabled | bool | TDE有効化状態（処理後はfalse） |

### 出力先

- PowerShellパイプライン：Microsoft.SqlServer.Management.Smo.Database オブジェクト（Select-DefaultViewで表示プロパティを制限）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ SqlInstance指定時にDatabaseパラメータの必須チェック
2. 対象データベース取得
   └─ SqlInstance使用時: Get-DbaDatabase経由で取得
   └─ InputObject使用時: パイプライン入力をそのまま使用
3. 各データベースに対するループ処理
   └─ ShouldProcess確認（-WhatIf/-Confirm対応）
   └─ EncryptionEnabled = $false 設定
   └─ Alter()メソッド実行
   └─ 復号完了待機ループ
       └─ 1秒間隔でリフレッシュ
       └─ EncryptionStateがUnencrypted/Noneになるまで継続
   └─ DEK削除（NoEncryptionKeyDrop未指定時）
   └─ 結果オブジェクト出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C{Database指定?}
    C -->|No| D[エラー: Database必須]
    C -->|Yes| E[Get-DbaDatabase実行]
    B -->|No| F[InputObjectを使用]
    E --> G[対象DB取得完了]
    F --> G
    G --> H{次のDBあり?}
    H -->|No| Z[終了]
    H -->|Yes| I{ShouldProcess?}
    I -->|No| H
    I -->|Yes| J[EncryptionEnabled = false]
    J --> K[Alter実行]
    K --> L[復号完了待機]
    L --> M{EncryptionState == Unencrypted?}
    M -->|No| N[1秒待機]
    N --> O[Refresh]
    O --> M
    M -->|Yes| P{NoEncryptionKeyDrop?}
    P -->|No| Q[Remove-DbaDbEncryptionKey]
    P -->|Yes| R[スキップ]
    Q --> S[結果出力]
    R --> S
    S --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | Database必須チェック | SqlInstance使用時はDatabaseパラメータが必須 | SqlInstanceパラメータ指定時 |
| BR-002 | 復号完了待機 | EncryptionStateがUnencrypted/Noneになるまで処理を待機 | 常時 |
| BR-003 | DEK自動削除 | NoEncryptionKeyDrop未指定時は暗号化キーを自動削除 | デフォルト動作 |
| BR-004 | 高影響確認 | ConfirmImpact="High"によりデフォルトで確認プロンプト表示 | インタラクティブ実行時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| TDE無効化 | sys.dm_database_encryption_keys | UPDATE（間接） | SMO経由でEncryptionEnabledを変更 |
| DEK削除 | sys.database_encryption_keys | DELETE（間接） | Remove-DbaDbEncryptionKey経由で削除 |

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

#### sys.dm_database_encryption_keys

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | encryption_state | 状態監視用に定期取得 | SMOのEncryptionStateプロパティ経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Function | SqlInstance使用時にDatabase未指定 | Databaseパラメータを指定 |
| - | Stop-Function | 処理中の予期しない例外 | エラーメッセージを確認し原因を特定 |

### リトライ仕様

復号完了待機は1秒間隔で自動的にリトライを継続する。タイムアウトは設定されていないため、大規模データベースでは長時間の待機が発生する可能性がある。

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

SMOのAlter()メソッドにより暗黙的にトランザクション管理される。復号処理自体は非同期で行われ、SQL Serverエンジンが内部的にトランザクション管理を行う。

## パフォーマンス要件

- 復号処理時間はデータベースサイズに依存
- 復号中はCPUとI/Oリソースを消費
- 大規模データベースでは数時間から数日かかる場合がある

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

- CONTROL DATABASE または ALTER DATABASE 権限が必要
- -WhatIf スイッチで事前確認を推奨
- ConfirmImpact="High" により誤操作防止の確認プロンプトがデフォルトで表示
- 復号後のデータは暗号化されていない状態となるため、他のセキュリティ対策を検討

## 備考

- TDEを完全に無効化するにはDEKの削除が必要（NoEncryptionKeyDropを使用しない場合は自動削除）
- NoEncryptionKeyDrop使用時は部分的に暗号化された状態が残る
- 復号完了まで処理がブロックされるため、大規模DBでは非同期実行を検討

---

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

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

### 推奨読解順序

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

TDE関連のSMOオブジェクト構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SMO Database | Microsoft.SqlServer.Management.Smo | EncryptionEnabled, DatabaseEncryptionKeyプロパティの関係 |

**読解のコツ**: SMO DatabaseオブジェクトのEncryptionEnabledプロパティがTDE状態を制御し、DatabaseEncryptionKeyプロパティで暗号化キーの詳細にアクセスできる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Disable-DbaDbEncryption.ps1 | `public/Disable-DbaDbEncryption.ps1` | 関数定義全体の構造 |

**主要処理フロー**:
1. **88-96行目**: パラメータ定義（CmdletBinding, パラメータ属性）
2. **97-105行目**: SqlInstance使用時のDatabase必須チェックとGet-DbaDatabase呼び出し
3. **107-139行目**: 各データベースに対するループ処理

#### Step 3: 復号処理の監視ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Disable-DbaDbEncryption.ps1 | `public/Disable-DbaDbEncryption.ps1` | 復号完了待機ループの実装 |

**主要処理フロー**:
- **116-117行目**: EncryptionEnabled = $false 設定とAlter()実行
- **118-128行目**: do-whileループによる復号完了待機
- **122-125行目**: プログレス表示とステップカウンタリセット
- **126行目**: 現在の暗号化状態をVerboseログ出力
- **128行目**: EncryptionStateがUnencrypted/None以外の間ループ継続
- **130-133行目**: DEK削除処理（Remove-DbaDbEncryptionKey呼び出し）

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

```
Disable-DbaDbEncryption
    │
    ├─ Get-DbaDatabase (SqlInstance使用時)
    │      └─ Connect-DbaInstance
    │
    ├─ SMO Database.Alter()
    │      └─ 暗号化設定の変更をサーバーに適用
    │
    ├─ Write-ProgressHelper
    │      └─ 復号進捗の表示
    │
    └─ Remove-DbaDbEncryptionKey (NoEncryptionKeyDrop未指定時)
           └─ DEK削除
```

### データフロー図

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

SqlInstance/Database ───▶ Get-DbaDatabase ───▶ SMO Database[]
        or
InputObject ───────────────────────────────────▶ SMO Database[]
                                                       │
                                                       ▼
                                              EncryptionEnabled = false
                                                       │
                                                       ▼
                                                  Alter()実行
                                                       │
                                                       ▼
                                              復号完了待機ループ
                                                       │
                                                       ▼
                                              Remove-DbaDbEncryptionKey
                                                       │
                                                       ▼
                                              Select-DefaultView
                                                       │
                                                       ▼
                                              パイプライン出力 ───▶ コンソール表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Disable-DbaDbEncryption.ps1 | `public/Disable-DbaDbEncryption.ps1` | ソース | メイン機能実装 |
| Remove-DbaDbEncryptionKey.ps1 | `public/Remove-DbaDbEncryptionKey.ps1` | ソース | DEK削除機能 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得機能 |
| Disable-DbaDbEncryption.Tests.ps1 | `tests/Disable-DbaDbEncryption.Tests.ps1` | テスト | 単体・統合テスト |
