# 画面設計書：ジョブステップ管理

## 1. 基本情報

| 項目 | 内容 |
|------|------|
| 画面ID | 9 |
| 画面名 | ジョブステップ管理 |
| 画面種別 | CLI（コマンドラインインターフェース） |
| カテゴリ | Agent |
| 関連ファイル | public/Get-DbaAgentJobStep.ps1, public/New-DbaAgentJobStep.ps1 |

## 2. 概要・目的

ジョブステップ管理は、SQL Server Agentジョブ内の個別ステップを取得・作成するPowerShellコマンド群です。

ジョブステップは、T-SQL、PowerShell、OSコマンド、SSISパッケージなど様々なサブシステムで実行可能で、成功/失敗時の分岐ロジック、リトライ設定、出力キャプチャなどの詳細な制御が可能です。

## 3. 主要機能

### 3.1 Get-DbaAgentJobStep

SQL Server Agentジョブステップの詳細情報を取得します。

**入力パラメータ：**

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | 条件付き | - | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | いいえ | - | 代替認証情報 |
| Job | string[] | いいえ | - | フィルタするジョブ名 |
| ExcludeJob | string[] | いいえ | - | 除外するジョブ名 |
| ExcludeDisabledJobs | switch | いいえ | false | 無効なジョブを除外 |
| InputObject | Job[] | 条件付き | - | パイプライン入力用ジョブオブジェクト |
| EnableException | switch | いいえ | false | 例外を有効化 |

**出力プロパティ：**

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | SQL Serverインスタンス名 |
| AgentJob | string | 親ジョブ名 |
| Name | string | ステップ名 |
| SubSystem | string | サブシステムタイプ |
| LastRunDate | DateTime | 最終実行日時 |
| LastRunOutcome | string | 最終実行結果 |
| State | string | 現在の状態 |

**追加プロパティ（Select-Object *で取得可能）：**

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ID | int | ステップID |
| CreateDate | DateTime | 作成日時 |
| DateLastModified | DateTime | 最終更新日時 |
| Command | string | 実行コマンド |
| CommandExecutionSuccessCode | int | 成功コード |
| DatabaseName | string | データベース名 |
| DatabaseUserName | string | データベースユーザー名 |
| RetryAttempts | int | リトライ回数 |
| RetryInterval | int | リトライ間隔（分） |
| OutputFileName | string | 出力ファイルパス |

### 3.2 New-DbaAgentJobStep

SQL Server Agentジョブステップを作成します。

**入力パラメータ：**

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | はい | - | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | いいえ | - | 代替認証情報 |
| Job | object[] | はい | - | 対象ジョブ名 |
| StepId | int | いいえ | 末尾 | ステップ実行順序 |
| StepName | string | はい | - | ステップ名 |
| Subsystem | string | いいえ | TransactSql | サブシステムタイプ |
| SubsystemServer | string | いいえ | - | Analysis Services サーバー名 |
| Command | string | いいえ | - | 実行コマンド |
| CmdExecSuccessCode | int | いいえ | - | CmdExec成功コード |
| OnSuccessAction | string | いいえ | QuitWithSuccess | 成功時アクション |
| OnSuccessStepId | int | いいえ | 0 | 成功時移動先ステップID |
| OnFailAction | string | いいえ | QuitWithFailure | 失敗時アクション |
| OnFailStepId | int | いいえ | 0 | 失敗時移動先ステップID |
| Database | string | いいえ | - | データベース名 |
| DatabaseUser | string | いいえ | - | データベースユーザー名 |
| RetryAttempts | int | いいえ | - | リトライ回数 |
| RetryInterval | int | いいえ | - | リトライ間隔（分） |
| OutputFileName | string | いいえ | - | 出力ファイルパス |
| Insert | switch | いいえ | false | ステップ挿入モード |
| Flag | string[] | いいえ | - | ログフラグ |
| ProxyName | string | いいえ | - | プロキシアカウント名 |
| Force | switch | いいえ | false | 強制モード |
| EnableException | switch | いいえ | false | 例外を有効化 |

**サブシステムタイプ：**

| 値 | 説明 |
|----|------|
| TransactSql | T-SQLスクリプト |
| PowerShell | PowerShellスクリプト |
| CmdExec | OSコマンド |
| Ssis | SSISパッケージ |
| AnalysisCommand | SSASコマンド |
| AnalysisQuery | SSASクエリ |
| Distribution | レプリケーション |
| LogReader | ログリーダー |
| Merge | マージレプリケーション |
| QueueReader | キューリーダー |
| Snapshot | スナップショット |

**成功/失敗アクション：**

| 値 | 説明 |
|----|------|
| QuitWithSuccess | ジョブを成功で終了 |
| QuitWithFailure | ジョブを失敗で終了 |
| GoToNextStep | 次のステップへ移動 |
| GoToStep | 指定ステップへ移動 |

**ログフラグ：**

| 値 | 説明 |
|----|------|
| AppendAllCmdExecOutputToJobHistory | コマンド出力をジョブ履歴に追加 |
| AppendToJobHistory | ジョブ履歴に追加 |
| AppendToLogFile | SQLログファイルに追加 |
| AppendToTableLog | テーブルログに追加 |
| LogToTableWithOverwrite | テーブルログを上書き |
| None | ログなし |
| ProvideStopProcessEvent | 処理停止イベント |

## 4. 処理フロー

### 4.1 Get-DbaAgentJobStep

```
[開始]
   ↓
[インスタンス接続]
   ├── Connect-DbaInstanceで接続
   ↓
[ジョブ取得]
   ├── server.JobServer.Jobsを取得
   ↓
[フィルタリング]（endブロック）
   ├── Job名でフィルタ
   ├── ExcludeJobで除外
   ├── ExcludeDisabledJobsで無効除外
   ↓
[ステップ取得]
   ├── InputObject.jobstepsをループ
   ↓
[出力プロパティ追加]
   ├── ComputerName, InstanceName, SqlInstance, AgentJob追加
   ↓
[ステップ情報出力]
   ↓
[終了]
```

### 4.2 New-DbaAgentJobStep

```
[開始]
   ↓
[パラメータ検証]
   ├── OnSuccessStepIdはOnSuccessAction='GoToStep'時のみ有効
   ├── OnFailStepIdはOnFailAction='GoToStep'時のみ有効
   ├── Analysis系SubsystemはSubsystemServer必須
   ↓
[インスタンス接続]
   ├── Connect-DbaInstanceで接続
   ↓
[ジョブ存在確認]
   ├── JobServer.Jobs.Nameに含まれるか確認
   ↓
[ジョブステップオブジェクト作成]
   ├── New-Object Microsoft.SqlServer.Management.Smo.Agent.JobStep
   ├── Parent = currentJob
   ↓
[ステップ名設定]
   ├── [ステップ名重複 + Force未指定] → エラー
   ├── [ステップ名重複 + Force指定] → Remove-DbaAgentJobStepで削除
   ↓
[ステップID設定]
   ├── [StepId未指定] → ジョブステップ数+1
   ├── [StepId指定 + 重複なし] → 指定IDを使用
   ├── [StepId指定 + 重複 + Insert] → 既存ステップを再番号付け
   ├── [StepId指定 + 重複 + Force] → 既存ステップ削除
   ↓
[ステップ設定]
   ├── Subsystem, SubsystemServer設定
   ├── Command設定
   ├── CmdExecSuccessCode設定
   ├── OnSuccessAction, OnSuccessStep設定
   ├── OnFailAction, OnFailStep設定
   ├── Database設定（存在確認）
   ├── DatabaseUser設定（存在確認）
   ├── RetryAttempts, RetryInterval設定
   ├── OutputFileName設定
   ├── ProxyName設定（存在確認）
   ├── Flag設定
   ↓
[ステップ作成]
   ├── jobStep.Create()
   ├── currentJob.Alter()
   ↓
[作成結果出力]
   ↓
[終了]
```

## 5. バリデーションルール

### 5.1 New-DbaAgentJobStep

| 条件 | エラーメッセージ |
|------|----------------|
| OnSuccessStepId>=1でOnSuccessAction!='GoToStep' | "Parameter OnSuccessStepId can only be used with OnSuccessAction 'GoToStep'." |
| OnFailStepId>=1でOnFailAction!='GoToStep' | "Parameter OnFailStepId can only be used with OnFailAction 'GoToStep'." |
| Analysis系SubsystemでSubsystemServer未指定 | "Please enter the server value using -SubSystemServer for subsystem $Subsystem." |
| ステップ名重複（Force未指定） | "The step name $StepName already exists for job $currentJob" |
| ステップID重複（Insert/Force未指定） | "The step id $StepId already exists for job $currentJob" |
| データベース未存在 | "The database is not present on instance $instance." |
| データベースユーザー未存在 | "The database user is not present in the database $Database on instance $instance." |
| プロキシ未存在 | "The proxy name $ProxyName doesn't exist on instance $instance." |

## 6. Insert機能

`-Insert`スイッチを使用すると、指定したStepIdの位置に新しいステップを挿入し、既存ステップのIDと参照を自動的に更新します。

```powershell
# 既存: Step1(ID=1), Step2(ID=2)
New-DbaAgentJobStep -SqlInstance sql1 -Job Job1 -StepName StepA -StepId 2 -Insert
# 結果: Step1(ID=1), StepA(ID=2), Step2(ID=3)
```

**更新される参照：**
- 既存ステップのID（StepId以上のステップ）
- OnFailureStepID（StepId以上を参照するもの）

## 7. 使用例

### 7.1 全ステップ取得

```powershell
Get-DbaAgentJobStep -SqlInstance localhost
```

### 7.2 特定ジョブのステップ取得

```powershell
Get-DbaAgentJobStep -SqlInstance localhost -Job BackupData, BackupDiff
```

### 7.3 有効なジョブのステップのみ取得

```powershell
Get-DbaAgentJobStep -SqlInstance localhost -ExcludeDisabledJobs
```

### 7.4 基本的なステップ作成

```powershell
New-DbaAgentJobStep -SqlInstance sql1 -Job Job1 -StepName Step1
```

### 7.5 データベース指定でステップ作成

```powershell
New-DbaAgentJobStep -SqlInstance sql1 -Job Job1 -StepName Step1 -Database msdb
```

### 7.6 ステップ挿入

```powershell
New-DbaAgentJobStep -SqlInstance sql1 -Job Job1 -StepName StepA -Database msdb -StepId 2 -Insert
```

### 7.7 成功/失敗アクション付きステップ作成

```powershell
$splatStep = @{
    SqlInstance     = 'sql1'
    Job             = 'Job1'
    StepName        = 'MainProcess'
    Command         = 'EXEC dbo.ProcessData'
    Database        = 'MyDB'
    OnSuccessAction = 'GoToNextStep'
    OnFailAction    = 'GoToStep'
    OnFailStepId    = 5
    RetryAttempts   = 3
    RetryInterval   = 5
}
New-DbaAgentJobStep @splatStep
```

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

### 8.1 理解の順序

1. **Get-DbaAgentJobStep.ps1** - ステップ取得の基本構造
2. **New-DbaAgentJobStep.ps1** - ステップ作成と詳細設定

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

```
Get-DbaAgentJobStep
├── Connect-DbaInstance (Line 132)
├── server.JobServer.Jobs (Line 137)
├── Where-Object (Lines 142-148) - フィルタリング
├── InputObject.jobsteps (Line 151)
├── Add-Member (Lines 152-155)
└── Select-DefaultView (Line 157)

New-DbaAgentJobStep
├── Connect-DbaInstance (Line 260)
├── Server.JobServer.Jobs[$j] (Line 274)
├── New-Object JobStep (Line 277)
├── Remove-DbaAgentJobStep (Lines 299, 330) - Force/Insert時
├── jobStep.Create() (Line 440)
└── currentJob.Alter() (Line 441)
```

### 8.3 データフロー図

```
[ユーザー入力]
     │
     ├─[Get-DbaAgentJobStep]──────────────────────────────────────────┐
     │       │                                                        │
     │       └── server.JobServer.Jobs                               │
     │                 │                                              │
     │                 ├── Job フィルタ                               │
     │                 ├── ExcludeJob フィルタ                        │
     │                 ├── ExcludeDisabledJobs フィルタ               │
     │                 │                                              │
     │                 └── .jobsteps ─────────────────────────────────┼─→ [ステップ情報]
     │                                                                │
     └─[New-DbaAgentJobStep]──────────────────────────────────────────┤
             │                                                        │
             ├── パラメータ検証                                       │
             │                                                        │
             ├── Server.JobServer.Jobs[$j]                           │
             │                                                        │
             ├── New-Object JobStep                                   │
             │                                                        │
             ├── プロパティ設定                                       │
             │     ├── Name, ID                                       │
             │     ├── Subsystem, Command                             │
             │     ├── OnSuccessAction, OnFailAction                  │
             │     ├── Database, DatabaseUser                         │
             │     ├── RetryAttempts, RetryInterval                   │
             │     └── ProxyName, Flag                                │
             │                                                        │
             ├── Create()                                             │
             │                                                        │
             └── Alter() ─────────────────────────────────────────────┴─→ [作成されたステップ]
```

### 8.4 関連ファイル一覧

| ファイルパス | 役割 | 行数 |
|-------------|------|------|
| public/Get-DbaAgentJobStep.ps1 | ステップ取得 | 160 |
| public/New-DbaAgentJobStep.ps1 | ステップ作成 | 458 |
| public/Remove-DbaAgentJobStep.ps1 | ステップ削除（依存） | - |
| public/Set-DbaAgentJobStep.ps1 | ステップ設定変更（関連） | - |
| public/Get-DbaAgentJob.ps1 | ジョブ取得（依存） | - |

### 8.5 重要コードポイント

#### ステップ挿入時のID再番号付け（New-DbaAgentJobStep.ps1: Lines 314-324）
```powershell
if (($currentJob.JobSteps.ID -contains $StepID) -and $Insert) {
    foreach ($tStep in $currentJob.JobSteps) {
        if ($tStep.Id -ge $Stepid) {
            $tStep.Id = ($tStep.ID) + 1
        }
        if ($tStep.OnFailureStepID -ge $StepId -and $tStep.OnFailureStepId -ne 0) {
            $tStep.OnFailureStepID = ($tStep.OnFailureStepID) + 1
        }
    }
    $jobStep.ID = $StepId
}
```

#### ステップ作成と親ジョブ更新（New-DbaAgentJobStep.ps1: Lines 440-441）
```powershell
$jobStep.Create()
$currentJob.Alter()
```

## 9. 権限要件

| 操作 | 必要な権限 |
|------|----------|
| Get-DbaAgentJobStep | SQLAgentReaderRole以上 |
| New-DbaAgentJobStep | SQLAgentOperatorRole以上 |

## 10. 関連コマンド

- Get-DbaAgentJob - ジョブ取得
- New-DbaAgentJob - ジョブ作成
- Set-DbaAgentJobStep - ジョブステップ設定変更
- Remove-DbaAgentJobStep - ジョブステップ削除
- Get-DbaAgentProxy - プロキシアカウント取得
