# 通知設計書 26-Copy-DbaAgentOperator

## 概要

本ドキュメントは、SQL Server Agentオペレーターを別のインスタンスにコピーするPowerShellコマンド `Copy-DbaAgentOperator` の通知設計書です。

### 本通知の処理概要

`Copy-DbaAgentOperator` は、ソースSQL Serverインスタンスから1つ以上の宛先インスタンスにSQL Server Agentオペレーターをコピーするコマンドです。メールアドレス、ページャー番号、通知スケジュールなど、すべてのオペレータープロパティを保持してコピーされます。

**業務上の目的・背景**：サーバー移行、環境の標準化、複数インスタンス間での一貫したアラート構成のセットアップにおいて、オペレーター設定を手動で再作成する代わりにスクリプトによる正確な複製を実現します。各オペレーターはソースからSMOを使用してスクリプト化され、宛先で再作成されるため、すべての構成詳細が保持されます。

**通知の送信タイミング**：このコマンドはオペレーターをコピーする機能であり、コピー時に通知は送信されません。各オペレーターのコピー処理完了後、マイグレーションステータスを含むMigrationObject（PSCustomObject）が即座にパイプラインに出力されます。

**通知の受信者**：コマンド実行者がPowerShellコンソールまたはスクリプトの出力を通じて結果を受信します。

**通知内容の概要**：出力には以下の情報が含まれます：日時、ソースサーバー名、宛先サーバー名、オペレーター名、タイプ（常に"Agent Operator"）、ステータス（Successful/Skipped/Failed）、備考（スキップ理由等）。

**期待されるアクション**：コマンド実行者は出力結果を確認し、失敗またはスキップされたオペレーターについては原因を調査して対処することが期待されます。-Forceオプションを使用して既存オペレーターを上書きするか、宛先で個別に設定を調整します。

## 通知種別

コンソール出力 / パイプライン出力（MigrationObject / PSCustomObject）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（各オペレーター処理完了時にパイプライン出力） |
| 優先度 | 中 |
| リトライ | 無（-Forceパラメータで既存の削除・再作成が可能） |

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

コマンド実行者のPowerShellセッションに直接出力されます。各オペレーターの処理完了後、MigrationObjectがSelect-DefaultViewを通じて出力されます。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力形式 | MigrationObject（PSCustomObject） |
| デフォルト表示プロパティ | DateTime, SourceServer, DestinationServer, Name, Type, Status, Notes |

### 出力オブジェクト構造

```powershell
[PSCustomObject]@{
    SourceServer      = "ソースサーバー名"
    DestinationServer = "宛先サーバー名"
    Name              = "オペレーター名"
    Type              = "Agent Operator"
    Status            = "Successful" / "Skipped" / "Failed"
    Notes             = "Already exists on destination" 等
    DateTime          = [DbaDateTime](Get-Date)
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| SourceServer | ソースサーバー名 | $sourceServer.Name | Yes |
| DestinationServer | 宛先サーバー名 | $destServer.Name | Yes |
| Name | オペレーター名 | $sOperator.Name | Yes |
| Type | オブジェクトタイプ | 固定値 "Agent Operator" | Yes |
| Status | 処理結果ステータス | 処理結果から動的に設定 | Yes |
| Notes | 備考・詳細情報 | 処理状況から動的に設定 | No |
| DateTime | 処理日時 | Get-Date | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コマンド実行 | Copy-DbaAgentOperator実行 | 各オペレーター処理完了時 | コピー処理の結果を出力 |
| 複数宛先 | Destination配列のループ | 各宛先への処理完了時 | 宛先ごとに結果を出力 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Operatorフィルタ不一致 | -Operatorパラメータで指定した名前に一致しない場合（処理スキップ） |
| ExcludeOperator一致 | -ExcludeOperatorパラメータで指定した名前に一致した場合（処理スキップ） |
| WhatIf指定時 | -WhatIfパラメータ指定時は実際のコピーは行わない |
| Confirm拒否時 | -Confirmで確認を求められた際にユーザーが拒否した場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[beginブロック]
    B --> C[ソースサーバー接続]
    C --> D{接続成功?}
    D -->|No| E[Stop-Function + Return]
    D -->|Yes| F[ソースオペレーター取得]
    F --> G[processブロック開始]
    G --> H{宛先ループ}
    H --> I[宛先サーバー接続]
    I --> J{接続成功?}
    J -->|No| K[Stop-Function + Continue]
    J -->|Yes| L[宛先オペレーター取得]
    L --> M[フェールセーフオペレーター取得]
    M --> N{各ソースオペレーターをループ}
    N --> O{Operator/ExcludeOperatorフィルタ}
    O -->|除外| N
    O -->|対象| P{宛先に既存?}
    P -->|Yes & Force=false| Q[Status=Skipped, Notes=Already exists]
    P -->|Yes & Force=true| R{フェールセーフ?}
    R -->|Yes| S[スキップ]
    R -->|No| T[既存をDrop]
    P -->|No| U[コピー処理]
    T --> U
    U --> V[Script()でSQL生成]
    V --> W[宛先でQuery実行]
    W --> X{成功?}
    X -->|Yes| Y[Status=Successful]
    X -->|No| Z[Status=Failed]
    Q --> AA[MigrationObject出力]
    Y --> AA
    Z --> AA
    AA --> N
    S --> N
    N -->|完了| H
    H -->|完了| AB[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| msdb.dbo.sysoperators（ソース） | コピー元オペレーター情報の取得 | SMO経由でアクセス |
| msdb.dbo.sysoperators（宛先） | 既存オペレーター確認 | SMO経由でアクセス |
| msdb.dbo.sysalerts_view（宛先） | フェールセーフオペレーター確認 | AlertSystem経由 |

### テーブル別参照項目詳細

#### msdb.dbo.sysoperators（ソース）

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| 全カラム | Script()メソッドでSQL生成 | 全オペレーター対象 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| msdb.dbo.sysoperators（宛先） | DELETE | Force時の既存オペレーター削除 |
| msdb.dbo.sysoperators（宛先） | INSERT | 新規オペレーターの作成（Script実行） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ソース接続エラー | ソースSQL Serverインスタンスに接続できない | 接続情報を確認し再試行 |
| 宛先接続エラー | 宛先SQL Serverインスタンスに接続できない | 接続情報を確認（他の宛先は継続処理） |
| 既存オペレーター | 同名オペレーターが宛先に存在 | -Forceを使用するか手動で対処 |
| Drop失敗 | Force時の削除処理失敗 | エラーメッセージを確認し原因対処 |
| コピー失敗 | Script実行失敗 | エラーメッセージを確認し原因対処 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（-Forceで既存削除・再作成が可能） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（任意のタイミングで実行可能）

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

- ソースおよび宛先SQL Serverインスタンスへのsysadmin権限が必要
- SourceSqlCredential/DestinationSqlCredentialパラメータを使用して安全に認証情報を渡すことが可能
- SupportsShouldProcessが有効で、ConfirmImpactはMediumに設定
- フェールセーフオペレーターは強制削除から保護される
- Script()メソッドでSQL生成するため、オペレーターの全設定が正確に複製される

## 備考

- Script()メソッドを使用してオペレーターの構成をSQLスクリプトとして取得し、宛先で実行
- -Forceパラメータを使用すると、既存オペレーターを削除して再作成（ただしフェールセーフオペレーターは保護）
- 複数の宛先インスタンスを指定可能（Destination配列）
- 宛先での処理後、JobServer.Operators.Refresh()を呼び出してコレクションを更新
- MigrationObjectはSelect-DefaultViewでTypeNameを"MigrationObject"に設定

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 65-79行目の.OUTPUTSセクションで出力構造を確認 |
| 1-2 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 138-146行目でMigrationObject構造を確認 |

**読解のコツ**: MigrationObjectはコピー操作の結果を表す汎用的な形式で、Select-DefaultViewを通じてTypeName "MigrationObject"が設定されます。

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

処理の起点となるfunction定義とパラメータを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 97-111行目でパラメータ定義を確認 |

**主要処理フロー**:
1. **113-122行目**: beginブロックでソース接続とオペレーター取得
2. **123行目**: Forceパラメータ時のConfirmPreference設定
3. **124行目**: processブロック開始

#### Step 3: ソース接続とオペレーター取得を理解する

beginブロックでのソースサーバー接続とオペレーター取得ロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 113-120行目でソース接続を確認 |

**主要処理フロー**:
- **114-118行目**: Connect-DbaInstance呼び出しとエラーハンドリング
- **120行目**: $sourceServer.JobServer.Operatorsでオペレーター取得

#### Step 4: 宛先処理とコピーロジックを理解する

processブロックでの宛先接続、フィルタリング、コピー処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | 125-199行目で宛先処理を確認 |

**主要処理フロー**:
- **126-131行目**: 宛先サーバー接続
- **133-134行目**: 宛先オペレーターとフェールセーフ取得
- **148-150行目**: Operator/ExcludeOperatorフィルタリング
- **152-178行目**: 既存オペレーター処理（Force時のDrop含む）
- **181-196行目**: Script()でSQL生成して宛先で実行

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

```
Copy-DbaAgentOperator
    |
    +-- [beginブロック]
    |       +-- Connect-DbaInstance (ソース)
    |       +-- $sourceServer.JobServer.Operators
    |       +-- Force時のConfirmPreference設定
    |
    +-- [processブロック]
            +-- Test-FunctionInterrupt
            +-- foreach ($destinstance in $Destination)
                    |
                    +-- Connect-DbaInstance (宛先)
                    +-- $destServer.JobServer.Operators
                    +-- $destServer.JobServer.AlertSystem.FailSafeOperator
                    |
                    +-- foreach ($sOperator in $serverOperator)
                            |
                            +-- Operator/ExcludeOperatorフィルタ
                            |
                            +-- 既存チェック
                            |       +-- Force=false → Status=Skipped
                            |       +-- Force=true & FailSafe → Skip
                            |       +-- Force=true → Drop()
                            |
                            +-- $sOperator.Script() → SQL生成
                            +-- $destServer.Query($sql)
                            +-- Refresh()
                            |
                            +-- Select-DefaultView → MigrationObject出力
```

### データフロー図

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

Source ────────────────────────> Connect-DbaInstance ─────┐
SourceSqlCredential ────────────────────────────────────────┤
                                                           |
                                                           v
                                              $sourceServer.JobServer.Operators
                                                           |
Destination[] ─────────────────> Connect-DbaInstance ─────┤
DestinationSqlCredential ───────────────────────────────────┤
                                                           |
Operator[] ─────────────────────────────────────> フィルタリング
ExcludeOperator[] ──────────────────────────────────────────┤
                                                           |
                                                           v
                                              既存チェック + Force処理
                                                           |
Force ─────────────────────────────────────────────────────┤
                                                           |
                                                           v
                                              $sOperator.Script()
                                                           |
                                                           v
                                              $destServer.Query($sql)
                                                           |
                                                           v
                                              MigrationObject ───> パイプライン出力
                                              - DateTime
                                              - SourceServer
                                              - DestinationServer
                                              - Name
                                              - Type
                                              - Status
                                              - Notes
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | ソース | オペレーターコピーの本体 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Test-FunctionInterrupt.ps1 | `internal/functions/Test-FunctionInterrupt.ps1` | ソース | 中断フラグチェック |
| Stop-Function.ps1 | `internal/functions/Stop-Function.ps1` | ソース | エラーハンドリング共通関数 |
| Write-Message.ps1 | `internal/functions/Write-Message.ps1` | ソース | ログ出力共通関数 |
| Select-DefaultView.ps1 | `internal/functions/Select-DefaultView.ps1` | ソース | デフォルト表示プロパティ設定 |
| Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | ソース | オペレーター取得（関連コマンド） |
| New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | ソース | オペレーター作成（関連コマンド） |
