# 通知設計書 10-Copy-DbaDbMail

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Copy-DbaDbMail` コマンドの設計仕様を記述したものである。このコマンドはDatabase Mail設定（プロファイル、アカウント、メールサーバー、設定値）を別のSQL Serverインスタンスにコピーするための機能を提供する。

### 本通知の処理概要

`Copy-DbaDbMail` は、SQL ServerのDatabase Mail設定全体をソースサーバーから宛先サーバーに移行するPowerShellコマンドである。メールプロファイル、アカウント、SMTPサーバー設定、グローバル設定値のすべてをコピーでき、サーバー移行や環境標準化に使用される。

**業務上の目的・背景**：Database Mailは自動アラート、バックアップ通知、ジョブ失敗レポート、メンテナンス通知に広く使用される。新規サーバーのセットアップ、環境間での設定標準化、ハードウェア移行時に、手作業での再設定は時間がかかりエラーが発生しやすい。このコマンドは、SMTPパスワードを含む完全なDatabase Mail設定を自動的に移行し、設定時間を大幅に削減する。

**通知の送信タイミング**：このコマンドは設定移行時に一度だけ実行される。コピーされた設定は宛先サーバーで後続のメール送信に使用される。

**通知の受信者**：該当なし（設定移行コマンド）。移行された設定を使用してメール送信が行われた場合、そのメールの受信者は移行されたプロファイル・アカウント設定に基づいて決定される。

**通知内容の概要**：移行されたコンポーネントごとにMigrationObjectを返す。このオブジェクトには、DateTime、SourceServer、DestinationServer、Name、Type、Status、Notesが含まれる。

**期待されるアクション**：移行完了後、DBAは宛先サーバーでの設定確認、テストメール送信、必要に応じたパスワード再設定などを行う。

## 通知種別

該当なし - 本コマンドはDatabase Mail設定を移行するためのコマンドであり、通知送信機能は持たない。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 該当なし（設定移行コマンド） |
| 優先度 | 該当なし |
| リトライ | 該当なし |

### 送信先決定ロジック

該当なし - このコマンドは設定移行専用であり、通知送信は行わない。

## 通知テンプレート

該当なし - 通知送信機能なし。

### メール通知の場合

該当なし

### 本文テンプレート

該当なし

### 添付ファイル

該当なし

## テンプレート変数

該当なし

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 手動実行 | ユーザーがコマンドを実行 | なし | 明示的なコマンド実行でのみ動作 |

### 送信抑止条件

該当なし（設定移行コマンド）

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B{ExcludePassword?}
    B -->|No| C[DAC接続でパスワード取得]
    B -->|Yes| D[通常接続]
    C --> E[ソースサーバー接続]
    D --> E
    E --> F[foreach: 各宛先インスタンス]
    F --> G[宛先サーバー接続]
    G --> H{Type指定?}
    H -->|Yes| I[指定タイプのみコピー]
    H -->|No| J[全コンポーネントコピー]
    I --> K[ConfigurationValues/Profiles/Accounts/MailServers]
    J --> L[Copy-DbaDbMailConfig]
    L --> M[Copy-DbaDatabaseAccount]
    M --> N[Copy-DbaDbMailProfile]
    N --> O[Copy-DbaDbMailServer]
    O --> P[Database Mail XPs有効化チェック]
    P --> Q{ソースで有効?}
    Q -->|Yes & 宛先で無効| R[Set-DbaSpConfigure: 有効化]
    Q -->|No| S[スキップ（警告出力）]
    Q -->|宛先で既に有効| T[スキップ]
    R --> U{次の宛先?}
    S --> U
    T --> U
    K --> U
    U -->|Yes| F
    U -->|No| V[DAC接続クローズ]
    V --> W[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧（ソースサーバー）

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| SMO SqlMail オブジェクト | Database Mail設定全体 | ConfigurationValues、Profiles、Accounts |
| sys.credentials | SMTPサーバー認証情報 | DAC接続でパスワード復号化 |
| msdb.dbo.sysmail_server | メールサーバーとCredentialの関連 | credential_idの参照 |

### 更新テーブル一覧（宛先サーバー）

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| msdb.dbo.sysmail_configuration | INSERT/UPDATE | 設定値のコピー |
| msdb.dbo.sysmail_account | INSERT | アカウントのコピー |
| msdb.dbo.sysmail_profile | INSERT | プロファイルのコピー |
| msdb.dbo.sysmail_server | INSERT | メールサーバーのコピー |
| sys.configurations | UPDATE | Database Mail XPs有効化 |

### コピー対象コンポーネント

| コンポーネント | 内部関数 | 説明 |
|--------------|---------|------|
| ConfigurationValues | Copy-DbaDbMailConfig | グローバル設定値 |
| Accounts | Copy-DbaDatabaseAccount | メールアカウント |
| Profiles | Copy-DbaDbMailProfile | メールプロファイル |
| MailServers | Copy-DbaDbMailServer | SMTPサーバー設定（パスワード含む） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ConnectionError | ソースまたは宛先への接続失敗 | Stop-Functionで警告出力後、処理中断 |
| MinimumVersion | SQL Server 2005未満 | Connect-DbaInstance -MinimumVersion 9で自動チェック |
| ExistingObject | 宛先に同名オブジェクトが存在 | -Force未指定時はSkipped、指定時は削除して再作成 |
| DropFailure | 既存オブジェクトの削除失敗 | Failed状態で出力、次へ継続 |
| CreateFailure | オブジェクト作成失敗 | Failed状態で出力、次へ継続 |
| PasswordDecryption | パスワード復号化失敗 | 警告出力、手動設定が必要 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

該当なし（設定移行コマンド）

### 配信時間帯

該当なし

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

- SQL Server への接続には Windows認証、SQL Server認証、Active Directory認証がサポートされる
- パスワード取得にはDAC（専用管理者接続）が必要
- sysadmin権限が必要
- パスワードはPowerShellリモート処理で復号化される
- -ExcludePasswordでパスワードなしのコピーが可能
- ShouldProcess（-WhatIf, -Confirm）をサポート
- -Forceで既存オブジェクトの上書きが可能

## 備考

- SQL Server 2005以上が必要（MinimumVersion 9）
- 完全なDatabase Mail移行には4つの内部関数を使用
- パスワード取得にはDAC接続が必要（ExcludePassword未指定時）
- SMOのScript()メソッドを使用してオブジェクトをT-SQLとしてスクリプト化
- ソースサーバー名を宛先サーバー名に置換して実行
- Database Mail XPsの有効化状態も同期可能

---

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

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

### 推奨読解順序

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

出力されるMigrationObjectの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行73-86: .OUTPUTSセクションで返却されるオブジェクト型とプロパティを確認 |

**読解のコツ**: PSCustomObject（MigrationObject型）を返す。DateTime、SourceServer、DestinationServer、Name、Type、Status、Notesが主要プロパティ。Statusは「Successful」「Skipped」「Failed」のいずれか。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行111-126: パラメータ定義。Source、SourceSqlCredential、Destination、DestinationSqlCredential、Credential、Type、ExcludePassword、Force、EnableException |

**主要処理フロー**:
1. **行127-416**: beginブロックで内部関数を定義
2. **行387-416**: ソースサーバー接続（DAC or 通常）
3. **行417-524**: processブロックで各宛先へのコピー実行
4. **行526-530**: endブロックでDAC接続クローズ

#### Step 3: 内部関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行129-159: Copy-DbaDbMailConfig - 設定値のコピー |
| 3-2 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行161-227: Copy-DbaDatabaseAccount - アカウントのコピー |
| 3-3 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行229-298: Copy-DbaDbMailProfile - プロファイルのコピー |
| 3-4 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行300-385: Copy-DbaDbMailServer - メールサーバーのコピー |

**主要処理フロー**:
- 各関数でShouldProcess確認後、Script()でT-SQL生成
- ソースサーバー名を宛先サーバー名に正規表現で置換
- 宛先で$destServer.Query()実行
- 結果をMigrationObjectとして出力

#### Step 4: パスワード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行305-312: パスワード取得のためのCredential情報取得 |
| 4-2 | Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | 行360-371: パスワードの復号化と置換 |

**主要処理フロー**:
- **行307-308**: sys.credentialsとmsdb.dbo.sysmail_serverをJOINしてCredential情報取得
- **行310**: Get-DecryptedObjectでパスワード復号化
- **行361-366**: 復号化されたパスワードでScript内の空パスワードを置換

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

```
Copy-DbaDbMail
    │
    ├─ begin ブロック
    │      │
    │      ├─ Copy-DbaDbMailConfig (内部関数定義)
    │      │      └─ $mail.ConfigurationValues.Script()
    │      │
    │      ├─ Copy-DbaDatabaseAccount (内部関数定義)
    │      │      └─ $account.Script()
    │      │
    │      ├─ Copy-DbaDbMailProfile (内部関数定義)
    │      │      └─ $profile.Script()
    │      │
    │      ├─ Copy-DbaDbMailServer (内部関数定義)
    │      │      ├─ Get-DecryptedObject (パスワード復号化)
    │      │      └─ $mailServer.Script()
    │      │
    │      └─ ソースサーバー接続
    │             ├─ Connect-DbaInstance (DAC or 通常)
    │             └─ $sourceServer.mail 取得
    │
    ├─ process ブロック (foreach 宛先)
    │      │
    │      ├─ Connect-DbaInstance (宛先接続)
    │      │
    │      ├─ Type指定時: 指定コンポーネントのみコピー
    │      │
    │      └─ Type未指定時: 全コンポーネントコピー
    │             ├─ Copy-DbaDbMailConfig
    │             ├─ Copy-DbaDatabaseAccount
    │             ├─ Copy-DbaDbMailProfile
    │             ├─ Copy-DbaDbMailServer
    │             └─ Database Mail XPs 有効化チェック
    │                    ├─ Get-DbaSpConfigure
    │                    └─ Set-DbaSpConfigure
    │
    └─ end ブロック
           └─ Disconnect-DbaInstance (DAC接続クローズ)
```

### データフロー図

```
[ソース]                      [処理]                         [宛先]

$sourceServer.Mail   ───▶  ConfigurationValues.Script() ───▶  $destServer.Query()
                                     │
$sourceServer.Mail.  ───▶  Account.Script()             ───▶  $destServer.Query()
  Accounts                           │
                                     │
$sourceServer.Mail.  ───▶  Profile.Script()             ───▶  $destServer.Query()
  Profiles                           │
                                     │
$sourceServer.Mail.  ───▶  MailServer.Script()          ───▶  $destServer.Query()
  Accounts.MailServers               │
                     ├── Get-DecryptedObject (パスワード復号化)
                     └── 置換: ソース名 → 宛先名

Get-DbaSpConfigure   ───▶  比較: Database Mail XPs      ───▶  Set-DbaSpConfigure
                                                               (有効化)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaDbMail.ps1 | `public/Copy-DbaDbMail.ps1` | ソース | メインコマンド実装 |
| Copy-DbaDbMail.Tests.ps1 | `tests/Copy-DbaDbMail.Tests.ps1` | テスト | Pesterユニットテスト |
| Get-DbaDbMail.ps1 | `public/Get-DbaDbMail.ps1` | ソース | 関連: Database Mail設定取得 |
| Get-DbaDbMailProfile.ps1 | `public/Get-DbaDbMailProfile.ps1` | ソース | 関連: プロファイル取得 |
| Get-DbaDbMailAccount.ps1 | `public/Get-DbaDbMailAccount.ps1` | ソース | 関連: アカウント取得 |
| Get-DbaDbMailServer.ps1 | `public/Get-DbaDbMailServer.ps1` | ソース | 関連: メールサーバー取得 |
| Get-DbaDbMailConfig.ps1 | `public/Get-DbaDbMailConfig.ps1` | ソース | 関連: 設定値取得 |
| Get-DbaSpConfigure.ps1 | `public/Get-DbaSpConfigure.ps1` | ソース | 依存: sp_configure値取得 |
| Set-DbaSpConfigure.ps1 | `public/Set-DbaSpConfigure.ps1` | ソース | 依存: sp_configure値設定 |
