# 機能設計書 145-Get-DbaRegistryRoot

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける`Get-DbaRegistryRoot`コマンドレットの機能設計を定義する。本機能は、SQL ServerインスタンスのWindowsレジストリルートパスを検出し、レジストリ構成へのアクセスを可能にする。

### 本機能の処理概要

`Get-DbaRegistryRoot`は、SQL Server WMIを照会して各SQL Serverインスタンスの構成設定が格納されているWindowsレジストリハイブパスを特定するコマンドレットである。スタンドアロンインスタンスとフェイルオーバークラスターインスタンスの両方に対応し、PowerShellレジストリコマンドレット（Get-ItemProperty、Set-ItemProperty等）で即座に使用可能な形式でパスを返す。

**業務上の目的・背景**：SQL Serverの構成設定の一部はWindowsレジストリに格納されており、起動問題のトラブルシューティング、トレースフラグの変更、構成マネージャーでは公開されない設定の自動化などで直接レジストリアクセスが必要となる場合がある。本機能は、SQL Serverバージョンやインスタンス名によって異なるレジストリパスを自動検出し、手動でのパス特定の手間を省く。

**機能の利用シーン**：
- SQL Server起動問題のトラブルシューティング
- トレースフラグや起動パラメータのレジストリ直接編集
- 構成ドキュメント作成のためのレジストリパス取得
- 構成変更の自動化スクリプト作成
- 複数インスタンス環境でのレジストリパス一括取得

**主要な処理内容**：
1. ComputerNameパラメータで対象サーバーを指定（デフォルト: ローカルホスト）
2. Invoke-ManagedComputerCommandでWMI経由でSQL Serverサービス情報を取得
3. DisplayNameでSQL Serverサービスをフィルタリング
4. AdvancedPropertiesからREGROOT（レジストリルートパス）とVSNAME（仮想サーバー名）を抽出
5. フェイルオーバークラスターの場合はVSNAMEを使用
6. PSCustomObjectとしてレジストリ情報を出力

**関連システム・外部連携**：
- SQL Server WMI（Windows Management Instrumentation）
- Windowsレジストリ
- Invoke-ManagedComputerCommand（内部関数）

**権限による制御**：対象コンピュータへのWMIアクセス権限が必要。リモートサーバーの場合は適切なWindowsクレデンシャルが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | レジストリルートパス取得 |

## 機能種別

情報取得処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | 対象コンピュータ名（デフォルト: $env:COMPUTERNAME） | パイプライン入力対応 |
| Credential | PSCredential | No | 代替Windowsクレデンシャル | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- SQL Server WMI（ManagedComputer.Services）
- サービスのAdvancedProperties（REGROOT、VSNAME）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名（デフォルトインスタンスは"MSSQLSERVER"） |
| SqlInstance | string | 完全なSQL Serverインスタンス名（computer\instance形式） |
| Hive | string | レジストリハイブ（常に"HKLM"） |
| Path | string | ハイブ内のレジストリパス（例: "Software\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\Setup"） |
| RegistryRoot | string | PowerShellレジストリコマンドレット用フルパス（例: "HKLM:\Software\Microsoft\..."） |

### 出力先

パイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. ComputerNameループ開始
   └─ 各コンピュータに対して処理を実行
2. WMIサービス情報取得
   └─ Invoke-ManagedComputerCommandでwmi.Servicesを取得
3. SQL Serverサービスフィルタリング
   └─ DisplayNameが"SQL Server ("で始まるサービスをフィルタ
4. サービスループ
   ├─ AdvancedPropertiesからREGROOTを抽出
   ├─ AdvancedPropertiesからVSNAMEを抽出
   ├─ DisplayNameからインスタンス名を解析
   └─ フォールバック処理（文字列形式の場合）
5. SqlInstance名の構築
   ├─ VSNAMEが空の場合: ComputerName使用
   └─ 名前付きインスタンスの場合: sqlInstance\instanceName形式
6. PSCustomObject出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ComputerNameループ]
    B --> C[Invoke-ManagedComputerCommand<br/>wmi.Services取得]
    C --> D{取得成功?}
    D -->|No| E[Stop-Function:<br/>エラー処理]
    D -->|Yes| F[DisplayNameで<br/>"SQL Server"フィルタ]
    F --> G[サービスループ]
    G --> H[AdvancedProperties取得<br/>REGROOT, VSNAME]
    H --> I{REGROOT<br/>が空?}
    I -->|Yes| J[文字列形式で<br/>再取得試行]
    I -->|No| K[値を使用]
    J --> L{再取得成功?}
    L -->|No| M[Stop-Function:<br/>インスタンス未発見]
    L -->|Yes| N[Split処理で<br/>値抽出]
    K --> O[VSNAME判定]
    N --> O
    O --> P{VSNAMEが空?}
    P -->|Yes| Q[SqlInstance =<br/>ComputerName]
    P -->|No| R[SqlInstance =<br/>VSNAME]
    Q --> S{インスタンス名が<br/>MSSQLSERVER?}
    R --> S
    S -->|No| T[SqlInstance\InstanceName<br/>形式に]
    S -->|Yes| U[そのまま使用]
    T --> V[PSCustomObject<br/>出力]
    U --> V
    V --> W{次のサービス<br/>あり?}
    W -->|Yes| G
    W -->|No| X{次のComputer<br/>あり?}
    X -->|Yes| B
    X -->|No| Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトコンピュータ | ComputerName未指定時はローカルホスト | ComputerName未指定 |
| BR-002 | Hive固定値 | SQL ServerのレジストリHiveは常にHKLM | 常時 |
| BR-003 | デフォルトインスタンス判定 | インスタンス名が"MSSQLSERVER"の場合、SqlInstanceにインスタンス名を付けない | デフォルトインスタンス |
| BR-004 | クラスターインスタンス | VSNAMEが存在する場合はクラスター仮想サーバー名を使用 | フェイルオーバークラスター |
| BR-005 | パス形式 | RegistryRootは"HKLM:\$regRoot"形式 | 常時 |

### 計算ロジック

特になし

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

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

本機能はSQL Serverデータベースへのアクセスを行わない。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | WMIアクセスのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | WMIアクセスエラー | 対象サーバーへのWMI接続失敗 | ネットワーク接続・権限確認 |
| - | インスタンス未発見 | REGROOTが取得できない | SQL Serverインストール確認 |
| - | 認証エラー | クレデンシャル不正 | 適切なクレデンシャル指定 |

### リトライ仕様

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

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

データベーストランザクションは使用しない。

## パフォーマンス要件

- WMI呼び出しのためネットワーク遅延に依存
- 複数コンピュータ指定時は順次処理

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

- WMIアクセスには適切なWindows権限が必要
- レジストリパス情報自体は機密性は低い
- 返されるパスを使用したレジストリ変更には管理者権限が必要

## 備考

- SQL Server 2005以降の全バージョンに対応
- レジストリパスはSQL Serverバージョンとインスタンス名によって異なる（例: MSSQL15.MSSQLSERVER = SQL Server 2019）

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaRegistryRoot.ps1 | `public/Get-DbaRegistryRoot.ps1` | 出力PSCustomObject構造 |

**読解のコツ**: 103-110行目で定義される出力オブジェクトは6プロパティを持つ。特にRegistryRootは"HKLM:\$regRoot"形式でPowerShellレジストリコマンドレットで直接使用可能。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaRegistryRoot.ps1 | `public/Get-DbaRegistryRoot.ps1` | 全体処理フロー |

**主要処理フロー**:
1. **63-64行目**: processブロック、ComputerNameループ開始
2. **65-69行目**: Invoke-ManagedComputerCommandでWMIサービス取得
3. **66行目**: DisplayNameで"SQL Server ("をフィルタ
4. **71-87行目**: REGROOTとVSNAME取得、フォールバック処理
5. **73-74行目**: AdvancedPropertiesからREGROOT/VSNAME抽出
6. **75行目**: DisplayNameからインスタンス名を解析（正規表現不使用のReplace処理）
7. **77-87行目**: REGROOT空の場合の文字列形式フォールバック
8. **89-97行目**: VSNAME判定とSqlInstance名構築
9. **103-110行目**: PSCustomObject出力

#### Step 3: 依存機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Invoke-ManagedComputerCommand | `private/Invoke-ManagedComputerCommand.ps1` | WMI呼び出し内部関数 |

**主要処理フロー**:
- WMI ManagedComputer経由でSQL Serverサービス情報を取得
- リモートサーバーへのクレデンシャル伝播
- ScriptBlock実行とエラーハンドリング

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

```
Get-DbaRegistryRoot
    │
    ├─ Invoke-ManagedComputerCommand
    │      └─ SQL Server WMI (ManagedComputer)
    │             ├─ wmi.Services（サービス一覧）
    │             └─ AdvancedProperties
    │                    ├─ REGROOT（レジストリパス）
    │                    └─ VSNAME（仮想サーバー名）
    │
    └─ PSCustomObject出力
           ├─ ComputerName
           ├─ InstanceName
           ├─ SqlInstance
           ├─ Hive
           ├─ Path
           └─ RegistryRoot
```

### データフロー図

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

ComputerName ────▶ Invoke-ManagedComputerCommand
                          │
                          ▼
                    WMI Services取得
                          │
                          ▼
                    DisplayNameフィルタ
                    "SQL Server (*)"
                          │
                          ▼
                    AdvancedProperties
                    ┌─────┴─────┐
                    ▼           ▼
                 REGROOT     VSNAME
                    │           │
                    ▼           ▼
              レジストリパス  仮想サーバー名
                    │           │
                    └─────┬─────┘
                          ▼
                    SqlInstance構築
                          │
                          ▼
                    [PSCustomObject]
                    - ComputerName
                    - InstanceName
                    - SqlInstance
                    - Hive: "HKLM"
                    - Path
                    - RegistryRoot: "HKLM:\$Path"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaRegistryRoot.ps1 | `public/Get-DbaRegistryRoot.ps1` | ソース | メイン機能 |
| Invoke-ManagedComputerCommand.ps1 | `private/` | ソース | WMI呼び出し内部関数 |
