# 機能設計書 493-Get-DbaAgentSchedule

## 概要

本ドキュメントは、SQL Server Agent 共有スケジュールの取得機能 `Get-DbaAgentSchedule` の設計仕様を記載する。

### 本機能の処理概要

SQL Server Agent で設定されている共有スケジュールの詳細情報を、人間が読みやすい説明付きで取得する機能である。共有スケジュールは複数のジョブで再利用でき、メンテナンスウィンドウの標準化とスケジュール管理の効率化に役立つ。

**業務上の目的・背景**：SQL Server Agent のジョブスケジュールは、自動化されたメンテナンス作業、ETL処理、バックアップなどの実行タイミングを制御する。共有スケジュールを使用することで、複数のジョブに同一のスケジュールを適用でき、スケジュール変更時の一括更新が可能となる。本機能は、スケジュール設定の監査、ドキュメント作成、ジョブ実行パターンのトラブルシューティングに不可欠である。

**機能の利用シーン**：
- メンテナンスウィンドウの定義確認
- 複数インスタンスにおけるスケジュール設定の一括監査
- スケジュール設定のドキュメント作成
- ジョブ実行タイミングのトラブルシューティング
- 新環境への設定移行準備

**主要な処理内容**：
1. 対象 SQL Server インスタンスへの接続
2. SharedSchedules コレクションのリフレッシュ
3. SQL Server Agent の共有スケジュール一覧取得
4. 指定された条件（名前、UID、ID）によるフィルタリング
5. スケジュール説明文の自動生成
6. 拡張プロパティの付与と結果の出力

**関連システム・外部連携**：SQL Server Management Objects (SMO) を使用して SQL Server Agent の SharedSchedules コレクションから情報を取得する。Express Edition では SQL Server Agent が存在しないため、処理をスキップする。

**権限による制御**：SQL Server への接続権限が必要。スケジュール情報の取得には、msdb データベースへの参照権限が必要となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | Agentスケジュール管理 | 主画面 | SQLエージェントスケジュールの取得 |

## 機能種別

データ取得（SELECT）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQLServerインスタンス。パイプライン入力可能 | 必須、配列対応 |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証/AD対応 |
| Schedule | string[] | No | 取得対象スケジュール名の配列 | 完全一致 |
| ScheduleUid | string[] | No | 取得対象スケジュールGUIDの配列 | GUID形式 |
| Id | int[] | No | 取得対象スケジュールIDの配列 | 整数 |
| EnableException | switch | No | 例外処理の制御フラグ | - |

### 入力データソース

- SQL Server インスタンスへの SMO 接続
- `$server.JobServer.SharedSchedules` コレクション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピューター名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| ScheduleName | string | スケジュール表示名 |
| ActiveStartDate | datetime | スケジュール有効開始日 |
| ActiveStartTimeOfDay | timespan | スケジュール有効開始時刻 |
| ActiveEndDate | datetime | スケジュール有効終了日 |
| ActiveEndTimeOfDay | timespan | スケジュール有効終了時刻 |
| DateCreated | datetime | スケジュール作成日時 |
| FrequencyTypes | enum | 頻度タイプ（Once/Daily/Weekly/Monthly等） |
| FrequencyInterval | int | 頻度間隔 |
| FrequencySubDayTypes | enum | サブ日頻度タイプ |
| FrequencySubDayInterval | int | サブ日頻度間隔 |
| FrequencyRecurrenceFactor | int | 繰り返し係数 |
| FrequencyRelativeIntervals | enum | 相対間隔（月次相対スケジュール用） |
| IsEnabled | bool | スケジュールが有効かどうか |
| JobCount | int | このスケジュールを使用しているジョブ数 |
| Description | string | 人間が読みやすい形式のスケジュール説明 |
| ScheduleUid | guid | スケジュールの一意識別子 |

### 出力先

PowerShell パイプラインへの出力（`Microsoft.SqlServer.Management.Smo.SharedSchedule` オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 内部関数定義
   └─ Get-ScheduleDescription 関数の定義
2. パラメータ検証
   └─ SqlInstance の必須チェック
3. インスタンスループ開始
   └─ 各 SqlInstance に対して処理
4. SQL Server 接続
   └─ Connect-DbaInstance で接続確立
5. エディションチェック
   └─ Express Edition の場合は処理スキップ
6. SharedSchedules リフレッシュ
   └─ 最新データ取得のためリフレッシュ
7. スケジュール取得
   └─ フィルタ条件に基づきスケジュール取得
8. 説明文生成
   └─ Get-ScheduleDescription で説明文生成
9. プロパティ付与
   └─ 拡張プロパティの追加
10. 結果出力
    └─ Select-DefaultView でデフォルトプロパティ表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Get-ScheduleDescription 関数定義]
    B --> C{SqlInstance ループ}
    C --> D[Connect-DbaInstance]
    D --> E{接続成功?}
    E -->|No| F[Stop-Function でエラー]
    F --> C
    E -->|Yes| G{Express Edition?}
    G -->|Yes| H[Stop-Function でスキップ]
    H --> C
    G -->|No| I[SharedSchedules.Refresh]
    I --> J{フィルタ指定?}
    J -->|Yes| K[Schedule/ScheduleUid/Id フィルタ]
    J -->|No| L[全スケジュール取得]
    K --> M[スケジュールループ]
    L --> M
    M --> N[Get-ScheduleDescription]
    N --> O[拡張プロパティ付与]
    O --> P[Select-DefaultView 出力]
    P --> C
    C -->|終了| Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-493-01 | Express Edition 除外 | Express Edition では SQL Agent が存在しないため処理をスキップ | サーバーエディションが Express* にマッチ |
| BR-493-02 | 複数フィルタ併用 | Schedule, ScheduleUid, Id パラメータは組み合わせ可能（OR条件） | 複数フィルタパラメータ指定時 |
| BR-493-03 | データリフレッシュ | 取得前に SharedSchedules コレクションをリフレッシュ | 常時 |
| BR-493-04 | 終了日なしの表示 | ActiveEndDate が年9999の場合は終了日なしを意味する | 説明文生成時 |

### 計算ロジック

**Get-ScheduleDescription 関数による説明文生成**:
- FrequencyTypes に基づく基本説明（Once/Daily/Weekly/Monthly/AutoStart/OnIdle）
- Weekly の場合は曜日をビット演算で解析（日曜=1, 月曜=2, 火曜=4, ...）
- MonthlyRelative の場合は相対位置（First/Second/Third/Fourth/Last）と曜日を組み合わせ
- SubDayTypes に基づく日中繰り返し説明（秒/分/時間単位）
- 開始日・終了日の付与

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スケジュール取得 | msdb.dbo.sysschedules | SELECT | スケジュール情報の取得（SMO経由） |

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

#### msdb.dbo.sysschedules

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | schedule_id, name, schedule_uid, enabled, freq_type, freq_interval など | 全件または名前/UID/IDフィルタ | SMO経由で取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Server への接続失敗 | Stop-Function で Continue、次のインスタンスへ |
| ExpressEdition | 非対応 | Express Edition インスタンス | Stop-Function で Continue、警告メッセージ出力 |

### リトライ仕様

リトライ処理は実装されていない。接続エラー時は次のインスタンスの処理へ継続する。

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- 各インスタンスへの接続は順次処理
- スケジュールの取得はメモリ内で行われる
- Get-ScheduleDescription による説明文生成は各スケジュールで実行

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

- SQL Server への接続には SqlCredential による認証情報指定が可能
- Windows 認証、SQL Server 認証、Active Directory 認証をサポート
- MFA 対応は Connect-DbaInstance を事前に使用する必要あり

## 備考

- Select-DefaultView により、デフォルトでは主要プロパティのみ表示される
- 全プロパティを確認するには `Select-Object *` を使用
- パイプライン入力により複数インスタンスの一括処理が可能
- ScheduleUid は不変の識別子（スケジュール名変更後も維持）

---

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

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

### 推奨読解順序

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

SMO の SharedSchedule オブジェクト構造と FrequencyTypes 列挙型を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | 321行目のデフォルト表示プロパティ定義 |

**読解のコツ**: FrequencyTypes は SMO の列挙型で、1=Once, 4=Daily, 8=Weekly, 16=Monthly, 32=MonthlyRelative, 64=AutoStart, 128=OnIdle を表す。

#### Step 2: 内部関数 Get-ScheduleDescription を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | 120-286行目の Get-ScheduleDescription 関数 |

**主要処理フロー**:
1. **129-132行目**: カルチャに基づく日付・時刻フォーマット取得
2. **135-138行目**: 開始日・終了日・時刻の取得
3. **141-146行目**: FrequencyTypes による基本説明分岐
4. **149-257行目**: 各頻度タイプに応じた詳細説明生成
5. **260-282行目**: サブ日タイプと日付範囲の説明追加

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | 108-117行目のパラメータ定義、288行目の process ブロック開始 |

**主要処理フロー**:
1. **289行目**: foreach ($instance in $SqlInstance) でインスタンスループ開始
2. **291行目**: Connect-DbaInstance で SMO 接続確立
3. **296-298行目**: Express Edition チェック
4. **303行目**: SharedSchedules.Refresh() で最新データ取得
5. **305-319行目**: フィルタリング処理

#### Step 4: フィルタリングと出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | 305-319行目のフィルタリング、323-332行目の出力処理 |

**主要処理フロー**:
- **306-307行目**: Schedule パラメータ指定時は Name -in でフィルタ
- **310-311行目**: ScheduleUid パラメータ指定時は ScheduleUid -in でフィルタ
- **314-315行目**: Id パラメータ指定時は Id -in でフィルタ
- **324行目**: Get-ScheduleDescription で説明文生成
- **326-329行目**: 拡張プロパティ追加

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

```
Get-DbaAgentSchedule
    │
    ├─ begin ブロック
    │      └─ Get-ScheduleDescription 関数定義
    │
    ├─ Connect-DbaInstance
    │      └─ SMO 接続確立
    │
    ├─ Stop-Function
    │      └─ エラー/警告処理
    │
    ├─ $server.JobServer.SharedSchedules.Refresh()
    │      └─ コレクションリフレッシュ
    │
    ├─ Get-ScheduleDescription
    │      ├─ Get-Culture
    │      │      └─ 日付時刻フォーマット取得
    │      └─ Get-Date
    │             └─ 日付時刻変換
    │
    ├─ Add-Member
    │      └─ 拡張プロパティ追加
    │
    └─ Select-DefaultView
           └─ デフォルト表示プロパティ設定
```

### データフロー図

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

SqlInstance ───────────┬─► Connect-DbaInstance ───────────► SMO Server オブジェクト
SqlCredential ─────────┘                                            │
                                                                    ▼
                                               SharedSchedules.Refresh()
                                                            │
Schedule ─────────────────► Where-Object ◄──────────────────┤
ScheduleUid ──────────────► Where-Object ◄──────────────────┤
Id ───────────────────────► Where-Object ◄──────────────────┘
                                    │
                                    ▼
                            各スケジュール
                                    │
                    ┌───────────────┼───────────────┐
                    ▼               ▼               ▼
           FrequencyTypes    SubDayTypes    ActiveDates
                    │               │               │
                    └───────────────┴───────────────┘
                                    │
                                    ▼
                        Get-ScheduleDescription
                                    │
                                    ▼
                             Add-Member (拡張)
                                    │
                                    ▼
                          Select-DefaultView ───────► SharedSchedule オブジェクト
                                                      (説明文付き)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server 接続ヘルパー |
| Stop-Function.ps1 | `internal/functions/Stop-Function.ps1` | ソース | エラー処理ヘルパー |
| Select-DefaultView.ps1 | `internal/functions/Select-DefaultView.ps1` | ソース | デフォルト表示設定 |
