# 機能設計書 511-Remove-DbaAgentSchedule

## 概要

本ドキュメントは、SQL Server Agentスケジュールを削除するdbatools関数「Remove-DbaAgentSchedule」の機能設計書である。

### 本機能の処理概要

Remove-DbaAgentScheduleは、SQL Server Agentのスケジュールをmsdbデータベースから削除する機能を提供する。

**業務上の目的・背景**：SQL Server Agentでは、ジョブの実行タイミングを制御するスケジュールを作成・管理する。運用が長期化すると、不要になったスケジュールが蓄積し、管理の複雑化やリソースの無駄遣いにつながる。本機能は、未使用スケジュールのクリーンアップ、複数スケジュールの統合、ジョブ再編成時のスケジュール削除など、メンテナンス作業を効率化する。

**機能の利用シーン**：
- 定期メンテナンス時の未使用スケジュール整理
- ジョブ統合・再編成時の古いスケジュール削除
- 環境間の設定統一化作業
- 名前が重複するスケジュールの整理

**主要な処理内容**：
1. 対象スケジュールの取得（名前、UID、IDによる指定またはパイプライン入力）
2. スケジュールがジョブに使用されているかの確認
3. ジョブとスケジュールの関連付けの解除（-Force指定時）
4. スケジュールの削除実行
5. TEPPキャッシュからのスケジュール名削除

**関連システム・外部連携**：SQL Server msdbデータベース、SMO (SQL Server Management Objects)

**権限による制御**：sysadmin権限が必要。スケジュールがジョブに使用されている場合、-Forceパラメータなしでは削除が拒否される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio - SQL Agent Schedules | 参照画面 | スケジュール一覧の確認・削除操作 |
| - | PowerShell Console | 主画面 | コマンド実行インターフェース |

## 機能種別

データ削除操作 (DELETE)

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | sysadmin権限、SQL Server 2000以上 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | Windows/SQL認証、AD認証対応 |
| Schedule | string[] | No | 削除するスケジュール名 | 空値不可、エイリアス: Schedules, Name |
| ScheduleUid | string[] | No | 削除するスケジュールのGUID | エイリアス: Uid |
| Id | int[] | No | 削除するスケジュールのID | 数値 |
| InputObject | ScheduleBase[] | No | パイプラインからのスケジュールオブジェクト | Get-DbaAgentScheduleからの出力 |
| EnableException | switch | No | 例外処理を有効化 | - |
| Force | switch | No | ジョブ使用中のスケジュールも強制削除 | - |

### 入力データソース

- Get-DbaAgentScheduleコマンドからのパイプライン入力
- SQL Server JobServer.SharedSchedulesコレクション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Schedule | string | 削除されたスケジュール名 |
| ScheduleId | int | スケジュールID |
| ScheduleUid | Guid | スケジュールのGUID |
| Status | string | 削除操作の結果（"Dropped"または エラーメッセージ） |
| IsRemoved | bool | 削除成功フラグ |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ InputObjectと他パラメータの同時使用をチェック

2. スケジュール取得
   ├─ SqlInstance指定時: Get-DbaAgentScheduleで取得
   └─ InputObject指定時: パイプラインからの入力を使用

3. 各スケジュールの処理（endブロック内）
   ├─ ジョブ使用チェック
   │   ├─ JobCount >= 1 かつ -Forceなし → エラー停止
   │   └─ JobCount >= 1 かつ -Forceあり → 関連付け解除処理
   ├─ ShouldProcess確認
   ├─ ジョブスケジュール関連の解除
   │   └─ 各ジョブのJobSchedulesからDrop
   ├─ TEPPキャッシュ更新
   └─ スケジュール削除（Drop）

4. 結果出力
   └─ PSCustomObjectとして結果を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C[Get-DbaAgentScheduleでスケジュール取得]
    B -->|No| D[InputObjectを使用]
    C --> E{InputObjectと他パラメータの同時使用?}
    D --> E
    E -->|Yes| F[エラー: 同時使用不可]
    E -->|No| G[各スケジュールをループ処理]
    G --> H{JobCount >= 1?}
    H -->|Yes| I{Forceフラグ?}
    I -->|No| J[エラー: スケジュール使用中]
    I -->|Yes| K[ジョブからスケジュール関連を解除]
    H -->|No| L[ShouldProcess確認]
    K --> L
    L --> M[TEPPキャッシュ更新]
    M --> N[スケジュール削除]
    N --> O[結果オブジェクト出力]
    O --> P{次のスケジュール?}
    P -->|Yes| G
    P -->|No| Q[終了]
    F --> Q
    J --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 使用中スケジュール保護 | ジョブに使用されているスケジュールは-Forceなしで削除不可 | JobCount >= 1 の場合 |
| BR-002 | パイプライン排他制御 | InputObject使用時は他の識別パラメータと併用不可 | InputObjectが指定された場合 |
| BR-003 | 削除前関連解除 | -Force指定時、まず全ジョブからスケジュール関連を解除後に削除 | Force かつ JobCount >= 1 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スケジュール削除 | msdb.dbo.sysschedules | DELETE | スケジュール定義の削除 |
| ジョブスケジュール関連解除 | msdb.dbo.sysjobschedules | DELETE | ジョブとスケジュールの関連削除 |

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

#### msdb.dbo.sysschedules

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | schedule_id | 指定されたスケジュールID | SMO Drop()メソッド経由 |

#### msdb.dbo.sysjobschedules

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | schedule_id, job_id | 対象スケジュールに関連するレコード | JobSchedule.Drop(true)経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | FunctionInterrupt | InputObjectと識別パラメータの同時使用 | パラメータを正しく指定 |
| - | Stop-Function | スケジュールがジョブで使用中（Forceなし） | -Forceパラメータを追加 |
| - | Stop-Function | スケジュール削除失敗 | エラーメッセージを確認、権限を確認 |

### リトライ仕様

リトライ機能なし。エラー発生時は-Continueにより次のスケジュール処理を継続。

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

SMOのDrop()メソッドによる暗黙的トランザクション。ジョブスケジュール関連解除とスケジュール削除は個別のトランザクションで実行される。

## パフォーマンス要件

特に定義なし。大量のスケジュール削除時はendブロックでまとめて処理される。

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

- sysadmin権限が必要
- SQL認証、Windows認証、Active Directory認証に対応
- WhatIf/Confirmパラメータによる事前確認が可能

## 備考

- SQL Server 2000以上に対応
- パイプラインからの入力はendブロックで処理されるため、Get-DbaAgentScheduleからの直接パイプでの"Collection was modified"エラーを回避

---

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

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

### 推奨読解順序

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

まず、処理対象となるスケジュールオブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Microsoft.SqlServer.Management.Smo.Agent.ScheduleBase | SMO | スケジュールの基底クラス、JobCount, ScheduleUid等のプロパティ |

**読解のコツ**: SMOのScheduleBaseクラスはJobCountプロパティで使用中ジョブ数を取得でき、EnumJobReferences()メソッドで関連ジョブIDを列挙できる。

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

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

**主要処理フロー**:
1. **112-126行目**: CmdletBinding属性とパラメータ定義
2. **127-129行目**: beginブロック - スケジュール配列の初期化
3. **130-140行目**: processブロック - スケジュールの収集
4. **141-183行目**: endブロック - 実際の削除処理

#### Step 3: 削除処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaAgentSchedule.ps1 | `public/Remove-DbaAgentSchedule.ps1` | endブロック内の削除ロジック |

**主要処理フロー**:
- **142-145行目**: InputObjectと他パラメータの排他チェック
- **147-150行目**: ジョブ使用中チェックとForce確認
- **163-168行目**: ジョブスケジュール関連の解除処理
- **171-172行目**: TEPPキャッシュ更新とスケジュール削除

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

```
Remove-DbaAgentSchedule
    │
    ├─ Get-DbaAgentSchedule (SqlInstance指定時)
    │      └─ Connect-DbaInstance
    │
    ├─ EnumJobReferences() (ジョブ参照の列挙)
    │      └─ GetJobByID() (ジョブオブジェクト取得)
    │
    ├─ JobSchedule.Drop($true) (関連解除)
    │
    ├─ Remove-TeppCacheItem (キャッシュ更新)
    │
    └─ Schedule.Drop() (スケジュール削除)
```

### データフロー図

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

Schedule名/UID/ID ───▶ Get-DbaAgentSchedule ───▶ スケジュールオブジェクト配列
      │                        │
      ▼                        ▼
InputObject ─────────▶ endブロックで統合処理
                              │
                              ▼
                       ジョブ使用チェック
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
              Force=true           Force=false
                    │                   │
                    ▼                   ▼
            関連解除処理          エラー出力
                    │
                    ▼
              スケジュール削除 ───▶ PSCustomObject
                                      │
                                      ▼
                               [パイプライン出力]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaAgentSchedule.ps1 | `public/Remove-DbaAgentSchedule.ps1` | ソース | メイン関数 |
| Get-DbaAgentSchedule.ps1 | `public/Get-DbaAgentSchedule.ps1` | ソース | スケジュール取得（依存関数） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Remove-TeppCacheItem.ps1 | `private/functions/Remove-TeppCacheItem.ps1` | ソース | TABキャッシュ更新 |
