# 機能設計書 235-Stop-DbaExternalProcess

## 概要

本ドキュメントは、dbatools PowerShellモジュールのStop-DbaExternalProcess関数に関する機能設計書です。この関数はSQL Serverインスタンスによって生成されたオペレーティングシステムプロセスを終了します。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverがxp_cmdshell、BCP操作、SSISパッケージ、外部スクリプト実行などで生成した外部プロセスが応答しなくなった場合に、パフォーマンス問題を解決するための手段を提供します。特にWAITFOR_RESULTSやEXTERNAL_SCRIPT_NETWORK_IOなどの外部待機タイプを示すハングしたSQL Serverセッションのトラブルシューティングに有効です。

**機能の利用シーン**：SQL Serverが外部プロセスの完了を待機していてそのプロセスが応答しなくなった場合、xp_cmdshell経由で起動したプロセスがハングした場合、外部待機タイプを持つセッションのトラブルシューティング時に使用されます。

**主要な処理内容**：
1. 対象コンピュータのプロセス情報をWMI経由で取得
2. 指定されたプロセスIDのプロセス名を特定
3. リモートコンピュータ上でStop-Processを実行
4. 終了結果をオブジェクトとして返却

**関連システム・外部連携**：WMI (Windows Management Instrumentation)、PowerShell Remoting、Get-DbaExternalProcessとの連携を使用します。

**権限による制御**：対象コンピュータへの管理者権限およびリモートプロセス終了権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | CLIコマンド | 主機能 | PowerShellコマンドラインから直接実行 |

## 機能種別

プロセス管理処理（Process Management）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter | Yes | 対象Windowsサーバー | パイプライン入力対応 |
| Credential | PSCredential | No | リモートコンピュータ認証用資格情報 | パイプライン入力対応 |
| ProcessId | int | No | 終了するプロセスID | パイプライン入力対応、別名"pid" |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- PowerShellコマンドライン引数
- Get-DbaExternalProcessからのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | プロセスが終了されたコンピュータ名 |
| ProcessId | int | 終了されたプロセスID |
| Name | string | 終了されたプロセス名/実行ファイル名 |
| Status | string | 操作ステータス（常に"Stopped"） |

### 出力先

- パイプラインにPSCustomObjectとして出力

## 処理フロー

### 処理シーケンス

```
1. プロセス情報取得
   └─ Get-DbaCmObjectでWin32_Processからプロセス名取得
2. プロセス名の文字列変換
   └─ ToString()でnull対策
3. プロセス終了実行
   └─ Invoke-Command2経由でStop-Process実行
4. 結果出力
   └─ PSCustomObjectとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[WMIでプロセス情報取得]
    B --> C[プロセス名取得]
    C --> D{ShouldProcess確認}
    D -->|Yes| E[Invoke-Command2でStop-Process実行]
    D -->|No| F[スキップ]
    E --> G{成功?}
    G -->|Yes| H[結果オブジェクト出力]
    G -->|No| I[エラー処理]
    H --> J[終了]
    I --> J
    F --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 確認プロンプト | ConfirmImpact = "High"で確認を要求 | 常時 |
| BR-002 | プロセス名事前取得 | 終了前にプロセス名を取得（終了後は取得不可のため） | 常時 |
| BR-003 | 強制終了 | Stop-Process -Forceで強制終了 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし（OS操作のみ） |

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

データベース操作はありません。WMI経由でOSプロセス情報を操作します。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ProcessKillError | プロセス終了エラー | プロセス終了失敗 | 権限・プロセス存在確認 |
| WMIError | WMI接続エラー | WMIアクセス失敗 | リモート接続・認証確認 |

### リトライ仕様

リトライ処理は実装されていません。エラー発生時はStop-Functionで処理を継続（Continue）します。

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

トランザクション管理は不要です（OS操作のみ）。

## パフォーマンス要件

- プロセス終了は即時実行
- WMI接続にはネットワーク遅延の影響あり

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

- 対象コンピュータへの管理者権限が必要
- Credential使用時はSecureStringで資格情報を保護
- ShouldProcess対応で誤操作を防止

## 備考

- Get-DbaExternalProcessと組み合わせて使用することを推奨
- 参考URL: https://web.archive.org/web/20201027122300/http://vickyharp.com/2013/12/killing-sessions-with-external-wait-types/

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Stop-DbaExternalProcess.ps1 | `public/Stop-DbaExternalProcess.ps1` | パラメータ定義（69-78行目） |
| 1-2 | Stop-DbaExternalProcess.ps1 | `public/Stop-DbaExternalProcess.ps1` | 出力オブジェクト構造（90-95行目） |

**読解のコツ**: ValueFromPipelineByPropertynameにより、Get-DbaExternalProcessの出力をそのままパイプラインで受け取れます。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Stop-DbaExternalProcess.ps1 | `public/Stop-DbaExternalProcess.ps1` | process block（79-100行目） |

**主要処理フロー**:
1. **82-83行目**: Get-DbaCmObjectでプロセス名取得、ToString()でnull対策
2. **85行目**: ShouldProcessで確認
3. **86-88行目**: Invoke-Command2でリモートStop-Process実行
4. **90-95行目**: 結果オブジェクト生成と出力

#### Step 3: 関連コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaExternalProcess.ps1 | `public/Get-DbaExternalProcess.ps1` | 入力元となる機能 |
| 3-2 | Get-DbaCmObject.ps1 | `public/Get-DbaCmObject.ps1` | WMIアクセス方法 |

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

```
Stop-DbaExternalProcess
    │
    ├─ Get-DbaCmObject
    │      └─ Win32_Process WMIクラスからプロセス情報取得
    │
    └─ Invoke-Command2
           └─ Stop-Process -Id $ProcessId -Force
```

### データフロー図

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

ComputerName ─────┐
                  │
Credential ───────┼──▶ Stop-DbaExternalProcess ────────▶ PSCustomObject
                  │         │                              (ComputerName,
ProcessId ────────┤         ├─ Get-DbaCmObject              ProcessId,
                  │         │     └─ プロセス名取得          Name,
EnableException ──┘         │                               Status)
                            └─ Invoke-Command2
                                  └─ Stop-Process

[WMI Win32_Process] ◄───── Query ─────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Stop-DbaExternalProcess.ps1 | `public/Stop-DbaExternalProcess.ps1` | ソース | メイン関数実装 |
| Get-DbaExternalProcess.ps1 | `public/Get-DbaExternalProcess.ps1` | ソース | 入力元となる機能 |
| Get-DbaCmObject.ps1 | `public/Get-DbaCmObject.ps1` | ソース | WMIアクセスヘルパー |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | リモート実行ヘルパー |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理ヘルパー |
