# 機能設計書 125-Get-DbaFeature

## 概要

本ドキュメントは、複数サーバーにわたってインストールされているSQL Serverの機能とコンポーネントを検出するGet-DbaFeature機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaFeatureは、SQL Serverの組み込み機能検出レポート（setup.exe /Action=RunDiscovery）を自動実行し、インストールされている全てのSQL Serverコンポーネント、エディション、インスタンスをインベントリ化する機能である。

**業務上の目的・背景**：企業環境では、複数のサーバーにSQL Serverがインストールされており、コンプライアンス監査、ライセンス管理、環境ドキュメント作成のために、どのサーバーにどのSQL Server機能がインストールされているかを把握する必要がある。手動でsetup.exe /Action=RunDiscoveryを実行してXMLレポートを解析する作業を自動化し、複数サーバーの一括検出を可能にする。

**機能の利用シーン**：
- SQL Serverライセンス監査とコンプライアンスレポート作成
- 環境ドキュメンテーションと構成管理
- アップグレード計画のための現状把握
- インストールされている機能の一括インベントリ取得

**主要な処理内容**：
1. 対象コンピュータでsetup.exeを検索（Microsoft SQL Serverフォルダ内）
2. setup.exe /Action=RunDiscovery /qを実行してDiscoveryレポートを生成
3. 生成されたSqlDiscoveryReport.xmlを読み取り
4. XMLを解析してインストールされた機能情報を構造化データとして出力

**関連システム・外部連携**：SQL Serverセットアッププログラム（setup.exe）、PowerShellリモーティング

**権限による制御**：対象コンピュータへの管理者権限が必要。setup.exeの実行権限も必要。

## 関連画面

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

## 機能種別

データ取得(SELECT) / インベントリ・監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | 対象コンピュータ名（デフォルト: $env:COMPUTERNAME） | ValueFromPipeline |
| Credential | PSCredential | No | リモートコンピュータへのWindows資格情報 | - |
| EnableException | switch | No | 例外を直接スローするか | - |

### 入力データソース

- コンピュータ名
- SQL Server setup.exeプログラム
- SqlDiscoveryReport.xml（自動生成）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverがインストールされているサーバー名 |
| Product | string | SQL Server製品名（例: "SQL Server 2019 Enterprise Edition"） |
| Instance | string | SQL Serverインスタンス名（デフォルトインスタンスは"MSSQLSERVER"） |
| InstanceID | string | レジストリ上のインスタンスID識別子 |
| Feature | string | インストールされた機能コンポーネント名 |
| Language | string | インストール言語（例: "English"） |
| Edition | string | SQL Serverエディション（Enterprise, Standard, Express等） |
| Version | string | バージョン番号（例: "15.0.2000.5"） |
| Clustered | bool/string | フェイルオーバークラスターの一部かどうか |
| Configured | bool/string | 機能が完全に構成済みかどうか |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力

## 処理フロー

### 処理シーケンス

```
1. beginブロックでスクリプトブロックを定義
   └─ setup.exe検索、Discovery実行、XML読み取り

2. 各ComputerNameをループ処理
   └─ Invoke-Command2でリモート実行

3. setup.exeをProgram Files\Microsoft SQL Server配下で検索
   └─ Setup Bootstrap\SQLまたはBootstrap\Release\Setup.exeパターン

4. setup.exe /Action=RunDiscovery /qを実行
   └─ 同期的に完了を待機

5. SqlDiscoveryReport.xmlを検索して読み取り
   └─ LastWriteTimeでソートして最新を取得

6. XMLをパースしてDiscoveryInformation要素を抽出
   └─ 各機能をPSCustomObjectに変換して出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ComputerNameループ}
    B -->|各コンピュータ| C[Invoke-Command2実行]
    C --> D[setup.exe検索]
    D --> E{setup.exe発見?}
    E -->|No| F[Verboseメッセージ]
    F --> B
    E -->|Yes| G[/Action=RunDiscovery /q実行]
    G --> H[SqlDiscoveryReport.xml検索]
    H --> I{XMLファイル発見?}
    I -->|No| B
    I -->|Yes| J[XML読み取り・パース]
    J --> K{DiscoveryInformationループ}
    K -->|各機能| L[PSCustomObject作成・出力]
    L --> K
    K -->|終了| B
    B -->|全コンピュータ完了| M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最新setup.exe使用 | 複数バージョンがある場合、最新のsetup.exeを使用（FullNameソート降順） | 複数バージョン環境 |
| BR-002 | 下位バージョン包含 | 実行したsetup.exeより古いバージョンのSQL Server情報も取得可能 | 複数バージョン環境 |
| BR-003 | 最新XMLファイル使用 | LastWriteTimeでソートして最新のSqlDiscoveryReport.xmlを使用 | 複数回実行時 |

### 計算ロジック

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

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | - | - | SQL Serverへの直接接続なし（ファイルシステムのみ） |

### ファイルシステムアクセス詳細

#### setup.exe

| 操作 | パス | 条件 | 備考 |
|-----|-----|------|------|
| 検索 | Program Files\Microsoft SQL Server | Setup Bootstrap\SQLパターン | 最新バージョンを優先 |
| 実行 | - | /Action=RunDiscovery /q | 同期実行 |

#### SqlDiscoveryReport.xml

| 操作 | パス | 条件 | 備考 |
|-----|-----|------|------|
| 検索・読み取り | setup.exe親ディレクトリ | LastWriteTime降順 | 最新ファイルを使用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 機能未検出 | setup.exeが見つからない | Verboseメッセージ出力 |
| - | リモート実行エラー | Invoke-Command2失敗 | Stop-Function -Continue |

### リトライ仕様

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

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

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

## パフォーマンス要件

- setup.exe /Action=RunDiscoveryの実行に数秒〜数十秒かかる可能性
- 複数コンピュータ指定時は順次処理

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

- 対象コンピュータへの管理者権限が必要
- Credentialパラメータで代替Windows資格情報を指定可能
- setup.exeはWindowsサービスアカウントの権限で実行

## 備考

- SQL Server 2008R2とSQL Server 2012で動作確認済み
- 「Microsoft SQL Server」フォルダがProgram Files内に存在する前提
- 参考: https://itsalljustelectrons.blogspot.be/2018/04/SQL-Server-Discovery-Report.html

---

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

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

### 推奨読解順序

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

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

**主要処理フロー**:
1. **83-89行目**: パラメータ定義（ComputerNameデフォルト値は$env:COMPUTERNAME）
2. **91-105行目**: beginブロックでスクリプトブロック定義
3. **93-95行目**: setup.exe検索パターン（Setup Bootstrap\SQLまたはBootstrap）
4. **97行目**: Start-Process /Action=RunDiscovery /q実行
5. **99行目**: SqlDiscoveryReport.xml検索
6. **109-135行目**: processブロックでリモート実行とXMLパース

**読解のコツ**:
- スクリプトブロックはInvoke-Command2でリモート実行される
- [System.Environment]::GetFolderPath("ProgramFiles")でProgram Filesパスを取得
- XMLのArrayOfDiscoveryInformation.DiscoveryInformation構造を理解する

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

```
Get-DbaFeature
    │
    └─ Invoke-Command2 (リモート実行)
           │
           ├─ Get-ChildItem (setup.exe検索)
           │
           ├─ Start-Process (Discovery実行)
           │      └─ setup.exe /Action=RunDiscovery /q
           │
           ├─ Get-ChildItem (XML検索)
           │
           └─ Get-Content (XML読み取り)
                  └─ [xml]キャスト → DiscoveryInformation抽出
```

### データフロー図

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

ComputerName   ───▶  Invoke-Command2           ───▶
                           │
                     setup.exe検索             ───▶
                           │
                     /Action=RunDiscovery       ───▶  SqlDiscoveryReport.xml
                           │
                     XML読み取り・パース       ───▶
                           │
                     PSCustomObject変換        ───▶  パイプライン出力
                                                     (ComputerName,
                                                      Product, Instance,
                                                      InstanceID, Feature,
                                                      Language, Edition,
                                                      Version, Clustered,
                                                      Configured)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaFeature.ps1 | `public/Get-DbaFeature.ps1` | ソース | メイン関数定義 |
| Get-DbaFeature.Tests.ps1 | `tests/Get-DbaFeature.Tests.ps1` | テスト | 単体・統合テスト |
| Invoke-Command2.ps1 | `functions/Invoke-Command2.ps1` | ソース | リモートコマンド実行ラッパー |
