# 機能設計書 523-Test-DbaAgentJobOwner

## 概要

本ドキュメントは、SQL Agent ジョブの所有者をセキュリティコンプライアンス観点から監査する `Test-DbaAgentJobOwner` コマンドの機能設計書です。

### 本機能の処理概要

SQL Server Agent ジョブの所有権を監査し、期待される所有者（通常は 'sa'）と異なるジョブを特定する PowerShell コマンドです。セキュリティベストプラクティスに基づいた所有権検証を行います。

**業務上の目的・背景**：SQL Server Agent ジョブが不適切なアカウントで所有されていると、セキュリティリスクが生じます。所有者アカウントが無効化、削除、または権限が削減された場合、ジョブの実行に影響が出る可能性があります。ベストプラクティスとして、ジョブは 'sa' または専用のsysadminアカウントで所有されるべきです。本コマンドは、この標準に準拠していないジョブを特定し、セキュリティコンプライアンス監査を支援します。

**機能の利用シーン**：
- セキュリティ監査での所有権チェック
- 定期的なコンプライアンスレポート生成
- 移行前の所有権標準化確認
- 新しいセキュリティポリシー適用時の影響分析
- 異なるログインを使用している場合のジョブ特定

**主要な処理内容**：
1. SQL Server インスタンスへの接続確立
2. ターゲットログインの検証
3. SQL Agent ジョブの収集
4. 各ジョブの所有者を期待値と比較
5. 不一致ジョブの結果出力

**関連システム・外部連携**：SQL Server Agent サービス、msdb データベース

**権限による制御**：SQLAgentReaderRole 以上の権限が必要です。ジョブ情報の読み取りにはジョブサーバーへのアクセス権が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio - SQL Server Agent Jobs | 参照画面 | ジョブプロパティでの所有者確認と同等の監査機能 |

## 機能種別

監査 / セキュリティコンプライアンス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象の SQL Server インスタンス | 有効なインスタンス名 |
| SqlCredential | PSCredential | No | 代替認証情報 | 有効な資格情報オブジェクト |
| Job | object[] | No | チェック対象のジョブ名 | - |
| ExcludeJob | object[] | No | 除外するジョブ名 | - |
| Login | string | No | 期待される所有者ログイン（デフォルト: sa） | サーバー上の有効なログイン |
| EnableException | switch | No | 例外をスローする | - |

### 入力データソース

- SQL Server Agent JobServer オブジェクト経由でジョブ情報を取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Server | string | SQL Server インスタンス名 |
| Job | string | ジョブ名 |
| JobType | string | ジョブタイプ（Remote/LocalJob/その他） |
| CurrentOwner | string | 現在の所有者ログイン名 |
| TargetOwner | string | 期待される所有者ログイン名 |
| OwnerMatch | bool | 所有者が一致するかどうか |

### 出力先

- PowerShell パイプライン出力（PSCustomObject）
- デフォルトでは OwnerMatch = $false のジョブのみ出力

## 処理フロー

### 処理シーケンス

```
1. 変数初期化
   └─ $return 配列を空で初期化
2. SQL Server インスタンスへの接続
   └─ Connect-DbaInstance を使用
3. ターゲットログインの検証
   └─ 指定ログインがサーバー上に存在するか確認
   └─ Windows グループでないことを確認
4. デフォルトログインの設定
   └─ 指定がない場合は 'sa' を使用
   └─ sa の場合は ID=1 のログイン名を取得（リネーム対応）
5. ジョブコレクションの収集
   └─ -Job 指定時: 指定ジョブのみ
   └─ -ExcludeJob 指定時: 除外適用
   └─ 指定なし: 全ジョブ
6. 各ジョブの所有権チェック
   └─ CategoryID=1（Remote）は常に一致として扱う
   └─ その他は実際の所有者と比較
7. 結果フィルタリング
   └─ -Job 指定時: 全ジョブを返す
   └─ 指定なし: OwnerMatch=$false のみ返す
8. 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQL Server 接続]
    B --> C{Login 指定?}
    C -->|Yes| D{ログイン存在?}
    D -->|No| E[エラー終了]
    D -->|Yes| F{Windows Group?}
    F -->|Yes| E
    F -->|No| G[Login 設定]
    C -->|No| H[Login = sa]
    H --> I{sa リネーム確認}
    I --> J[ID=1 のログイン名取得]
    G --> K[ジョブ収集]
    J --> K
    K --> L[各ジョブをループ]
    L --> M{CategoryID=1?}
    M -->|Yes| N[OwnerMatch=true]
    M -->|No| O{Owner=Login?}
    O -->|Yes| N
    O -->|No| P[OwnerMatch=false]
    N --> Q[結果オブジェクト作成]
    P --> Q
    Q --> R{次のジョブ?}
    R -->|Yes| L
    R -->|No| S{-Job 指定?}
    S -->|Yes| T[全結果出力]
    S -->|No| U[不一致のみ出力]
    T --> V[終了]
    U --> V
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ログイン検証 | 指定ログインはサーバー上に存在する必要がある | -Login 指定時 |
| BR-002 | Windows グループ禁止 | Windows グループはジョブ所有者になれない | -Login 指定時 |
| BR-003 | sa デフォルト | Login 未指定時は 'sa' を使用 | -Login 未指定時 |
| BR-004 | sa リネーム対応 | ID=1 のログイン名を取得して sa リネームに対応 | Login='sa' 時 |
| BR-005 | Remote ジョブ例外 | CategoryID=1 のジョブは常に一致として扱う | 常時 |
| BR-006 | 出力フィルタ | -Job 未指定時は不一致ジョブのみ出力 | -Job 未指定時 |

### 計算ロジック

- OwnerMatch = (CategoryID == 1) ? true : (OwnerLoginName == TargetLogin)

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ログイン確認 | sys.server_principals | SELECT (間接) | SMO 経由でログイン情報取得 |
| ジョブ取得 | msdb.dbo.sysjobs | SELECT (間接) | SMO 経由でジョブ情報取得 |

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

#### msdb.dbo.sysjobs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name, owner_sid, category_id | 全ジョブまたは指定ジョブ | SMO の Jobs コレクション経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | SQL Server に接続できない | 接続情報を確認 |
| - | ログインエラー | 指定ログインが存在しない | 有効なログイン名を指定 |
| - | グループエラー | Windows グループを指定 | 個別ログインを指定 |

### リトライ仕様

リトライなし（読み取り専用操作）

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

読み取り専用操作のためトランザクションなし

## パフォーマンス要件

- 読み取り専用操作のため高速に完了
- ジョブ数に比例した処理時間

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

- SQLAgentReaderRole 以上の権限が必要
- ジョブ所有権情報のみを読み取り
- セキュリティ監査目的での使用を想定

## 備考

- ベストプラクティス参照: https://www.itprotoday.com/sql-server-tip-assign-ownership-jobs-sysadmin-account
- Remote ジョブ（CategoryID=1）は特別扱い

---

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

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

### 推奨読解順序

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

出力は PSCustomObject で、所有権比較結果を含みます。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Test-DbaAgentJobOwner.ps1 | `public/Test-DbaAgentJobOwner.ps1` | 出力オブジェクトの構造（147-155行目） |

**読解のコツ**: [ordered] ハッシュテーブルで順序付きプロパティを定義しています。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Test-DbaAgentJobOwner.ps1 | `public/Test-DbaAgentJobOwner.ps1` | 関数定義とパラメータ |

**主要処理フロー**:
1. **79-91行目**: パラメータ定義
2. **93-96行目**: begin ブロックで $return 初期化
3. **97-164行目**: process ブロックでメイン処理
4. **166-168行目**: end ブロックで結果出力

#### Step 3: ログイン検証ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Test-DbaAgentJobOwner.ps1 | `public/Test-DbaAgentJobOwner.ps1` | ログイン検証処理 |

**主要処理フロー**:
- **105-118行目**: ログイン存在確認と Windows グループチェック
- **120-131行目**: デフォルトログイン設定と sa リネーム対応

#### Step 4: 所有権比較ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Test-DbaAgentJobOwner.ps1 | `public/Test-DbaAgentJobOwner.ps1` | 所有権比較処理 |

**主要処理フロー**:
- **145-158行目**: 各ジョブの所有権チェックと結果オブジェクト作成
- **150-153行目**: JobType と OwnerMatch の計算ロジック
- **159-163行目**: 結果フィルタリング

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

```
Test-DbaAgentJobOwner
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Server SMO 接続確立
    │
    ├─ $server.Logins
    │      └─ ログイン検証
    │
    ├─ $server.JobServer.Jobs
    │      └─ ジョブコレクション取得
    │
    └─ Select-DefaultView
           └─ 出力プロパティ設定
```

### データフロー図

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

SqlInstance ───▶ Connect-DbaInstance ───▶ SMO Server Object
                         │
Login ─────────▶ Logins Validation ────▶ Target Login Name
                         │
Job/ExcludeJob ─▶ Jobs Collection ─────▶ Job Objects
                         │
                  Owner Comparison ────▶ Match Results
                         │
                  Result Filter ───────▶ PSCustomObject[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Test-DbaAgentJobOwner.ps1 | `public/Test-DbaAgentJobOwner.ps1` | ソース | メイン関数定義 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server 接続 |
