# 機能設計書 386-Add-DbaPfDataCollectorCounter

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるAdd-DbaPfDataCollectorCounter機能の設計仕様を記載する。本機能は、SQL Serverモニタリング用の既存Windows Performance Monitor Data Collector Setにパフォーマンスカウンターを追加する。

### 本機能の処理概要

本機能は、Windows Performance Monitor内の既存Data Collector Setに特定のパフォーマンスカウンターを追加する。これにより、DBAsはディスクキュー長、プロセッサ時間、SQL Serverオブジェクトカウンターなどの SQL Server固有のカウンターを既存のコレクションセットに追加して、パフォーマンスモニタリングをカスタマイズできる。

**業務上の目的・背景**：SQL Serverの性能問題診断やベースライン測定において、適切なパフォーマンスカウンターを収集することは重要である。既存のData Collector Setに必要なカウンターを追加することで、モニタリングセットアップを再作成することなく、監視対象を拡張できる。

**機能の利用シーン**：
- SQL Server固有のパフォーマンスカウンターの追加
- 既存のシステム監視セットへのカスタムカウンター追加
- 複数サーバーへの標準化されたカウンターセットの展開
- 性能問題発生時の追加メトリクス収集

**主要な処理内容**：
1. 対象のData CollectorオブジェクトをGet-DbaPfDataCollectorで取得（または入力オブジェクトから）
2. Data Collector SetのXML設定を解析
3. 新しいカウンターをXMLに追加
4. 更新されたXMLをData Collector Setにコミット
5. 追加されたカウンター情報を出力

**関連システム・外部連携**：Windows Performance Monitor（Pla.DataCollectorSet COMオブジェクト）。

**権限による制御**：対象コンピュータでの管理者権限（昇格したセッション）が必要。

## 関連画面

本機能はCLIベースのPowerShellコマンドレットであり、GUI画面との直接的な関連はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | PowerShellコンソール | 主画面 | コマンド実行とカウンター追加結果表示 |
| - | Windows Performance Monitor | 参照画面 | 追加されたカウンターの確認 |

## 機能種別

設定変更 / オブジェクト追加

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstance[] | No | Data Collector Setがあるコンピュータ。デフォルトはローカル | - |
| Credential | PSCredential | No | リモートコンピュータ接続用資格情報 | - |
| CollectorSet | string[] | No | 対象Data Collector Set名（エイリアス: DataCollectorSet） | - |
| Collector | string[] | No | 対象Data Collector名（エイリアス: DataCollector） | - |
| Counter | object[] | Yes | 追加するパフォーマンスカウンターパス（エイリアス: Name） | Mandatory, ValueFromPipelineByPropertyName |
| InputObject | object[] | No | Get-DbaPfDataCollectorからのパイプライン入力 | - |
| WhatIf | switch | No | 実行せず影響を表示 | - |
| Confirm | switch | No | 実行前に確認を要求 | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- パイプライン入力：InputObjectがValueFromPipelineをサポート
- CounterパラメータはValueFromPipelineByPropertyNameをサポート（Get-DbaPfAvailableCounterからの入力）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | Data Collector Setがあるコンピュータ名 |
| DataCollectorSet | string | 親Data Collector Set名 |
| DataCollector | string | Data Collector名 |
| Name | string | 追加されたパフォーマンスカウンターのフルパス |
| FileName | string | パフォーマンスデータが保存されるファイル名 |

### 出力先

PowerShellパイプラインへPSCustomObjectとして出力（Select-DefaultViewで表示制御）。

## 処理フロー

### 処理シーケンス

```
1. 入力の処理
   └─ InputObjectのCredentialを継承（未指定時）
   └─ Get-DbaPfAvailableCounterからの入力を識別
2. Data Collectorの取得
   └─ InputObject未指定時: Get-DbaPfDataCollectorで取得
3. 入力検証
   └─ DataCollectorObjectプロパティの存在確認
4. 各Data Collectorに対してループ
   └─ XML設定を解析
5. 各カウンターに対してループ
   └─ Counter要素をXMLに追加
   └─ CounterDisplayName要素をXMLに追加
6. XML変更のコミット
   └─ Invoke-Command2でCOMオブジェクト経由でコミット
7. 結果取得
   └─ Get-DbaPfDataCollectorCounterで追加されたカウンターを取得
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObjectにCredentialあり?}
    B -->|Yes| C[Credentialを継承]
    B -->|No| D[入力タイプ判定]
    C --> D
    D --> E{Get-DbaPfAvailableCounterからの入力?}
    E -->|Yes| F[ComputerName/Counter抽出]
    E -->|No| G{InputObject指定あり?}
    F --> G
    G -->|No| H[Get-DbaPfDataCollectorでCollector取得]
    G -->|Yes| I{DataCollectorObject存在?}
    H --> I
    I -->|No| J[エラー: 不正な入力タイプ]
    I -->|Yes| K[各Data Collectorでループ]
    K --> L[XML設定を解析]
    L --> M[各カウンターでループ]
    M --> N[Counter要素追加]
    N --> O[CounterDisplayName要素追加]
    O --> P{次のカウンターあり?}
    P -->|Yes| M
    P -->|No| Q[ShouldProcess確認]
    Q --> R[Invoke-Command2でXMLコミット]
    R --> S[Get-DbaPfDataCollectorCounterで結果取得]
    S --> T{次のData Collectorあり?}
    T -->|Yes| K
    T -->|No| U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | カウンターパス形式 | '\Processor(_Total)\% Processor Time'形式のフルパス | 常時 |
| BR-002 | Commitモード | 0x0003（追加または変更）でコミット | 常時 |
| BR-003 | 昇格権限 | Test-ElevationRequirementで管理者権限確認 | 常時 |
| BR-004 | ConfirmImpact | Low設定 | 常時 |

### 計算ロジック

XMLへのカウンター追加:
```powershell
$node = $xml.SelectSingleNode("//Name[.='$collectorname']")
$newitem = $xml.CreateElement('Counter')
$newitem.PsBase.InnerText = $countername
$node.ParentNode.AppendChild($newitem)
```

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

本機能はデータベースを操作しない。

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | Windows Performance Monitor設定のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 入力タイプエラー | DataCollectorObjectプロパティがない | Get-DbaPfDataCollectorまたはGet-DbaPfAvailableCounterからの入力を使用 |
| - | コミットエラー | XMLコミット失敗 | 権限・接続を確認 |
| - | リモート接続エラー | Invoke-Command2失敗 | 認証情報・ネットワークを確認 |

### リトライ仕様

リトライ機能は実装されていない。

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

COMオブジェクトのCommitメソッドでアトミックに適用。

## パフォーマンス要件

- XML操作は軽量
- リモートコンピュータへの接続はInvoke-Command2で実行

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

- 管理者権限（昇格）が必要
- Credentialパラメータでリモート認証可能

## 備考

- Get-DbaPfAvailableCounterと組み合わせて使用可能
- SupportsShouldProcessでWhatIf/Confirmサポート
- 追加後はGet-DbaPfDataCollectorCounterで結果を取得

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | 出力オブジェクト構造（56-72行目の.OUTPUTS） |

**読解のコツ**: Data Collector SetのXML構造を理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | パラメータ定義（84-98行目） |
| 2-2 | Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | beginブロック（99-107行目） |

**主要処理フロー**:
1. **84-98行目**: パラメータ定義。Counterは必須、Mandatory
2. **100-106行目**: setscript定義（COMオブジェクト操作）

#### Step 3: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | 入力処理（108-131行目） |
| 3-2 | Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | XML操作とコミット（133-160行目） |

**主要処理フロー**:
- **109-118行目**: Get-DbaPfAvailableCounterからの入力を識別
- **120-124行目**: InputObject未指定時のData Collector取得
- **133-148行目**: XMLへのカウンター追加
- **152-158行目**: Invoke-Command2でCOMオブジェクトコミット

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

```
Add-DbaPfDataCollectorCounter
    │
    ├─ Get-DbaPfDataCollector
    │      └─ Data Collectorオブジェクト取得
    │
    ├─ Test-ElevationRequirement
    │      └─ 管理者権限確認
    │
    ├─ Invoke-Command2
    │      └─ setscript実行（COMオブジェクト操作）
    │
    └─ Get-DbaPfDataCollectorCounter
           └─ 追加されたカウンターの取得
```

### データフロー図

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

CollectorSet ───┐
                │
Collector ──────┤
                │
Counter ────────┼──▶ XML解析・編集 ──▶ PSCustomObject
                │    ▼                   │
InputObject ────┘    COMオブジェクト     ├─ ComputerName
                     コミット            ├─ DataCollectorSet
                                         ├─ DataCollector
                                         ├─ Name
                                         └─ FileName
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | ソース | メイン機能実装 |
| Add-DbaPfDataCollectorCounter.Tests.ps1 | `tests/Add-DbaPfDataCollectorCounter.Tests.ps1` | テスト | 単体テスト |
| Get-DbaPfDataCollector.ps1 | `public/Get-DbaPfDataCollector.ps1` | 依存 | Data Collector取得 |
| Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | 関連 | 利用可能カウンター取得 |
| Get-DbaPfDataCollectorCounter.ps1 | `public/Get-DbaPfDataCollectorCounter.ps1` | 依存 | 結果取得 |
