# 機能設計書 518-Set-DbaAgentOperator

## 概要

本ドキュメントは、SQL Server Agentオペレーターの連絡先情報やページャー設定を変更するdbatools関数「Set-DbaAgentOperator」の機能設計書である。

### 本機能の処理概要

Set-DbaAgentOperatorは、既存のSQL Server Agentオペレーターの連絡先情報、ページャー通知スケジュール、フェイルセーフオペレーター設定を変更する機能を提供する。

**業務上の目的・背景**：SQL Server Agentオペレーターは、ジョブ失敗やアラート発生時に通知を受け取る担当者を定義する。組織変更、担当者交代、連絡先情報の更新など、オペレーター設定を変更する必要が生じた場合、SSMSでの手動編集は煩雑である。本機能により、複数サーバーのオペレーター設定を一括で更新できる。

**機能の利用シーン**：
- 担当者のメールアドレス変更
- ページャー通知時間帯の調整
- フェイルセーフオペレーターの設定
- オペレーター名の変更
- 複数サーバーでのオペレーター設定の統一

**主要な処理内容**：
1. 対象SQL Serverインスタンスへの接続
2. 対象オペレーターの取得
3. 連絡先情報（メール、NetSend、ページャー）の検証
4. ページャースケジュールの設定
5. フェイルセーフオペレーター設定（オプション）
6. SMO Alter()メソッドによる変更のコミット

**関連システム・外部連携**：SQL Server JobServer.Operators、JobServer.AlertSystem

**権限による制御**：適切な権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio - Operator Properties | 参照画面 | オペレータープロパティの確認・編集 |
| - | PowerShell Console | 主画面 | コマンド実行インターフェース |

## 機能種別

データ更新操作 (UPDATE)

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | 代替認証資格情報 | - |
| Operator | string[] | No* | 対象オペレーター名 | OperatorまたはInputObjectの少なくとも一方が必要 |
| Name | string | No | 新しいオペレーター名 | - |
| EmailAddress | string | No | メールアドレス | EmailAddress/NetSendAddress/PagerAddressの少なくとも一つが必要 |
| NetSendAddress | string | No | NetSendアドレス | - |
| PagerAddress | string | No | ページャーメールアドレス | - |
| PagerDay | string | No | ページャー有効曜日 | EveryDay, Weekdays, Weekend, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday |
| SaturdayStartTime | string | No | 土曜開始時刻 | HHMMSS形式 |
| SaturdayEndTime | string | No | 土曜終了時刻 | HHMMSS形式 |
| SundayStartTime | string | No | 日曜開始時刻 | HHMMSS形式 |
| SundayEndTime | string | No | 日曜終了時刻 | HHMMSS形式 |
| WeekdayStartTime | string | No | 平日開始時刻 | HHMMSS形式 |
| WeekdayEndTime | string | No | 平日終了時刻 | HHMMSS形式 |
| IsFailsafeOperator | switch | No | フェイルセーフオペレーターとして設定 | - |
| FailsafeNotificationMethod | string[] | No | フェイルセーフ通知方法 | None, NotifyEmail, Pager, NetSend, NotifyAll |
| InputObject | Operator[] | No* | パイプラインからのオペレーターオブジェクト | - |
| EnableException | switch | No | 例外処理を有効化 | - |

### 入力データソース

- Get-DbaAgentOperatorからのパイプライン入力
- SQL Server JobServer.Operatorsコレクション

## 出力仕様

### 出力データ

Microsoft.SqlServer.Management.Smo.Agent.Operator オブジェクト

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | string | オペレーター名 |
| EmailAddress | string | メールアドレス |
| NetSendAddress | string | NetSendアドレス |
| PagerAddress | string | ページャーアドレス |
| PagerDays | int | ページャー有効曜日（ビットマスク） |
| SaturdayPagerStartTime | string | 土曜開始時刻 |
| SaturdayPagerEndTime | string | 土曜終了時刻 |
| SundayPagerStartTime | string | 日曜開始時刻 |
| SundayPagerEndTime | string | 日曜終了時刻 |
| WeekdayPagerStartTime | string | 平日開始時刻 |
| WeekdayPagerEndTime | string | 平日終了時刻 |
| ID | int | オペレーターID |
| LastNotificationTime | DateTime | 最終通知日時 |

### 出力先

PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.Agent.Operator）

## 処理フロー

### 処理シーケンス

```
1. 入力検証（processブロック）
   ├─ 連絡先情報の存在確認（EmailAddress/NetSendAddress/PagerAddressの少なくとも1つ）
   └─ オペレーター識別子の存在確認（Operator/InputObject）

2. ページャー日付の計算
   └─ PagerDayを整数のビットマスク値に変換

3. 時刻フォーマット検証
   ├─ HHMMSS形式の検証
   └─ 未指定時のデフォルト値設定

4. フェイルセーフ通知方法の検証
   └─ None/NotifyAllと他の値の組み合わせ禁止

5. 時刻フォーマット変換
   └─ HHMMSS → HH:MM:SS形式

6. オペレーター取得
   └─ SqlInstance指定時: Get-DbaAgentOperatorで取得

7. 各オペレーターの処理
   ├─ 名前変更（Name指定時）: sp_update_operator実行
   ├─ EmailAddress更新
   ├─ NetSendAddress更新
   ├─ PagerAddress更新
   ├─ PagerDays更新
   ├─ 各種時刻設定更新
   ├─ フェイルセーフオペレーター設定
   └─ Alter()メソッド呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{連絡先情報指定?}
    B -->|No| C[エラー: 連絡先必須]
    B -->|Yes| D{Operator/InputObject指定?}
    D -->|No| E[エラー: オペレーター必須]
    D -->|Yes| F[PagerDay→ビットマスク変換]
    F --> G[時刻フォーマット検証]
    G --> H{検証OK?}
    H -->|No| I[エラー: 時刻形式不正]
    H -->|Yes| J[フェイルセーフ通知方法検証]
    J --> K{検証OK?}
    K -->|No| L[エラー: 通知方法不整合]
    K -->|Yes| M[時刻フォーマット変換]
    M --> N{SqlInstance指定?}
    N -->|Yes| O[Get-DbaAgentOperator]
    N -->|No| P[InputObjectを使用]
    O --> Q[各オペレーターをループ]
    P --> Q
    Q --> R{Name指定?}
    R -->|Yes| S[sp_update_operator実行]
    R -->|No| T[プロパティ更新]
    S --> T
    T --> U{IsFailsafeOperator?}
    U -->|Yes| V[AlertSystem設定更新]
    U -->|No| W[ShouldProcess確認]
    V --> W
    W --> X[Alter実行]
    X --> Y[オペレーターオブジェクト出力]
    Y --> Z{次のオペレーター?}
    Z -->|Yes| Q
    Z -->|No| AA[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 連絡先必須 | EmailAddress, NetSendAddress, PagerAddressの少なくとも1つが必要 | 常時 |
| BR-002 | オペレーター識別子必須 | OperatorまたはInputObjectの指定が必要 | 常時 |
| BR-003 | フェイルセーフ通知方法排他 | NoneとNotifyAllは他の値と組み合わせ不可 | IsFailsafeOperator設定時 |
| BR-004 | 時刻フォーマット | 時刻はHHMMSS形式（000000-235959） | 時刻パラメータ指定時 |
| BR-005 | デフォルト時刻 | 時刻未指定時は000000（開始）または235959（終了）を使用 | PagerDay指定時 |

### 計算ロジック

**PagerDayのビットマスク計算**：
- Sunday = 1
- Monday = 2
- Tuesday = 4
- Wednesday = 8
- Thursday = 16
- Friday = 32
- Saturday = 64
- Weekdays = 62
- Weekend = 65
- EveryDay = 127

**フェイルセーフ通知方法のビットマスク計算**：
- NotifyEmail = 1
- Pager = 2
- NetSend = 4
- NotifyAll = 7

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| オペレーター更新 | msdb.dbo.sysoperators | UPDATE | オペレータープロパティの更新 |
| オペレーター名変更 | msdb.dbo.sysoperators | UPDATE | sp_update_operator経由 |
| フェイルセーフ設定 | msdb.dbo.sysalerts | UPDATE | AlertSystem.Alter()経由 |

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

#### msdb.dbo.sysoperators

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | Name指定値 | sp_update_operator経由 |
| UPDATE | email_address | EmailAddress指定値 | - |
| UPDATE | netsend_address | NetSendAddress指定値 | - |
| UPDATE | pager_address | PagerAddress指定値 | - |
| UPDATE | pager_days | PagerDay計算値 | ビットマスク |
| UPDATE | saturday_pager_start_time | SaturdayStartTime | - |
| UPDATE | saturday_pager_end_time | SaturdayEndTime | - |
| UPDATE | sunday_pager_start_time | SundayStartTime | - |
| UPDATE | sunday_pager_end_time | SundayEndTime | - |
| UPDATE | weekday_pager_start_time | WeekdayStartTime | - |
| UPDATE | weekday_pager_end_time | WeekdayEndTime | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Function | 連絡先情報が一つも指定されていない | EmailAddress/NetSendAddress/PagerAddressのいずれかを指定 |
| - | Stop-Function | オペレーター識別子が指定されていない | OperatorまたはInputObjectを指定 |
| - | Stop-Function | 時刻フォーマット不正 | HHMMSS形式で指定 |
| - | Stop-Function | フェイルセーフ通知方法の不整合 | None/NotifyAllは単独で使用 |
| - | ConnectionError | インスタンス接続失敗 | 接続情報を確認 |
| - | Stop-Function | オペレーター更新失敗 | エラーメッセージを確認 |

### リトライ仕様

リトライ機能なし。

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

SMOのAlter()メソッドによる暗黙的トランザクション。各オペレーターの更新は個別のトランザクション。

## パフォーマンス要件

特に定義なし。

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

- 適切な権限が必要
- フェイルセーフオペレーター設定は重要な監視設定
- WhatIf/Confirmパラメータによる事前確認が可能

## 備考

- NetSendは非推奨だが後方互換性のため対応
- 名前変更はsp_update_operatorストアドプロシージャを直接実行（列挙問題回避）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Microsoft.SqlServer.Management.Smo.Agent.Operator | SMO | オペレーターオブジェクトのプロパティ |

**読解のコツ**: SMOのOperatorクラスにはEmailAddress、PagerDays、各種時刻プロパティがあり、Alter()メソッドで変更を反映する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 関数定義、パラメータ、processブロック構造 |

**主要処理フロー**:
1. **121-144行目**: CmdletBinding属性とパラメータ定義
2. **145-396行目**: processブロック - メイン処理

#### Step 3: ページャー日付計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | PagerDayのビットマスク計算 |

**主要処理フロー**:
- **156-183行目**: PagerDayの文字列→整数変換

#### Step 4: 時刻検証とフォーマット変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 時刻検証とフォーマット変換 |

**主要処理フロー**:
- **185行目**: 時刻正規表現パターン
- **187-245行目**: 曜日別の時刻検証
- **274-293行目**: HHMMSS→HH:MM:SS変換

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | プロパティ更新と保存 |

**主要処理フロー**:
- **303-318行目**: 名前変更（sp_update_operator使用）
- **320-378行目**: 各プロパティの更新
- **380-386行目**: フェイルセーフオペレーター設定
- **388-390行目**: Alter実行

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

```
Set-DbaAgentOperator
    │
    ├─ Get-DbaAgentOperator (SqlInstance指定時)
    │
    ├─ Get-ConnectionParent (サーバー取得)
    │
    ├─ Invoke-DbaQuery (名前変更時)
    │      └─ sp_update_operator
    │
    ├─ Operator.Alter() (プロパティ更新)
    │
    └─ AlertSystem.Alter() (フェイルセーフ設定時)
```

### データフロー図

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

SqlInstance ─────────▶ Get-DbaAgentOperator
      │                        │
Operator名 ──────────▶ オペレーター取得
      │                        │
連絡先情報 ──────────▶ 入力検証
      │                        │
PagerDay ───────────▶ ビットマスク計算
      │                        │
時刻パラメータ ────────▶ 検証 + フォーマット変換
      │                        │
      ▼                        ▼
InputObject ─────────▶ 各オペレーターを処理
                              │
                              ▼
                       プロパティ更新
                       ├─ EmailAddress
                       ├─ NetSendAddress
                       ├─ PagerAddress
                       ├─ PagerDays
                       └─ 各種時刻設定
                              │
                              ▼
                    IsFailsafeOperator設定
                              │
                              ▼
                         Alter()
                              │
                              ▼
                   Operator ───▶ [Operatorオブジェクト出力]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | ソース | メイン関数 |
| Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | ソース | オペレーター取得 |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | SQLクエリ実行 |
