# 画面設計書 245-管理オブジェクト

## 概要

本ドキュメントは、dbatools PowerShellモジュールの `Get-DbaManagementObject` および `Test-DbaManagementObject` コマンドに関する画面設計書です。SQL Server Management Objects (SMO) ライブラリの検出とバージョン確認機能を提供します。

### 本画面の処理概要

`Get-DbaManagementObject` および `Test-DbaManagementObject` コマンドは、システムにインストールされているSQL Server管理オブジェクト（SMO）アセンブリとSqlClientライブラリを検出・検証する機能を提供します。

**業務上の目的・背景**：PowerShellからSQL Serverを管理するdbatoolsは、SQL Server Management Objects (SMO) ライブラリに依存しています。異なるバージョンのSMOが混在する環境や、必要なSMOがインストールされていない環境では、予期しない動作やエラーが発生することがあります。本コマンド群は、SMOのバージョン競合のトラブルシューティング、必要なバージョンがインストールされているかの事前確認、スクリプト実行環境の検証などに使用されます。特にマイグレーション前の環境チェックや、複数サーバーでの自動化スクリプト展開時に有用です。

**画面へのアクセス方法**：PowerShellコンソールまたはPowerShell ISEから `Get-DbaManagementObject` または `Test-DbaManagementObject` コマンドを直接実行します。

**主要な操作・処理内容**：
1. **Get-DbaManagementObject**:
   - ローカルまたはリモートコンピュータのSMOアセンブリをスキャン
   - Global Assembly Cache (GAC) とPowerShellインストールディレクトリを検索
   - 現在ロードされているアセンブリの情報を取得
   - SNIモジュールとSqlClientアセンブリの関連付け

2. **Test-DbaManagementObject**:
   - 指定したバージョン番号のSMOが存在するかテスト
   - 複数バージョンを同時にテスト可能
   - 存在有無をbooleanで返却

**画面遷移**：CLIコマンドのため画面遷移はありません。

**権限による表示制御**：リモートコンピュータへのアクセスにはWindows管理者権限が必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 131 | Get-DbaManagementObject | 主機能 | SQL管理オブジェクトの取得 |
| 249 | Test-DbaManagementObject | 補助機能 | 管理オブジェクトのテスト |
| - | Invoke-Command2 | 補助機能 | リモートコンピュータでのスクリプト実行 |

## 画面種別

CLI（コマンドラインインターフェース）/ 情報取得・テスト系

## URL/ルーティング

PowerShellコマンド:
- `Get-DbaManagementObject`
- `Test-DbaManagementObject`

## 入出力項目

### Get-DbaManagementObject 入力パラメータ

| パラメータ名 | 型 | 必須 | パイプライン | 説明 |
|-------------|----|----|-------------|------|
| ComputerName | DbaInstanceParameter[] | No | Yes | 対象コンピュータ（デフォルト: $env:COMPUTERNAME） |
| Credential | PSCredential | No | No | リモートアクセス用Windows資格情報 |
| VersionNumber | int | No | No | 特定バージョン番号でフィルタリング |
| EnableException | switch | No | No | 例外を詳細表示するフラグ |

### Test-DbaManagementObject 入力パラメータ

| パラメータ名 | 型 | 必須 | パイプライン | 説明 |
|-------------|----|----|-------------|------|
| ComputerName | DbaInstance[] | No | Yes | 対象コンピュータ（デフォルト: $env:COMPUTERNAME） |
| Credential | PSCredential | No | No | リモートアクセス用Windows資格情報 |
| VersionNumber | int[] | Yes | No | テスト対象のSMOバージョン番号（複数指定可） |
| EnableException | switch | No | No | 例外を詳細表示するフラグ |

## 表示項目

### Get-DbaManagementObject 出力オブジェクト（PSCustomObject）

| 項目名 | 型 | 説明 |
|--------|----|----|
| ComputerName | string | コンピュータ名 |
| Version | string | アセンブリ/モジュールのバージョン |
| Loaded | bool | PowerShellセッションにロード済みか |
| Path | string | ファイルパス（GACの場合はnull） |
| LoadTemplate | string | アセンブリをロードするためのPowerShellコマンド |

### Test-DbaManagementObject 出力オブジェクト（PSCustomObject）

| 項目名 | 型 | 説明 |
|--------|----|----|
| ComputerName | string | コンピュータ名 |
| Version | int | テストしたSMOバージョン番号 |
| Exists | bool | 指定バージョンが存在するか（True: 存在、False: 不在） |

## イベント仕様

### 1-Get-DbaManagementObject実行

コマンド実行時の処理フロー:

1. **ローカル実行またはリモート判定**: ComputerNameがローカルかリモートかを判定
2. **ロード済みアセンブリ検索**: `[AppDomain]::CurrentDomain.GetAssemblies()` でSMO/SqlClient関連アセンブリ検索
3. **ローカルファイル検索**: PowerShellインストールディレクトリ内のSMOライブラリを検索
4. **GAC検索**: `$env:SystemRoot\assembly\GAC_MSIL` および `$env:SystemRoot\Microsoft.NET\assembly\GAC_MSIL` を検索
5. **SNIモジュール検索**: プロセスモジュールからSNI関連DLLを検索
6. **結果出力**: 検出された各アセンブリ/モジュールの情報を出力

### 2-Test-DbaManagementObject実行

コマンド実行時の処理フロー:

1. **GACパス検索**: 指定バージョン番号でGAC内のSMOアセンブリを検索
2. **存在判定**: 一致するアセンブリが見つかったかを判定
3. **結果出力**: バージョンごとにExists: True/Falseを出力

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コマンド実行 | - | - | データベースアクセスなし（ファイルシステム/GAC検索） |

### テーブル別更新項目詳細

本コマンドはデータベースへのアクセスを行いません。ファイルシステムとGACのみを検索対象とします。

## メッセージ仕様

| メッセージID | レベル | メッセージ内容 | 発生条件 |
|-------------|--------|--------------|----------|
| - | Verbose | Checking currently loaded SMO, SqlClient, and related assemblies | アセンブリ検索開始時 |
| - | Verbose | Found {count} loaded SQL-related assemblies | アセンブリが見つかった場合 |
| - | Verbose | No SQL-related assemblies currently loaded in AppDomain | アセンブリが見つからない場合 |
| - | Verbose | No SMO versions found in GAC | GACにSMOがない場合 |
| - | Verbose | Executing scriptblock against {computer} | スクリプトブロック実行時 |
| - | Error | Failure | リモート実行失敗時 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|---------|---------|
| リモート実行エラー | Invoke-Command2の実行失敗 | Stop-Functionでエラー記録、続行 |
| SNIモジュール取得エラー | Get-Process/Modulesアクセス失敗 | catchでスキップ、処理続行 |

## 備考

- GACパス:
  - 古いフォーマット: `$env:SystemRoot\assembly\GAC_MSIL\Microsoft.SqlServer.Smo`
  - 新しいフォーマット: `$env:SystemRoot\Microsoft.NET\assembly\GAC_MSIL\Microsoft.SqlServer.Smo`
- 一般的なSMOバージョン番号:
  - 11: SQL Server 2012
  - 12: SQL Server 2014
  - 13: SQL Server 2016
  - 14: SQL Server 2017
  - 15: SQL Server 2019
  - 16: SQL Server 2022
- Linux/macOSではGAC検索をスキップ
- LoadTemplateプロパティを使用してアセンブリを手動ロード可能

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaManagementObject.ps1 | `public/Get-DbaManagementObject.ps1` | 37-54行目: .OUTPUTSセクションで出力プロパティ定義 |
| 1-2 | Test-DbaManagementObject.ps1 | `public/Test-DbaManagementObject.ps1` | 37-45行目: .OUTPUTSセクションで出力プロパティ定義 |

**読解のコツ**: Get-DbaManagementObjectは複数種類の出力（ローカルファイル、GAC、ロード済みアセンブリ、SNIモジュール）を返す点に注目。

#### Step 2: Get-DbaManagementObjectのスクリプトブロックを理解する

大部分のロジックはスクリプトブロック内で実行されます。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaManagementObject.ps1 | `public/Get-DbaManagementObject.ps1` | 81-301行目: $scriptBlockの内容 |

**主要処理フロー**:
1. **86-104行目**: ロード済みアセンブリの検索とバージョン抽出
2. **106-117行目**: SNIモジュールの検索
3. **119-173行目**: ローカルファイル検索（非リモート時）
4. **175-201行目**: ロード済みアセンブリの追加出力
5. **205-256行目**: GAC検索（Windows限定）
6. **258-300行目**: SNIモジュール出力

#### Step 3: Test-DbaManagementObjectのロジックを理解する

シンプルなGAC検索ロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Test-DbaManagementObject.ps1 | `public/Test-DbaManagementObject.ps1` | 63-84行目: $scriptBlockの内容 |

**主要処理フロー**:
- **64-68行目**: 2つのGACパスを検索（旧形式と新形式）
- **70-82行目**: 存在有無を判定してPSCustomObject出力

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

```
Get-DbaManagementObject
    │
    ├─ (ローカル実行時)
    │      └─ Invoke-Command -Scriptblock $scriptBlock
    │             ├─ [AppDomain]::CurrentDomain.GetAssemblies()
    │             ├─ Get-Process -Id $PID | Modules (SNI検索)
    │             └─ Get-ChildItem (GAC検索)
    │
    └─ (リモート実行時)
           └─ Invoke-Command2 -ComputerName $computer -ScriptBlock $scriptBlock
                  └─ (同上のスクリプトブロック)

Test-DbaManagementObject
    │
    └─ Invoke-Command2 -ComputerName $computer -ScriptBlock $scriptBlock
           └─ Get-ChildItem (GAC検索)
```

### データフロー図

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

ComputerName ───▶ ローカル/リモート判定
VersionNumber ───▶           │
                             ▼
            ┌────────────────┴────────────────┐
            │                                  │
    [ローカル実行]                      [リモート実行]
            │                                  │
            ▼                                  ▼
    [AppDomain].GetAssemblies()     Invoke-Command2
            │                                  │
            ├─ ローカルファイル検索             └─ $scriptBlock
            │      (PowerShellディレクトリ)          │
            ├─ GAC検索                              └─ (同様の処理)
            │      ($env:SystemRoot\assembly)
            └─ SNIモジュール検索
                   (Get-Process Modules)
                             │
                             ▼
                       PSCustomObject
              (ComputerName, Version, Loaded, Path, LoadTemplate)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaManagementObject.ps1 | `public/Get-DbaManagementObject.ps1` | ソース | SMOアセンブリ検出 |
| Test-DbaManagementObject.ps1 | `public/Test-DbaManagementObject.ps1` | ソース | SMOバージョン存在テスト |
| Invoke-Command2.ps1 | `internal/functions/Invoke-Command2.ps1` | ソース | リモートコマンド実行ラッパー |
