# 機能設計書 474-Copy-DbaAgentAlert

## 概要

本ドキュメントは、SQL Server Agentのアラートをソースインスタンスから宛先インスタンスにコピーするPowerShellコマンド「Copy-DbaAgentAlert」の機能設計書である。

### 本機能の処理概要

Copy-DbaAgentAlertは、SQL Server Agentのアラート設定をソースインスタンスから1つ以上の宛先インスタンスに移行する機能である。アラートの構成、通知設定、およびジョブの関連付けを含めて自動的に転送する。

**業務上の目的・背景**：サーバー移行、災害復旧準備、または複数のSQL Server環境間での監視標準化において、アラート設定の手動再作成は時間がかかりエラーが発生しやすい。本機能を使用することで、複雑な通知チェーンを含む数十のアラートを効率的に移行でき、アラートとオペレーター、ジョブ間の依存関係も自動的に処理される。

**機能の利用シーン**：
- 本番サーバーから災害復旧サーバーへのアラート構成の複製
- 新規サーバー構築時の標準アラート設定の展開
- サーバー統合・移行プロジェクトでのアラート移行
- 複数環境間でのアラート設定の標準化

**主要な処理内容**：
1. ソースサーバーへの接続とアラート一覧の取得
2. 宛先サーバーへの接続
3. アラートデフォルト設定のコピー（IncludeDefaults指定時）
4. 各アラートの依存関係チェック（オペレーター、ジョブの存在確認）
5. 既存アラートとの競合チェック
6. SMOスクリプトによるアラートの作成
7. ジョブ関連付けの復元
8. 通知設定の復元

**関連システム・外部連携**：SQL Server Agentサービス、msdbデータベース、オペレーター設定、ジョブ設定との連携。

**権限による制御**：ソースおよび宛先の両方でsysadmin固定サーバーロールのメンバーシップが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SQL Server Management Studio - SQL Server Agent - Alerts | 参照画面 | アラート設定の確認 |

## 機能種別

データ移行処理 / SMOスクリプティング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | コピー元SQL Serverインスタンス | SQL Server 2000以上 |
| SourceSqlCredential | PSCredential | No | ソース接続用の資格情報 | - |
| Destination | DbaInstanceParameter[] | Yes | コピー先SQL Serverインスタンス（複数可） | SQL Server 2000以上 |
| DestinationSqlCredential | PSCredential | No | 宛先接続用の資格情報 | - |
| Alert | object[] | No | コピーするアラート名 | - |
| ExcludeAlert | object[] | No | 除外するアラート名 | - |
| IncludeDefaults | switch | No | アラートデフォルト設定もコピー | - |
| Force | switch | No | 既存アラートを削除して再作成 | - |
| WhatIf | switch | No | 実行内容のプレビュー | - |
| Confirm | switch | No | 実行前の確認プロンプト | - |
| EnableException | switch | No | 例外をスローするかどうか | - |

### 入力データソース

- ソースSQL ServerのJobServer.Alertsコレクション
- ソースSQL ServerのJobServer.AlertSystem（デフォルト設定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SourceServer | string | ソースSQL Serverインスタンス名 |
| DestinationServer | string | 宛先SQL Serverインスタンス名 |
| Name | string | アラート名または設定項目名 |
| Type | string | オブジェクトタイプ（Agent Alert, Agent Alert Job Association, Agent Alert Notification, Alert Defaults） |
| Status | string | 処理結果（Successful, Failed, Skipped） |
| Notes | string | 追加情報（スキップ理由、エラー詳細など） |
| DateTime | DbaDateTime | 処理実行日時 |

### 出力先

パイプライン出力（PSCustomObject - MigrationObject）

## 処理フロー

### 処理シーケンス

```
1. ソースサーバー接続（begin）
   └─ Connect-DbaInstanceでソースに接続し、アラート一覧を取得
2. 宛先サーバー接続（process）
   └─ 各宛先インスタンスにConnect-DbaInstanceで接続
3. アラートデフォルトのコピー（IncludeDefaults時）
   └─ AlertSystem.Script()でスクリプト生成し実行
4. 各アラートの処理（foreach serverAlert）
   ├─ フィルタリング（Alert/ExcludeAlertパラメータ）
   ├─ 通知用オペレーターの存在確認
   ├─ 既存アラートの存在確認と競合チェック
   ├─ ジョブ依存関係の確認
   ├─ アラートの作成（Script()とQuery実行）
   ├─ ジョブ関連付けの復元
   └─ 通知設定の復元
5. 結果出力
   └─ 各操作ごとにMigrationObjectを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C{接続成功?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[アラート一覧取得]
    E --> F[foreach 宛先インスタンス]
    F --> G[宛先サーバー接続]
    G --> H{IncludeDefaults?}
    H -->|Yes| I[アラートデフォルトをコピー]
    H -->|No| J[foreach アラート]
    I --> J
    J --> K{Alert/ExcludeAlertでフィルタ}
    K -->|除外| L[次のアラートへ]
    K -->|対象| M{通知オペレーター存在?}
    M -->|No| N[Skipped: オペレーター不足]
    M -->|Yes| O{宛先に既存?}
    O -->|Yes| P{Force指定?}
    P -->|No| Q[Skipped: 既に存在]
    P -->|Yes| R[既存アラートを削除]
    O -->|No| S{競合チェック}
    R --> S
    S -->|競合あり| T[Skipped: 競合]
    S -->|競合なし| U{ジョブ依存確認}
    U -->|依存ジョブなし| V[Skipped: ジョブなし]
    U -->|OK| W[アラート作成]
    W --> X{ジョブ関連付け?}
    X -->|Yes| Y[ジョブ関連付け復元]
    X -->|No| Z[通知設定復元]
    Y --> Z
    Z --> L
    N --> L
    Q --> L
    T --> L
    V --> L
    L --> J
    J --> F
    F --> AA[終了]
    D --> AA
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | オペレーター依存 | アラートに設定されているオペレーターが宛先に存在しない場合はスキップ | アラートに通知設定がある場合 |
| BR-002 | ジョブ依存 | アラート応答として設定されているジョブが宛先に存在しない場合はスキップ | アラートにジョブ関連付けがある場合 |
| BR-003 | 競合検出 | 同一のSeverity、MessageID、DatabaseName、EventDescriptionKeywordの組み合わせを持つアラートが既に存在する場合はスキップ | 常時 |
| BR-004 | Force動作 | Forceが指定された場合、既存アラートを削除して再作成 | 宛先に同名アラートが存在する場合 |
| BR-005 | ジョブID置換 | アラートスクリプト内のジョブIDは一旦ゼロに置換し、作成後に正しいジョブIDで更新 | ジョブ関連付けがある場合 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| アラート削除 | msdb.dbo.sysalerts | DELETE | sp_delete_alertにより削除 |
| アラート作成 | msdb.dbo.sysalerts | INSERT | sp_add_alertにより作成 |
| アラート更新 | msdb.dbo.sysalerts | UPDATE | sp_update_alertによりジョブ関連付け |
| 通知追加 | msdb.dbo.sysnotifications | INSERT | AddNotificationメソッドにより作成 |
| デフォルト設定 | msdb.dbo.sysmail_configuration | UPDATE | AlertSystem.Script()により更新 |

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

#### msdb.dbo.sysalerts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, severity, message_id, database_name, etc. | ソースアラートの設定値 | SMO Script()で生成 |
| UPDATE | job_id | 宛先ジョブのjob_id | sp_update_alertで更新 |
| DELETE | - | WHERE name = @alertname | sp_delete_alertで削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | ソースまたは宛先に接続できない | Stop-Functionで処理を中断 |
| OperatorMissing | オペレーター不足 | 通知先オペレーターが宛先に存在しない | Skippedとして記録し次のアラートへ |
| JobMissing | ジョブ不足 | 応答ジョブが宛先に存在しない | Skippedとして記録し次のアラートへ |
| AlertConflict | アラート競合 | 同一条件のアラートが既に存在 | Skippedとして記録し次のアラートへ |
| ScriptError | スクリプトエラー | アラート作成スクリプトの実行に失敗 | Failedとして記録し次のアラートへ |

### リトライ仕様

リトライ処理は実装されていない。エラー発生時は次のアラートの処理に移行する。

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

個々のアラート作成操作は独立したトランザクションとして実行される。一括トランザクションは使用されない。

## パフォーマンス要件

特になし。アラート数に比例して処理時間が増加するが、通常は数秒から数分程度。

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

- ソースおよび宛先の両方でsysadmin権限が必要
- SQL認証使用時は資格情報がSecureStringとして管理される
- WhatIfパラメータによる事前確認が可能

## 備考

- アラートの通知チェーン（Email、Pager、NetSend）はすべて復元される
- FailSafeOperatorやForwardingServerなどのアラートデフォルト設定は-IncludeDefaultsで別途コピー可能
- ジョブ関連付けがある場合は、先にCopy-DbaAgentJobでジョブを移行しておく必要がある

---

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

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

### 推奨読解順序

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

SMOのAlertオブジェクトの構造と、関連するオペレーター・ジョブとの依存関係を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaAgentAlert.ps1 | `public/Copy-DbaAgentAlert.ps1` | 118行目で$sourceServer.JobServer.Alertsを取得 |

**読解のコツ**: Alertオブジェクトは.HasNotification、.EnumNotifications()、.JobId、.JobNameプロパティで通知とジョブ情報にアクセスできる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaAgentAlert.ps1 | `public/Copy-DbaAgentAlert.ps1` | 101-114行目のパラメータ定義、115-124行目のbeginブロック |

**主要処理フロー**:
1. **115-124行目**: beginブロックでソース接続とアラート一覧取得
2. **125-161行目**: アラートデフォルトのコピー処理（IncludeDefaults時）
3. **165-178行目**: アラートごとの状態オブジェクト作成
4. **180-195行目**: 通知オペレーターの存在確認
5. **197-222行目**: 既存アラートの確認とForce処理
6. **224-247行目**: 競合チェックとジョブ依存確認
7. **249-265行目**: アラート作成スクリプト実行
8. **275-306行目**: ジョブ関連付けの復元
9. **308-347行目**: 通知設定の復元

#### Step 3: 依存関係チェックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaAgentAlert.ps1 | `public/Copy-DbaAgentAlert.ps1` | 180-195行目のオペレーター確認ロジック |

**主要処理フロー**:
- **180行目**: HasNotificationプロパティで通知有無を確認
- **181行目**: EnumNotifications()で通知詳細を取得
- **182-184行目**: 宛先オペレーターと比較し、不足を検出
- **240-247行目**: JobNameが設定されている場合、宛先ジョブの存在を確認

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

```
Copy-DbaAgentAlert
    │
    ├─ Connect-DbaInstance（Source）
    │      └─ ソースサーバー接続
    │
    ├─ $sourceServer.JobServer.Alerts
    │      └─ アラート一覧取得
    │
    ├─ Connect-DbaInstance（Destination）
    │      └─ 宛先サーバー接続
    │
    ├─ AlertSystem.Script()（IncludeDefaults時）
    │      └─ デフォルト設定スクリプト生成
    │
    ├─ $serverAlert.EnumNotifications()
    │      └─ 通知設定一覧取得
    │
    ├─ $serverAlert.Script()
    │      └─ アラート作成スクリプト生成
    │
    ├─ $destServer.Query()
    │      └─ T-SQL実行（sp_add_alert, sp_update_alert, sp_delete_alert）
    │
    └─ $newAlert.AddNotification()
           └─ 通知設定の追加
```

### データフロー図

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

Source           ───▶ Connect-DbaInstance ───▶ $sourceServer
                                │
                                ▼
$sourceServer.JobServer.Alerts ───▶ アラート一覧
                                │
Destination      ───▶ Connect-DbaInstance ───▶ $destServer
                                │
                                ▼
各アラート ───▶ 依存関係チェック ───▶ スキップ or 続行
                    │
                    ▼
           Script()でT-SQL生成 ───▶ Query()で実行
                    │
                    ▼
           ジョブ関連付け復元 ───▶ sp_update_alert
                    │
                    ▼
           通知設定復元 ───▶ AddNotification()
                    │
                    ▼
                [MigrationObject出力]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaAgentAlert.ps1 | `public/Copy-DbaAgentAlert.ps1` | ソース | メイン処理ロジック |
| Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | ソース | 前提となるオペレーターコピー |
| Copy-DbaAgentJob.ps1 | `public/Copy-DbaAgentJob.ps1` | ソース | 前提となるジョブコピー |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続用コマンド |
