# 画面設計書 13-Agentオペレーター管理

## 概要

本ドキュメントは、SQL Server Agent オペレーターの作成・取得・設定・削除・コピー機能を提供するコマンド群の設計仕様を記述したものです。

### 本画面の処理概要

本機能は、SQL Server Agent のオペレーター（通知連絡先）を管理し、アラートやジョブ失敗時の通知設定を構成します。オペレーターはメール、ポケベル、ネット送信を介して通知を受信でき、曜日・時間帯別のポケベルスケジュールも設定できます。

**業務上の目的・背景**：SQL Server Agent からのアラートやジョブ障害通知を適切な担当者に届けるため、オペレーター（連絡先）の管理が必要です。複数サーバーに対して一貫したオペレーター設定を展開し、監査やコンプライアンス要件に対応する通知インフラを構築できます。

**画面へのアクセス方法**：PowerShell コンソールまたはスクリプトから以下のコマンドを実行してアクセスします。
- `Get-DbaAgentOperator` - オペレーター設定の取得
- `New-DbaAgentOperator` - オペレーターの新規作成
- `Set-DbaAgentOperator` - オペレーターの設定変更
- `Remove-DbaAgentOperator` - オペレーターの削除
- `Copy-DbaAgentOperator` - オペレーターのインスタンス間コピー

**主要な操作・処理内容**：
1. SQL Server インスタンスからオペレーター設定一覧を取得し、関連ジョブ・アラートも表示
2. 新規オペレーターの作成（メールアドレス、ポケベルスケジュール等）
3. 既存オペレーターの連絡先情報・スケジュールの更新
4. 不要なオペレーターの削除
5. フェイルセーフオペレーターの設定

**画面遷移**：本機能はCLIコマンドであり、他のコマンドとパイプライン連携が可能です。
- `Get-DbaAgentOperator` から `Set-DbaAgentOperator` または `Remove-DbaAgentOperator` へパイプライン連携可能
- `Copy-DbaAgentAlert` と連携してアラートも含めた移行が可能

**権限による表示制御**：sysadmin 権限が必要です。Express Edition では SQL Agent が存在しないため、エラーメッセージが表示されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 491 | Get-DbaAgentOperator | 主機能 | SQLエージェントオペレーターの取得 |
| 501 | New-DbaAgentOperator | 主機能 | SQLエージェントオペレーターの新規作成 |
| 509 | Remove-DbaAgentOperator | 主機能 | SQLエージェントオペレーターの削除 |
| 518 | Set-DbaAgentOperator | 補助機能 | SQLエージェントオペレーターの設定変更 |
| 478 | Copy-DbaAgentOperator | 補助機能 | オペレーターのコピー |

## 画面種別

一覧 / 登録 / 編集 / 削除

## URL/ルーティング

PowerShell コマンドとして提供（CLIベース）
- `Get-DbaAgentOperator`
- `New-DbaAgentOperator`
- `Set-DbaAgentOperator`
- `Remove-DbaAgentOperator`
- `Copy-DbaAgentOperator`

## 入出力項目

### Get-DbaAgentOperator パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象のSQL Serverインスタンス |
| SqlCredential | PSCredential | No | 代替認証情報 |
| Operator | object[] | No | 取得するオペレーター名 |
| ExcludeOperator | object[] | No | 除外するオペレーター名 |
| EnableException | switch | No | 例外を有効化 |

### New-DbaAgentOperator パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス |
| SqlCredential | PSCredential | No | 代替認証情報 |
| Operator | string | Yes | オペレーター名 |
| EmailAddress | string | No | メールアドレス |
| NetSendAddress | string | No | ネット送信アドレス |
| PagerAddress | string | No | ポケベルアドレス |
| PagerDay | ValidateSet | No | ポケベル通知曜日（EveryDay/Weekdays/Weekend/各曜日） |
| 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 | フェイルセーフ通知方法（NotifyEmail/NotifyPager） |
| Force | switch | No | 既存オペレーターを上書き |
| InputObject | Server[] | No | パイプライン入力 |
| EnableException | switch | No | 例外を有効化 |

### Set-DbaAgentOperator パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス |
| SqlCredential | PSCredential | No | 代替認証情報 |
| Operator | string[] | No | オペレーター名 |
| Name | string | No | 新しいオペレーター名 |
| EmailAddress | string | No | メールアドレス |
| NetSendAddress | string | No | ネット送信アドレス |
| PagerAddress | string | No | ポケベルアドレス |
| PagerDay | ValidateSet | No | ポケベル通知曜日 |
| IsFailsafeOperator | switch | No | フェイルセーフオペレーターとして指定 |
| FailsafeNotificationMethod | ValidateSet[] | No | フェイルセーフ通知方法 |
| InputObject | Operator[] | No | パイプライン入力 |
| EnableException | switch | No | 例外を有効化 |

### Remove-DbaAgentOperator パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス |
| SqlCredential | PSCredential | No | 代替認証情報 |
| Operator | string[] | No | 削除するオペレーター名 |
| ExcludeOperator | string[] | No | 除外するオペレーター名 |
| InputObject | Operator[] | No | パイプライン入力 |
| EnableException | switch | No | 例外を有効化 |

## 表示項目

### Get-DbaAgentOperator 出力

| 項目名 | 説明 |
|--------|------|
| ComputerName | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | SQL Serverインスタンス名 |
| SqlInstance | 完全なSQL Serverインスタンス名 |
| Name | オペレーター名 |
| ID | オペレーターID |
| IsEnabled | 有効/無効 |
| EmailAddress | メールアドレス |
| LastEmail | 最終メール送信日時 |
| RelatedJobs | 関連ジョブ一覧 |
| RelatedAlerts | 関連アラート一覧 |
| AlertLastEmail | アラート最終通知日時 |

### Remove-DbaAgentOperator 出力

| 項目名 | 説明 |
|--------|------|
| ComputerName | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | SQL Serverインスタンス名 |
| SqlInstance | 完全なSQL Serverインスタンス名 |
| Name | 削除されたオペレーター名 |
| Status | 操作結果（Dropped/エラーメッセージ） |
| IsRemoved | 削除成功フラグ |

## イベント仕様

### 1-オペレーター取得

**処理フロー**:
1. `Connect-DbaInstance` でSQL Serverインスタンスに接続
2. Express Editionチェック
3. `$server.JobServer.Operators` からオペレーター一覧を取得
4. 各オペレーターに対して関連ジョブを検索（OperatorToEmail/OperatorToNetSend/OperatorToPage）
5. 各アラートの `EnumNotifications()` を呼び出し、関連アラートを収集
6. `Select-DefaultView` で整形して出力

### 2-オペレーター作成

**処理フロー**:
1. EmailAddress/NetSendAddress/PagerAddress のいずれかが必須チェック
2. PagerDayに応じた時刻検証（正規表現: `^(?:(?:([01]?\d|2[0-3]))?([0-5]?\d))?([0-5]?\d)$`）
3. 時刻をHH:MM:SS形式にフォーマット
4. 既存オペレーターの存在チェック（`-Force` で上書き可能）
5. `New-Object Microsoft.SqlServer.Management.Smo.Agent.Operator` でオペレーターオブジェクト作成
6. プロパティ設定（EmailAddress、PagerDays等）
7. `$operators.Create()` でオペレーターを作成
8. フェイルセーフオペレーター設定（`-IsFailsafeOperator` 指定時）
9. 作成されたオペレーターを `Get-DbaAgentOperator` で取得して返却

### 3-オペレーター設定変更

**処理フロー**:
1. EmailAddress/NetSendAddress/PagerAddress のいずれかが必須チェック
2. `Get-DbaAgentOperator` で対象オペレーター取得
3. `-Name` 指定時は `sp_update_operator` でリネーム（Rename()ではなくSQLスクリプト実行）
4. 各プロパティを更新（EmailAddress、PagerDays、時刻等）
5. フェイルセーフオペレーター設定（通知方法のビットマスク計算）
6. `$op.Alter()` で変更をコミット

### 4-オペレーター削除

**処理フロー**:
1. `Get-DbaAgentOperator` でオペレーターオブジェクトを取得（または `InputObject` から）
2. `end` ブロックで削除処理（コレクション変更エラー防止）
3. `$dbOperator.Drop()` でオペレーターを削除
4. 結果オブジェクト（Status、IsRemoved）を出力

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Get-DbaAgentOperator | msdb.dbo.sysoperators | SELECT | オペレーター設定の取得 |
| New-DbaAgentOperator | msdb.dbo.sysoperators | INSERT | オペレーターの新規作成 |
| Set-DbaAgentOperator | msdb.dbo.sysoperators | UPDATE | オペレーター設定の更新 |
| Remove-DbaAgentOperator | msdb.dbo.sysoperators | DELETE | オペレーターの削除 |

### テーブル別更新項目詳細

#### msdb.dbo.sysoperators

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | ユーザー指定のオペレーター名 | 一意制約あり |
| INSERT | email_address | メールアドレス | |
| INSERT | pager_address | ポケベルアドレス | |
| INSERT | netsend_address | ネット送信アドレス | |
| INSERT | pager_days | 曜日ビットマスク | 1=日,2=月,...,64=土 |
| UPDATE | email_address | 更新後のメールアドレス | |
| UPDATE | name | sp_update_operator で更新 | |

## メッセージ仕様

| メッセージ種別 | 条件 | メッセージ内容 |
|---------------|------|---------------|
| Error | Express Edition | "There is no SQL Agent on $server, it's a $($server.Edition)" |
| Error | 連絡先未指定 | "You must specify either an EmailAddress, NetSendAddress, or a PagerAddress..." |
| Error | 時刻形式エラー | "Start time $SaturdayStartTime needs to match between '000000' and '235959'" |
| Error | AG Listener経由 | "Cannot create agent operator through a contained availability group listener..." |
| Error | フェイルセーフ通知方法エラー | "The failsafe operator notification methods 'None' and 'NotifyAll' cannot be specified..." |
| Verbose | 既存スキップ | "Operator $operator exists at $server. Use -Force to drop and create." |
| Verbose | デフォルト時刻設定 | "Saturday Start time was not set. Force is being used. Setting it to $SaturdayStartTime" |

## 例外処理

| 例外条件 | 対応 |
|---------|------|
| SQL Serverインスタンスへの接続失敗 | Stop-Function でエラー出力し、次のインスタンスへ継続 |
| Express Editionへの接続 | Stop-Function で警告出力し、処理継続 |
| 連絡先情報の未指定 | Stop-Function でエラー出力し、処理終了 |
| 時刻形式の不正 | Stop-Function でエラー出力し、処理終了 |
| AG Listener経由での作成 | Stop-Function でエラー出力し、プライマリレプリカへの接続を推奨 |
| オペレーター削除失敗 | Status に エラーメッセージを設定、IsRemoved = false |

## 備考

- PagerDaysはビットマスク形式で保存（日=1, 月=2, 火=4, 水=8, 木=16, 金=32, 土=64）
- Weekdays=62、Weekend=65、EveryDay=127
- フェイルセーフオペレーターは1インスタンスにつき1つのみ設定可能
- `-Force` 使用時、時刻未指定の場合は '000000' から '235959' がデフォルト設定される
- Set-DbaAgentOperatorの名前変更は、列挙問題回避のためRename()ではなくsp_update_operatorを直接実行

---

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

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

### 推奨読解順序

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

SMO の Operator クラス構造と関連ジョブ・アラートの取得方法を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | 63-106行: .OUTPUTS セクションでSMO Operatorオブジェクト構造を確認 |

**読解のコツ**: `RelatedJobs` と `RelatedAlerts` はカスタムプロパティとして追加される点に注意。

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

各コマンドのパラメータ処理と前処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | 108-117行: パラメータ定義 |
| 2-2 | Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | 129-131行: Express Editionチェック |
| 2-3 | Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | 145-157行: 関連ジョブ・アラートの収集 |

**主要処理フロー**:
1. **121行**: `Connect-DbaInstance` でサーバー接続
2. **136-141行**: オペレーターフィルタリング
3. **147行**: `OperatorToEmail`, `OperatorToNetSend`, `OperatorToPage` で関連ジョブを検索
4. **151-157行**: 各アラートの `EnumNotifications()` で関連アラートを収集

#### Step 3: オペレーター作成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | 148-170行: パラメータ定義 |
| 3-2 | New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | 182-209行: PagerDayのビットマスク計算 |
| 3-3 | New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | 211-289行: 時刻検証ロジック |
| 3-4 | New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | 352-420行: オペレーター作成処理 |

**主要処理フロー**:
- **186-196行**: PagerDayからビットマスク値への変換
- **357行**: `New-Object Microsoft.SqlServer.Management.Smo.Agent.Operator` でオブジェクト生成
- **407行**: `$operators.Create()` で SQL Server に作成
- **409-413行**: フェイルセーフオペレーター設定

#### Step 4: 設定変更ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 247-269行: フェイルセーフ通知方法のビットマスク計算 |
| 4-2 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 306-318行: sp_update_operatorによる名前変更 |
| 4-3 | Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | 388-390行: Alter()によるコミット |

**主要処理フロー**:
- **254-268行**: 通知方法のビットマスク計算（NotifyEmail=1, Pager=2, NetSend=4, NotifyAll=7）
- **309行**: `sp_update_operator` でリネーム（Rename()ではない）
- **389行**: `$op.Alter()` で変更確定

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

```
Get-DbaAgentOperator
    |
    +-- Connect-DbaInstance (接続確立)
    |
    +-- Express Editionチェック
    |
    +-- $server.JobServer.Operators (オペレーター一覧取得)
    |
    +-- Filter: -Operator, -ExcludeOperator
    |
    +-- 関連ジョブ検索
    |       +-- Where-Object { OperatorToEmail/NetSend/Page }
    |
    +-- 関連アラート検索
    |       +-- $alert.EnumNotifications($operat.Name)
    |
    +-- Select-DefaultView (出力整形)

New-DbaAgentOperator
    |
    +-- 連絡先必須チェック
    |
    +-- PagerDayビットマスク計算
    |
    +-- 時刻検証（正規表現）
    |
    +-- Connect-DbaInstance (接続確立)
    |
    +-- 既存オペレーターチェック
    |       +-- [Force] Drop既存オペレーター
    |
    +-- New-Object Operator (SMOオブジェクト作成)
    |
    +-- プロパティ設定
    |
    +-- $operators.Create() (作成)
    |
    +-- [IsFailsafeOperator]
    |       +-- AlertSystem.FailSafeOperator設定
    |       +-- AlertSystem.Alter()
    |
    +-- Get-DbaAgentOperator (結果取得)
```

### データフロー図

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

SqlInstance ────────> Connect-DbaInstance ─────────> SMO Server Object
                            |
                      Edition チェック
                            |
Operator/Exclude ────> フィルタリング ───────────────> Operator Objects
                            |
                      関連ジョブ検索
                      (OperatorToEmail/NetSend/Page)
                            |
                      関連アラート検索
                      (EnumNotifications)
                            |
                      Add-Member (カスタムプロパティ)
                            |
                      Select-DefaultView ────────────> [出力オブジェクト]
                                                        - ComputerName
                                                        - Name
                                                        - IsEnabled
                                                        - EmailAddress
                                                        - RelatedJobs
                                                        - RelatedAlerts
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaAgentOperator.ps1 | `public/Get-DbaAgentOperator.ps1` | ソース | オペレーター取得のメインコマンド |
| New-DbaAgentOperator.ps1 | `public/New-DbaAgentOperator.ps1` | ソース | オペレーター作成コマンド |
| Set-DbaAgentOperator.ps1 | `public/Set-DbaAgentOperator.ps1` | ソース | オペレーター設定変更コマンド |
| Remove-DbaAgentOperator.ps1 | `public/Remove-DbaAgentOperator.ps1` | ソース | オペレーター削除コマンド |
| Copy-DbaAgentOperator.ps1 | `public/Copy-DbaAgentOperator.ps1` | ソース | オペレーターコピーコマンド |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続管理 |
| Select-DefaultView.ps1 | `internal/functions/Select-DefaultView.ps1` | ソース | 出力整形ユーティリティ |
