# 機能設計書 124-Get-DbaExternalProcess

## 概要

本ドキュメントは、SQL Serverインスタンスによって生成された外部プロセス（子プロセス）を取得するGet-DbaExternalProcess機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaExternalProcessは、SQL Server（sqlservr.exe）を親プロセスとして生成されたOSレベルの子プロセスを検出・列挙する機能である。xp_cmdshell、BCP操作、SSISパッケージ、その他の外部ユーティリティによって起動されたプロセスを識別できる。

**業務上の目的・背景**：SQL Serverセッションが外部待機型（External Wait Types）でハングしている場合、どの外部プロセスが原因かを特定する必要がある。WAITFOR_RESULTSやEXTERNAL_SCRIPT_NETWORK_IOなどの待機タイプが発生している際に、本機能で具体的な外部プロセスを特定し、トラブルシューティングを効率化できる。

**機能の利用シーン**：
- 外部待機型でハングしているSQLセッションのトラブルシューティング
- xp_cmdshellで実行された外部コマンドの監視
- BCP操作やSSIS実行状況の確認
- SQL Serverから起動されたプロセスのリソース使用状況分析

**主要な処理内容**：
1. WMI経由でsqlservr.exeプロセスのProcessIDを取得
2. 親プロセスIDがSQL ServerであるプロセスをWMIで検索
3. 各プロセスの詳細情報（メモリ使用量、ハンドル数等）を取得
4. 結果をPSCustomObjectとして出力

**関連システム・外部連携**：WMI (Windows Management Instrumentation)、CIM (Common Information Model)

**権限による制御**：対象コンピュータへのWMIアクセス権限が必要。通常は管理者権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コンソール/ターミナル | 主画面 | コマンド実行と結果表示 |

## 機能種別

データ取得(SELECT) / 診断・トラブルシューティング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | Yes | 対象コンピュータ名（SQL Serverインスタンス名も可、コンピュータ名に自動解決） | Mandatory, ValueFromPipeline |
| Credential | PSCredential | No | WMI接続用のWindows資格情報 | - |
| EnableException | switch | No | 例外を直接スローするか | - |

### 入力データソース

- コンピュータ名（SQL Serverホスト）
- WMI（Win32_Process）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | DbaInstanceParameter | 対象コンピュータ名 |
| Credential | PSCredential | 使用されたWMI接続資格情報 |
| ProcessId | uint32 | 子プロセスのプロセスID |
| Name | string | 子プロセスの実行ファイル名（例: cmd.exe, bcp.exe） |
| HandleCount | uint32 | 子プロセスが保持するオープンハンドル数 |
| WorkingSetSize | uint64 | 子プロセスが現在使用しているメモリ（バイト） |
| VirtualSize | uint64 | 子プロセスが予約している仮想アドレス空間（バイト） |
| CimObject | CIM_Process | 基となるWMIプロセスオブジェクト（全プロパティにアクセス可能） |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力（Select-DefaultViewで主要プロパティを表示）

## 処理フロー

### 処理シーケンス

```
1. 各ComputerNameをループ処理
   └─ 複数コンピュータ対応

2. Get-DbaCmObjectでsqlservr.exeプロセスを検索
   └─ win32_processクラスからProcessName="sqlservr.exe"を取得

3. SQL ServerのProcessIDを親とする子プロセスを検索
   └─ ParentProcessId -in $sqlpid でフィルタリング

4. 各子プロセスの情報をPSCustomObjectに変換
   └─ ProcessId, Name, HandleCount, WorkingSetSize, VirtualSize

5. Select-DefaultViewで出力プロパティを制御
   └─ CimObjectは分析用に保持
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ComputerNameループ}
    B -->|各コンピュータ| C[Get-DbaCmObject: sqlservr.exe取得]
    C --> D[SQL Server ProcessID抽出]
    D --> E[Get-DbaCmObject: 子プロセス検索]
    E --> F{子プロセスあり?}
    F -->|Yes| G{子プロセスループ}
    F -->|No| B
    G -->|各プロセス| H[PSCustomObject作成]
    H --> I[Select-DefaultView出力]
    I --> G
    G -->|終了| B
    B -->|全コンピュータ完了| J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | SQL Server子プロセスのみ | ParentProcessIdがsqlservr.exeのプロセスのみ返却 | 全ての検索 |
| BR-002 | 複数インスタンス対応 | 同一サーバー上の複数SQL Serverインスタンスの子プロセスを全て取得 | 複数インスタンス環境 |
| BR-003 | 子プロセスなし時 | 子プロセスがない場合は何も返さない | 通常運用時 |

### 計算ロジック

特になし（WMIからの値をそのまま返却）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | SQL Serverへの直接接続なし（WMI経由のみ） |

### WMIアクセス詳細

#### Win32_Process

| 操作 | 項目（プロパティ名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | ProcessId, ProcessName, ParentProcessId, HandleCount, WorkingSetSize, VirtualSize | ProcessName="sqlservr.exe"またはParentProcessId=SQL Server PID | Get-DbaCmObject経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | WMIアクセスエラー | WMI接続失敗またはアクセス拒否 | Stop-Function -Continueで次のコンピュータへ |

### リトライ仕様

リトライ処理なし。エラー発生時は警告出力後に次のコンピュータを処理。

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

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

## パフォーマンス要件

- WMIアクセスのため、リモートサーバーでは若干の遅延あり
- 複数コンピュータ指定時は順次処理

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

- 対象コンピュータへのWMIアクセス権限（通常は管理者権限）が必要
- Credentialパラメータで代替Windows資格情報を指定可能
- SQL Server認証は不使用（OSレベルのプロセス情報のみ）

## 備考

- xp_cmdshell、BCP、SSISなどで起動された外部プロセスを検出可能
- CimObjectプロパティからWin32_Processの全プロパティにアクセス可能
- 参考URL: http://vickyharp.com/2013/12/killing-sessions-with-external-wait-types/

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaExternalProcess.ps1 | `public/Get-DbaExternalProcess.ps1` | 関数の全体構造とパラメータ定義 |

**主要処理フロー**:
1. **60-66行目**: パラメータ定義（ComputerNameはMandatory、ValueFromPipeline）
2. **70行目**: Get-DbaCmObjectでsqlservr.exeプロセス取得
3. **71行目**: ParentProcessIdがSQL Serverの子プロセスを検索
4. **73-83行目**: 各子プロセスをPSCustomObjectに変換して出力
5. **85-86行目**: エラー時はStop-Function -Continueで継続

**読解のコツ**:
- Get-DbaCmObjectは内部関数でWMI/CIMのラッパー
- Where-Object ProcessName -eq "sqlservr.exe"でSQL Serverプロセスを特定
- ParentProcessId -in $sqlpidで子プロセスをフィルタリング（複数インスタンス対応）

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

```
Get-DbaExternalProcess
    │
    ├─ Get-DbaCmObject (sqlservr.exe検索)
    │      └─ win32_process WMIクエリ
    │
    ├─ Get-DbaCmObject (子プロセス検索)
    │      └─ ParentProcessIdフィルタリング
    │
    └─ Select-DefaultView (出力フォーマット)
```

### データフロー図

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

ComputerName   ───▶  Get-DbaCmObject           ───▶  sqlservr.exe PID取得
                           │
                     Get-DbaCmObject           ───▶  子プロセス検索
                           │                         (ParentProcessId)
                     PSCustomObject変換        ───▶
                           │
                     Select-DefaultView        ───▶  パイプライン出力
                                                     (ComputerName,
                                                      ProcessId, Name,
                                                      HandleCount,
                                                      WorkingSetSize,
                                                      VirtualSize,
                                                      CimObject)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaExternalProcess.ps1 | `public/Get-DbaExternalProcess.ps1` | ソース | メイン関数定義 |
| Get-DbaExternalProcess.Tests.ps1 | `tests/Get-DbaExternalProcess.Tests.ps1` | テスト | 単体・統合テスト |
| Get-DbaCmObject.ps1 | `functions/Get-DbaCmObject.ps1` | ソース | WMI/CIMアクセスラッパー |
