# 通知設計書 24-Set-DbaAgentOperator

## 概要

本ドキュメントは、既存のSQL Server Agentオペレーターの連絡先情報、ページャースケジュール、フェールセーフ設定を変更するPowerShellコマンド `Set-DbaAgentOperator` の通知設計書です。

### 本通知の処理概要

`Set-DbaAgentOperator` は、既存のSQL Server Agentオペレーターの設定を更新するコマンドです。メールアドレス、ページャー連絡先、NetSendアドレス、ページャー通知のスケジュール（曜日別時間帯）、およびフェールセーフオペレーター設定を変更できます。オペレーター名の変更も可能です。

**業務上の目的・背景**：組織内の人員異動、連絡先情報の更新、オンコールスケジュールの変更などにより、既存オペレーターの設定を更新する必要が生じます。このコマンドは、SSMSを使用した手動更新の代わりに、スクリプトによる一貫した設定変更を実現します。複数オペレーターの一括更新やパイプライン入力による効率的な運用が可能です。

**通知の送信タイミング**：このコマンドはオペレーター設定を更新する機能であり、更新時に通知は送信されません。コマンド実行完了後、更新されたオペレーターオブジェクト（SMO Operator）がパイプラインに出力されます。

**通知の受信者**：コマンド実行者がPowerShellコンソールまたはスクリプトの出力を通じて結果を受信します。更新されたオペレーターは、引き続きアラートやジョブからの通知を受信する設定として機能します。

**通知内容の概要**：出力には更新されたオペレーターのSMOオブジェクトが含まれ、変更後の全プロパティ（EmailAddress、NetSendAddress、PagerAddress、PagerDays、ページャー時間設定、Name等）にアクセスできます。

**期待されるアクション**：コマンド実行者は更新結果を確認し、必要に応じて関連するアラートやジョブの通知設定が正しく機能することをテストすることが期待されます。

## 通知種別

コンソール出力 / パイプライン出力（Microsoft.SqlServer.Management.Smo.Agent.Operator）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（処理完了後にパイプライン出力） |
| 優先度 | 中 |
| リトライ | 無（コマンド再実行により対応） |

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

コマンド実行者のPowerShellセッションに直接出力されます。各オペレーターの更新完了後、そのSMOオブジェクトが出力されます。

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 出力形式 | Microsoft.SqlServer.Management.Smo.Agent.Operator |
| 利用可能プロパティ | 全SMO Operatorプロパティ（EmailAddress, NetSendAddress, PagerAddress, PagerDays, 各種時間設定, Name, ID等） |

### 更新可能なプロパティ

```powershell
$op.EmailAddress = $EmailAddress        # メールアドレス
$op.NetSendAddress = $NetSendAddress    # NetSendアドレス
$op.PagerAddress = $PagerAddress        # ページャーアドレス
$op.PagerDays = $Interval               # ページャー通知曜日（ビットマスク）
$op.SaturdayPagerStartTime = $SaturdayStartTime
$op.SaturdayPagerEndTime = $SaturdayEndTime
$op.SundayPagerStartTime = $SundayStartTime
$op.SundayPagerEndTime = $SundayEndTime
$op.WeekdayPagerStartTime = $WeekdayStartTime
$op.WeekdayPagerEndTime = $WeekdayEndTime
# 名前変更はsp_update_operatorストアドプロシージャ経由
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| Operator | 更新対象オペレーター名 | パラメータまたはInputObject | Yes (いずれか) |
| Name | 新しいオペレーター名 | パラメータ | No |
| EmailAddress | メール通知先アドレス | パラメータ | No (いずれか1つ必須) |
| NetSendAddress | NetSend通知先アドレス | パラメータ | No (いずれか1つ必須) |
| PagerAddress | ページャー通知先アドレス | パラメータ | No (いずれか1つ必須) |
| PagerDay | ページャー通知曜日 | パラメータ | No |
| SaturdayStartTime | 土曜ページャー開始時間 | パラメータ（HHMMSS形式） | No |
| SaturdayEndTime | 土曜ページャー終了時間 | パラメータ（HHMMSS形式） | No |
| SundayStartTime | 日曜ページャー開始時間 | パラメータ（HHMMSS形式） | No |
| SundayEndTime | 日曜ページャー終了時間 | パラメータ（HHMMSS形式） | No |
| WeekdayStartTime | 平日ページャー開始時間 | パラメータ（HHMMSS形式） | No |
| WeekdayEndTime | 平日ページャー終了時間 | パラメータ（HHMMSS形式） | No |
| IsFailsafeOperator | フェールセーフオペレーター設定 | パラメータ | No |
| FailsafeNotificationMethod | フェールセーフ通知方法 | パラメータ | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コマンド実行 | Set-DbaAgentOperator実行 | ShouldProcess確認後 | オペレーター更新完了時に出力 |
| パイプライン入力 | InputObject（SMO Operator）受信 | ValueFromPipeline | Get-DbaAgentOperatorからのパイプ入力 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 通知先未指定 | EmailAddress, NetSendAddress, PagerAddressのいずれも指定されていない場合 |
| オペレーター未指定 | OperatorパラメータもInputObjectも指定されていない場合 |
| WhatIf指定時 | -WhatIfパラメータ指定時は実際の更新は行わない |
| Confirm拒否時 | -Confirmで確認を求められた際にユーザーが拒否した場合 |
| フェールセーフ通知方法不正 | NoneまたはNotifyAllと他の方法を同時指定した場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B{通知先指定あり?}
    B -->|No| C[Stop-Function: 通知先必須]
    B -->|Yes| D{Operator/InputObject指定?}
    D -->|No| E[Stop-Function: オペレーター必須]
    D -->|Yes| F[PagerDay計算]
    F --> G{ページャー時間検証}
    G -->|NG| H[Stop-Function: 時間形式エラー]
    G -->|OK| I{フェールセーフ通知方法検証}
    I -->|NG| J[Stop-Function: 通知方法不正]
    I -->|OK| K[時間形式変換 HH:MM:SS]
    K --> L{SqlInstance指定?}
    L -->|Yes| M[Get-DbaAgentOperator]
    L -->|No| N[InputObject使用]
    M --> O[オペレーターループ]
    N --> O
    O --> P{Name変更?}
    P -->|Yes| Q[sp_update_operator実行]
    Q --> R[Refresh + 再取得]
    P -->|No| S[プロパティ更新]
    R --> S
    S --> T{IsFailsafeOperator?}
    T -->|Yes| U[AlertSystem設定]
    T -->|No| V[Alter実行]
    U --> V
    V --> W[出力]
    W --> O
    O -->|完了| X[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| msdb.dbo.sysoperators | 既存オペレーター取得 | SMO経由でアクセス |

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

#### msdb.dbo.sysoperators

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| name | オペレーター検索 | 指定名と一致 |
| 全カラム | 現在値取得 | Get-DbaAgentOperator経由 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| msdb.dbo.sysoperators | UPDATE | オペレーター設定の更新 |
| msdb.dbo.sysalerts_view | UPDATE | フェールセーフオペレーター設定時 |

#### オペレーター更新時

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| UPDATE | email_address | $EmailAddress | メールアドレス |
| UPDATE | netsend_address | $NetSendAddress | NetSendアドレス |
| UPDATE | pager_address | $PagerAddress | ページャーアドレス |
| UPDATE | pager_days | $Interval | ページャー曜日ビットマスク |
| UPDATE | saturday_pager_start/end_time | 時間値 | 土曜ページャー時間 |
| UPDATE | sunday_pager_start/end_time | 時間値 | 日曜ページャー時間 |
| UPDATE | weekday_pager_start/end_time | 時間値 | 平日ページャー時間 |

#### 名前変更時（sp_update_operator経由）

```sql
EXEC msdb.dbo.sp_update_operator @name = N'旧名', @new_name = N'新名'
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 通知先未指定 | EmailAddress, NetSendAddress, PagerAddressのいずれも未指定 | いずれか1つ以上を指定 |
| オペレーター未指定 | OperatorもInputObjectも未指定 | いずれかを指定 |
| 時間形式エラー | ページャー時間がHHMMSS形式でない | 000000-235959の範囲で指定 |
| 通知方法不正 | NoneまたはNotifyAllと他の方法を同時指定 | 適切な組み合わせで指定 |
| 接続エラー | SQL Serverインスタンスに接続できない | 接続情報を確認し再試行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（手動で再実行が必要） |

## 配信設定

### レート制限

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

### 配信時間帯

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

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

- SQL Serverインスタンスへの適切な権限が必要
- SqlCredentialパラメータを使用して安全に認証情報を渡すことが可能
- SupportsShouldProcessが有効で、ConfirmImpactはMediumに設定
- オペレーター名変更時はsp_update_operatorストアドプロシージャを直接実行

## 備考

- PagerDayパラメータはビットマスクで内部管理：Sunday=1, Monday=2, Tuesday=4, Wednesday=8, Thursday=16, Friday=32, Saturday=64, Weekdays=62, Weekend=65, EveryDay=127
- ページャー時間はHHMMSS形式で指定し、内部でHH:MM:SS形式に変換される
- ページャー時間を指定しない場合、デフォルトで000000（開始）と235959（終了）が設定される
- 名前変更には.Rename()メソッドではなくsp_update_operatorを使用（パイプライン処理時の列挙問題回避のため）
- FailsafeNotificationMethodは複数指定可能（NotifyEmail=1, Pager=2, NetSend=4, NotifyAll=7）、ただしNone、NotifyAllは単独使用

---

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

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

### 推奨読解順序

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

まず、入出力されるSMOオペレーターオブジェクトとパラメータの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 88-107行目の.OUTPUTSセクションで出力構造を確認 |
| 1-2 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 121-144行目でパラメータ定義を確認 |

**読解のコツ**: InputObjectパラメータで既存のSMO Operatorオブジェクトをパイプライン入力できるため、Get-DbaAgentOperatorとの連携が容易です。

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

処理の起点となるfunction定義とパラメータバリデーションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 145行目（processブロック開始） |
| 2-2 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 146-154行目で必須パラメータチェック |

**主要処理フロー**:
1. **146-149行目**: 通知先（Email/NetSend/Pager）の必須チェック
2. **151-154行目**: Operator/InputObjectの必須チェック
3. **156-183行目**: PagerDay値からビットマスクへの変換

#### Step 3: ページャー時間の検証と変換を理解する

ページャー時間パラメータの検証と形式変換ロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 185行目で時間形式の正規表現定義 |
| 3-2 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 187-245行目で曜日別時間検証 |
| 3-3 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 273-293行目で時間形式変換（HH:MM:SS） |

**主要処理フロー**:
- **185行目**: 正規表現 `^(?:(?:([01]?\d|2[0-3]))?([0-5]?\d))?([0-5]?\d)$`
- **189-191行目**: 未指定時のデフォルト値設定（000000/235959）

#### Step 4: フェールセーフ通知方法の検証を理解する

FailsafeNotificationMethodパラメータの検証とビットマスク変換を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 247-271行目でフェールセーフ通知方法検証 |

**主要処理フロー**:
- **247-249行目**: None/NotifyAllと他の組み合わせチェック
- **254-268行目**: 通知方法のビットマスク変換（NotifyEmail=1, Pager=2, NetSend=4, NotifyAll=7）

#### Step 5: オペレーター更新処理を理解する

名前変更、プロパティ更新、フェールセーフ設定のロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 295-301行目でオペレーター取得 |
| 5-2 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 303-395行目で更新処理 |

**主要処理フロー**:
- **306-318行目**: 名前変更（sp_update_operator使用）
- **320-378行目**: 各プロパティの更新（ShouldProcess確認付き）
- **380-386行目**: フェールセーフオペレーター設定
- **388-391行目**: Alter()実行と出力

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

```
Set-DbaAgentOperator
    |
    +-- [processブロック]
            +-- 通知先必須チェック
            +-- Operator/InputObject必須チェック
            +-- PagerDay → ビットマスク変換
            +-- ページャー時間検証（正規表現）
            +-- フェールセーフ通知方法検証・変換
            +-- 時間形式変換（HHMMSS → HH:MM:SS）
            |
            +-- SqlInstance指定時
            |       +-- Get-DbaAgentOperator
            |
            +-- foreach ($op in $InputObject)
                    |
                    +-- Get-ConnectionParent
                    |
                    +-- Name変更時
                    |       +-- Invoke-DbaQuery (sp_update_operator)
                    |       +-- Refresh()
                    |       +-- Get-DbaAgentOperator
                    |
                    +-- プロパティ更新 (ShouldProcess付き)
                    |       +-- EmailAddress
                    |       +-- NetSendAddress
                    |       +-- PagerAddress
                    |       +-- PagerDays
                    |       +-- ページャー時間各種
                    |
                    +-- IsFailsafeOperator時
                    |       +-- AlertSystem.FailSafeOperator設定
                    |       +-- AlertSystem.NotificationMethod設定
                    |       +-- AlertSystem.Alter()
                    |
                    +-- $op.Alter()
                    +-- $op 出力
```

### データフロー図

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

SqlInstance[] ──┬──────────────> Get-DbaAgentOperator ─────┐
                |                                          |
Operator ───────┘                                          |
                                                           v
InputObject (Pipeline) ────────────────────────────────> オペレーターループ
                                                           |
Name ─────────────────────────────────────────> sp_update_operator (名前変更)
                                                           |
EmailAddress ────┐                                         |
NetSendAddress ──┼─────────────────────────────> プロパティ更新
PagerAddress ────┘                                         |
                                                           v
PagerDay ────────────────> ビットマスク変換 ────> PagerDays設定
                                                           |
SaturdayStartTime ──┐                                      |
SaturdayEndTime ────┤                                      |
SundayStartTime ────┼─> 時間検証 + 形式変換 ───> ページャー時間設定
SundayEndTime ──────┤                                      |
WeekdayStartTime ───┤                                      |
WeekdayEndTime ─────┘                                      |
                                                           v
IsFailsafeOperator ─────────────────────────────> AlertSystem設定
FailsafeNotificationMethod ──> ビットマスク変換 ────────> |
                                                           v
                                                   $op.Alter() ──> SMO Operator出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | ソース | オペレーター更新の本体 |
| Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | ソース | オペレーター取得（入力/名前変更後の再取得） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | sp_update_operator実行 |
| Get-ConnectionParent.ps1 | `internal/functions/Get-ConnectionParent.ps1` | ソース | SMOオブジェクトから親サーバー取得 |
| Stop-Function.ps1 | `internal/functions/Stop-Function.ps1` | ソース | エラーハンドリング共通関数 |
| Write-Message.ps1 | `internal/functions/Write-Message.ps1` | ソース | ログ出力共通関数 |
| New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | ソース | オペレーター作成（関連コマンド） |
| Remove-DbaAgentOperator.ps1 | `public/Remove-DbaAgentOperator.ps1` | ソース | オペレーター削除（関連コマンド） |
