# 機能設計書 389-Get-DbaPfAvailableCounter

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるGet-DbaPfAvailableCounter機能の設計仕様を記載する。本機能は、ローカルまたはリモートマシンで利用可能なすべてのWindowsパフォーマンスカウンターを取得する。

### 本機能の処理概要

本機能は、指定されたマシンで利用可能なすべてのWindowsパフォーマンスカウンターをレジストリから直接読み取り、高速に列挙する。SQL Serverモニタリング設定時に、Data CollectorやPerformance Monitor設定前に利用可能なカウンターを確認するために使用される。

**業務上の目的・背景**：SQL Serverモニタリングをセットアップする際、どのパフォーマンスカウンターが利用可能かを事前に把握する必要がある。従来のGet-Counterメソッドは遅く、大量のカウンターを発見するには実用的ではない。本機能は、レジストリベースのアプローチにより高速な列挙を実現し、複数サーバーにわたる数百のカウンターを実用的に発見できる。

**機能の利用シーン**：
- SQL Serverパフォーマンスカウンターの確認
- Data Collector設定前の利用可能カウンター調査
- カスタムモニタリングソリューションのセットアップ
- 複数サーバー間でのカウンター可用性比較

**主要な処理内容**：
1. 対象コンピュータへのリモート接続（Invoke-Command2使用）
2. Windowsレジストリからカウンター情報を取得
3. パターンフィルタリング（オプション）
4. PSCustomObjectとして結果を出力

**関連システム・外部連携**：Windowsレジストリ（HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009）。

**権限による制御**：レジストリへの読み取り権限が必要。リモートコンピュータの場合はPowerShellリモーティングが必要。

## 関連画面

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

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | PowerShellコンソール | 主画面 | コマンド実行とカウンター一覧表示 |
| - | Windows Performance Monitor | 参照画面 | カウンターの確認と設定 |

## 機能種別

データ取得（SELECT）/ レジストリ照会

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstance[] | No | 対象コンピュータ。デフォルトはローカル | - |
| Credential | PSCredential | No | リモートコンピュータ接続用資格情報 | - |
| Pattern | string | No | カウンター名のワイルドカードパターン（*、?サポート） | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- Windowsレジストリ：HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | カウンターが利用可能なコンピュータ名 |
| Name | string | パフォーマンスカウンター名 |
| Credential | PSCredential | 接続に使用した認証情報（非表示、パイプライン連携用） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. パターン変換
   └─ ワイルドカード（*、?）を正規表現に変換
2. 各コンピュータに対してループ
   └─ Invoke-Command2でリモートスクリプト実行
3. レジストリからカウンター取得
   └─ HKLM:\...\Perflib\009のcounterプロパティを取得
   └─ 数字のみの項目を除外
   └─ ソートと重複除去
4. パターンフィルタリング（指定時）
   └─ Where-Object Name -match $pattern
5. PSCustomObjectとして出力
   └─ Credentialを含む（パイプライン用）
   └─ Select-DefaultViewで表示制御
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Pattern指定?}
    B -->|Yes| C[ワイルドカードを正規表現に変換]
    B -->|No| D[各コンピュータでループ]
    C --> D
    D --> E[Invoke-Command2でスクリプト実行]
    E --> F[レジストリからcounterプロパティ取得]
    F --> G[数字のみの項目を除外]
    G --> H[ソートと重複除去]
    H --> I[PSCustomObjectに変換]
    I --> J{Pattern指定?}
    J -->|Yes| K[Where-Object -match でフィルタ]
    J -->|No| L[Select-DefaultViewで出力]
    K --> L
    L --> M{次のコンピュータあり?}
    M -->|Yes| D
    M -->|No| N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | レジストリソース | Perflib\009（英語）からカウンター名を取得 | 常時 |
| BR-002 | 数字除外 | 数字のみの項目（ID）を除外 | 常時 |
| BR-003 | パターン変換 | "*"を".*"に、"..*"を".*"に変換 | Pattern指定時 |
| BR-004 | Credential継承 | 出力にCredentialを含め、パイプライン連携を可能に | 常時 |

### 計算ロジック

パターン変換:
```powershell
$Pattern = $Pattern.Replace("*", ".*").Replace("..*", ".*")
```

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

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | Windowsレジストリのみを参照 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | リモートコンピュータへの接続失敗 | Stop-Functionで処理継続 |
| - | レジストリアクセスエラー | レジストリキーへのアクセス権限がない | 管理者権限で実行 |

### リトライ仕様

リトライ機能は実装されていない。-Continueで次のコンピュータの処理を継続。

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

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

## パフォーマンス要件

- レジストリベースのアプローチにより、Get-Counterより高速
- 複数コンピュータは順次処理

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

- レジストリへの読み取り権限のみ必要
- Credentialパラメータでリモート認証可能
- 出力のCredentialプロパティはデフォルトで非表示

## 備考

- Daniel Streefkerkによる高速カウンター列挙手法を採用
- https://daniel.streefkerkonline.com/2016/02/18/use-powershell-to-list-all-windows-performance-counters-and-their-numeric-ids
- Add-DbaPfDataCollectorCounterとパイプラインで連携可能

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: 出力にCredentialを含めることで、Add-DbaPfDataCollectorCounterへのパイプライン連携を実現。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | パラメータ定義（79-85行目） |
| 2-2 | Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | beginブロック（86-102行目） |

**主要処理フロー**:
1. **79-85行目**: パラメータ定義。ComputerNameはDbaInstance[]
2. **87-98行目**: scriptBlock定義（レジストリ照会）
3. **100-101行目**: Patternのワイルドカード変換

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | レジストリ照会スクリプト（87-98行目） |
| 3-2 | Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | メイン処理ループ（103-120行目） |

**主要処理フロー**:
- **88-89行目**: レジストリからcounterプロパティ取得
- **89行目**: 数字フィルタ（$_ -notmatch '[0-90000]'）
- **91-97行目**: PSCustomObject生成（Credential含む）
- **109-114行目**: パターンマッチとSelect-DefaultView

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

```
Get-DbaPfAvailableCounter
    │
    ├─ Invoke-Command2
    │      └─ scriptBlock実行
    │           └─ Get-ItemProperty (レジストリ)
    │
    ├─ Where-Object
    │      └─ パターンフィルタリング
    │
    └─ Select-DefaultView
           └─ Credential非表示
```

### データフロー図

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

ComputerName ───┐
                │
Credential ─────┼──▶ Invoke-Command2 ──▶ PSCustomObject
                │    ▼                    │
Pattern ────────┘    レジストリ照会       ├─ ComputerName
                     HKLM:\...\Perflib    ├─ Name
                     ▼                    └─ Credential
                     フィルタリング            (非表示)
                     (Pattern)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaPfAvailableCounter.ps1 | `public/Get-DbaPfAvailableCounter.ps1` | ソース | メイン機能実装 |
| Get-DbaPfAvailableCounter.Tests.ps1 | `tests/Get-DbaPfAvailableCounter.Tests.ps1` | テスト | 単体テスト |
| Add-DbaPfDataCollectorCounter.ps1 | `public/Add-DbaPfDataCollectorCounter.ps1` | 関連 | カウンター追加（パイプライン連携） |
