# 機能設計書 478-Copy-DbaAgentOperator

## 概要

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

### 本機能の処理概要

Copy-DbaAgentOperatorは、SQL Server Agentのオペレーター設定をソースインスタンスから1つ以上の宛先インスタンスにコピーする機能である。メールアドレス、ポケベル番号、通知スケジュールなどのオペレータープロパティを含めて移行する。

**業務上の目的・背景**：サーバー移行、環境標準化、または災害復旧準備において、オペレーター設定の手動再作成は時間がかかる。オペレーターはアラートやジョブの通知先として重要な役割を果たすため、正確な移行が不可欠である。本機能を使用することで、複数のSQL Serverインスタンス間で一貫した通知設定を維持できる。

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

**主要な処理内容**：
1. ソースサーバーへの接続とオペレーター一覧の取得
2. 宛先サーバーへの接続
3. 各オペレーターの処理
4. 既存オペレーターとの重複チェック（フェイルセーフオペレーター保護含む）
5. SMOスクリプトによるオペレーターの作成
6. 処理結果の出力

**関連システム・外部連携**：SQL Server Agentサービス、msdbデータベース、Database Mail。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SQL Server Management Studio - SQL Server Agent - Operators | 参照画面 | オペレーター設定の確認 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- ソースSQL ServerのJobServer.Operatorsコレクション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DateTime | DbaDateTime | 処理実行日時 |
| SourceServer | string | ソースSQL Serverインスタンス名 |
| DestinationServer | string | 宛先SQL Serverインスタンス名 |
| Name | string | オペレーター名 |
| Type | string | オブジェクトタイプ（Agent Operator） |
| Status | string | 処理結果（Successful, Failed, Skipped） |
| Notes | string | 追加情報（スキップ理由など） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. ソースサーバー接続（begin）
   └─ Connect-DbaInstanceでソースに接続し、オペレーター一覧を取得
2. 宛先サーバー接続（process）
   └─ 各宛先インスタンスにConnect-DbaInstanceで接続
3. フェイルセーフオペレーターの確認
   └─ $destServer.JobServer.AlertSystem.FailSafeOperatorを取得
4. 各オペレーターの処理（foreach sOperator）
   ├─ フィルタリング（Operator/ExcludeOperatorパラメータ）
   ├─ 既存オペレーターの確認
   │   ├─ 既存でForceなし: スキップ
   │   ├─ フェイルセーフオペレーター: 常にスキップ
   │   └─ 既存でForceあり: 削除して再作成
   └─ Script()でオペレーター作成
5. 結果出力
   └─ 各操作ごとにMigrationObjectを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C{接続成功?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[オペレーター一覧取得]
    E --> F[foreach 宛先インスタンス]
    F --> G[宛先サーバー接続]
    G --> H[フェイルセーフオペレーター確認]
    H --> I[foreach オペレーター]
    I --> J{Operator/ExcludeOperatorでフィルタ}
    J -->|除外| K[次のオペレーターへ]
    J -->|対象| L{宛先に既存?}
    L -->|Yes| M{Force指定?}
    M -->|No| N[Skipped: 既に存在]
    M -->|Yes| O{フェイルセーフ?}
    O -->|Yes| P[スキップ: フェイルセーフ]
    O -->|No| Q[既存オペレーター削除]
    L -->|No| R[オペレーター作成]
    Q --> R
    R --> S{作成成功?}
    S -->|Yes| T[Successful]
    S -->|No| U[Failed]
    N --> K
    P --> K
    T --> K
    U --> K
    K --> I
    I --> F
    F --> V[終了]
    D --> V
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | フェイルセーフオペレーター保護 | フェイルセーフオペレーターはForce指定時も削除されない | 常時 |
| BR-002 | Force動作 | Forceが指定された場合、既存オペレーターを削除して再作成（フェイルセーフ除く） | 宛先に同名オペレーターが存在する場合 |
| BR-003 | 全プロパティ保持 | メールアドレス、ポケベル番号、通知スケジュール等すべてのプロパティがコピーされる | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| オペレーター削除 | msdb.dbo.sysoperators | DELETE | SMO Drop()により削除 |
| オペレーター作成 | msdb.dbo.sysoperators | INSERT | SMO Script()で生成したT-SQLを実行 |

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

#### msdb.dbo.sysoperators

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, email_address, pager_address, etc. | ソースオペレーターの設定値 | SMO Script()で生成 |
| DELETE | - | WHERE name = @operatorName | SMO Drop()で削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | ソースまたは宛先に接続できない | Stop-Functionで処理を中断 |
| DropError | 削除エラー | 既存オペレーターの削除に失敗 | Failedとして記録し次のオペレーターへ |
| CreateError | 作成エラー | オペレーターの作成に失敗 | Failedとして記録し次のオペレーターへ |

### リトライ仕様

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

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

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

## パフォーマンス要件

特になし。オペレーター数に比例して処理時間が増加するが、通常は数秒程度。

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

- ソースおよび宛先の両方でsysadmin権限が必要
- SQL認証使用時は資格情報がSecureStringとして管理される
- フェイルセーフオペレーターは保護されているため、誤って削除されることはない
- WhatIfパラメータによる事前確認が可能

## 備考

- オペレーターはアラートやジョブの通知先として使用される
- アラート移行前にオペレーターを移行する必要がある
- フェイルセーフオペレーターはSQL Serverの障害通知に使用される重要な設定

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: Operatorオブジェクトは.Name、.EmailAddress、.PagerAddress等のプロパティを持ち、Script()メソッドでT-SQLを生成できる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 97-111行目のパラメータ定義、113-123行目のbeginブロック |

**主要処理フロー**:
1. **113-123行目**: beginブロックでソース接続とオペレーター取得
2. **133-134行目**: 宛先オペレーターとフェイルセーフオペレーターの取得
3. **135-150行目**: フィルタリングと既存確認
4. **152-165行目**: Force時のフェイルセーフ確認と削除処理
5. **181-196行目**: Script()でオペレーター作成

#### Step 3: フェイルセーフオペレーター保護を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 134行目と162-165行目のフェイルセーフ処理 |

**主要処理フロー**:
- **134行目**: $destServer.JobServer.AlertSystem.FailSafeOperatorでフェイルセーフを取得
- **162-165行目**: フェイルセーフオペレーターの場合はcontinueでスキップ

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

```
Copy-DbaAgentOperator
    │
    ├─ Connect-DbaInstance（Source）
    │      └─ ソースサーバー接続
    │
    ├─ $sourceServer.JobServer.Operators
    │      └─ オペレーター一覧取得
    │
    ├─ Connect-DbaInstance（Destination）
    │      └─ 宛先サーバー接続
    │
    ├─ $destServer.JobServer.AlertSystem
    │      └─ フェイルセーフオペレーター取得
    │
    ├─ $destServer.JobServer.Operators[$operatorName].Drop()
    │      └─ 既存オペレーターの削除（Force時）
    │
    ├─ $sOperator.Script()
    │      └─ オペレーター作成スクリプト生成
    │
    └─ $destServer.Query()
           └─ T-SQL実行（sp_add_operator）
```

### データフロー図

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

Source           ───▶ Connect-DbaInstance ───▶ $sourceServer
                                │
                                ▼
$sourceServer.JobServer.Operators ───▶ オペレーター一覧
                                │
Destination      ───▶ Connect-DbaInstance ───▶ $destServer
                                │
                                ▼
$destServer.JobServer.AlertSystem ───▶ フェイルセーフ確認
                                │
                                ▼
各オペレーター ───▶ 既存確認/フェイルセーフ確認 ───▶ スキップ or 続行
                    │
                    ▼
           Script()でT-SQL生成 ───▶ Query()で実行
                    │
                    ▼
                [MigrationObject出力]
```

### 関連ファイル一覧

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