# 機能設計書 133-Get-DbaMsdtc

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Get-DbaMsdtc`コマンドレットに関する機能設計書です。このコマンドレットは、Microsoft Distributed Transaction Coordinator (MSDTC) サービスのステータスと構成詳細を取得する機能を提供します。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverの分散トランザクション、リンクサーバー操作、複数のサーバーやインスタンスにまたがるクロスデータベーストランザクションには、MSDTCが必須のコンポーネントです。MSDTCの設定不備は分散トランザクションの失敗の主要な原因となります。本機能は、MSDTCのサービス状態とセキュリティ設定を一括で取得し、複数サーバー間での構成の一貫性を検証できます。

**機能の利用シーン**：
- 分散トランザクション失敗のトラブルシューティング時
- リンクサーバー設定時のMSDTC要件確認
- 複数サーバー間でのMSDTC構成監査
- セキュリティ設定（ネットワークDTCアクセス、XAトランザクション等）の確認

**主要な処理内容**：
1. 対象コンピュータへの接続（WSManまたはDCom）
2. Win32_ServiceからMSDTCサービス情報を取得
3. レジストリからMSDTCセキュリティ設定を取得
4. レジストリからMSDTC CID（コンポーネント識別子）情報を取得
5. すべての情報をPSCustomObjectとして出力

**関連システム・外部連携**：
- WMI/CIM（Win32_Service）
- Windowsレジストリ（HKLM:\Software\Microsoft\MSDTC\Security, HKCR:\CID）
- PowerShell Remoting（Invoke-Command2）

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

## 関連画面

本機能はコマンドラインツールであり、画面機能マッピングに該当する関連画面はありません。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | PowerShellコマンドラインで実行 |

## 機能種別

データ取得 / 診断・監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | MSDTCを確認するサーバー名。デフォルトはローカルコンピュータ | パイプライン入力可、エイリアス: cn, host, Server |
| Credential | PSCredential | No | リモートコンピュータへの接続に使用する代替資格情報 | - |
| EnableException | switch | No | 例外処理を有効化 | - |

### 入力データソース

- WMI/CIM: Win32_Service クラス（MSDTCサービス）
- レジストリ: HKLM:\Software\Microsoft\MSDTC\Security
- レジストリ: HKEY_CLASSES_ROOT:\CID

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| DTCServiceName | string | MSDTCサービスの表示名 |
| DTCServiceState | string | サービス状態（Running, Stopped等） |
| DTCServiceStatus | string | サービスステータス（OK, Degraded等） |
| DTCServiceStartMode | string | 起動モード（Auto, Manual, Disabled） |
| DTCServiceAccount | string | サービスアカウント |
| DTCCID_MSDTC | string | MSDTCコンポーネントID |
| DTCCID_MSDTCUIS | string | MSDTC UIサービスコンポーネントID |
| DTCCID_MSDTCTIPGW | string | MSDTC TIPゲートウェイコンポーネントID |
| DTCCID_MSDTCXATM | string | MSDTC XAトランザクションマネージャーコンポーネントID |
| networkDTCAccess | bool | ネットワークDTCアクセスが有効か |
| networkDTCAccessAdmin | bool | ネットワークDTC管理アクセスが有効か |
| networkDTCAccessClients | bool | クライアントからのDTCネットワークアクセスが有効か |
| networkDTCAccessInbound | bool | 受信ネットワークDTCトランザクションが有効か |
| networkDTCAccessOutBound | bool | 送信ネットワークDTCトランザクションが有効か |
| networkDTCAccessTip | bool | TIP（Transaction Internet Protocol）アクセスが有効か |
| networkDTCAccessTransactions | bool | ネットワークDTCトランザクションが有効か |
| XATransactions | bool | XAトランザクションが有効か |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. beginブロック: クエリとスクリプトブロック定義
   ├─ WMIクエリ定義（Win32_Service）
   ├─ DTCセキュリティ取得スクリプトブロック定義
   └─ DTC CID取得スクリプトブロック定義

2. processブロック: 各コンピュータに対して処理
   ├─ PSRemoting接続テスト
   │
   ├─ [PSRemoting有効] WSMan経由
   │     ├─ Get-CimInstanceでサービス情報取得
   │     ├─ Invoke-Command2でセキュリティ設定取得
   │     └─ Invoke-Command2でCID情報取得
   │
   └─ [PSRemoting無効] DCom経由
         └─ New-CimSession (DCom) でサービス情報取得

3. 結果をPSCustomObjectとして出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[各ComputerNameに対して]
    B --> C[Test-PSRemoting]
    C --> D{PSRemoting有効?}
    D -->|Yes| E[WSMan経由でCIM取得]
    D -->|No| F[DCom経由でCIM取得]
    E --> G[Invoke-Command2でセキュリティ取得]
    G --> H[Invoke-Command2でCID取得]
    H --> I{サービス取得成功?}
    F --> I
    I -->|Yes| J[PSCustomObject出力]
    I -->|No| K[警告出力]
    J --> L{次のコンピュータ?}
    K --> L
    L -->|Yes| B
    L -->|No| M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 接続方式自動選択 | PSRemotingが有効ならWSMan、無効ならDComを使用 | 常時 |
| BR-002 | CID情報ハッシュ化 | CID情報はキーバリューペアでハッシュテーブルに格納 | 常時 |
| BR-003 | サービス未取得時は出力なし | DTCServiceが取得できない場合は何も出力しない | DTCService = null |
| BR-004 | レジストリアクセス失敗時は警告 | セキュリティ/CID情報が取得できない場合は警告を出力 | アクセス失敗時 |

### 計算ロジック

CID情報の取得：
- HKEY_CLASSES_ROOT:\CID配下のサブキーをスキャン
- 各サブキーのDescriptionプロパティからData（名前）とCID（パス）を取得
- MSDTC, MSDTCUIS, MSDTCTIPGW, MSDTCXATMのCIDを特定

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

本機能はデータベースへの直接操作を行いません。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CIM接続エラー | WMIへの接続失敗（WSMan） | 警告出力、DComへフォールバック |
| - | DCom接続エラー | WMIへの接続失敗（DCom） | Stop-Functionで処理継続 |
| - | レジストリアクセスエラー | セキュリティ設定取得失敗 | Stop-Functionで処理継続 |
| - | CID取得エラー | CID情報取得失敗 | 警告出力、CID情報はnull |

### リトライ仕様

WSMan接続失敗時にDComへフォールバックする擬似リトライ処理を実装。

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

データベース操作がないため、トランザクション管理は不要です。

## パフォーマンス要件

- 各コンピュータに対してWMIクエリ1回、レジストリ読み取り2回
- リモートコンピュータへのアクセスはネットワーク状況に依存

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

- リモートコンピュータへのWindows管理者権限が必要
- PSRemotingまたはDComの有効化が必要
- 資格情報はSecureStringとして保護

## 備考

- MSDTCの設定変更には管理者権限が必要
- リンクサーバーで分散トランザクションを使用する場合、networkDTCAccessInboundとnetworkDTCAccessOutBoundの両方がtrueである必要がある
- XAトランザクションはOracleなどの外部データソースとの連携に使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 160-179行目: PSCustomObject出力構造 |

**読解のコツ**: CID情報はハッシュテーブル($cidHash)からキー名でアクセスしている点に注目。

#### Step 2: beginブロックの定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 93行目: WMIクエリ定義 |
| 2-2 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 94-99行目: セキュリティ設定取得スクリプトブロック |
| 2-3 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 100-105行目: CID取得スクリプトブロック |

**主要処理フロー**:
1. **93行目**: `Select * FROM Win32_Service WHERE Name = 'MSDTC'`
2. **95-98行目**: `HKLM:\Software\Microsoft\MSDTC\Security`からGet-ItemPropertyでセキュリティ設定取得
3. **101-104行目**: `HKCR:\CID`からCID情報取得（一時的にPSDriveを作成）

#### Step 3: メイン処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 108-115行目: PSRemoting接続テスト |
| 3-2 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 116-145行目: WSMan経由の処理 |
| 3-3 | Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | 146-158行目: DCom経由の処理 |

**主要処理フロー**:
- **111-114行目**: Test-PSRemotingで接続方式を判定
- **119行目**: Get-CimInstanceでMSDTCサービス情報取得
- **126行目**: Invoke-Command2でセキュリティ設定取得
- **135行目**: Invoke-Command2でCID情報取得
- **153行目**: New-CimSessionでDCom接続

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

```
Get-DbaMsdtc
    │
    ├─ begin ブロック
    │      ├─ WMIクエリ定義
    │      ├─ $dtcSecurityスクリプトブロック定義
    │      └─ $dtcCidsスクリプトブロック定義
    │
    └─ process ブロック
           │
           └─ foreach ($computer in $ComputerName)
                  │
                  ├─ Test-PSRemoting
                  │
                  ├─ [PSRemoting有効]
                  │     ├─ Get-CimInstance (Win32_Service)
                  │     ├─ Invoke-Command2 ($dtcSecurity)
                  │     │      └─ Get-ItemProperty (レジストリ)
                  │     └─ Invoke-Command2 ($dtcCids)
                  │            ├─ New-PSDrive (HKCR)
                  │            └─ Get-ItemProperty (CID)
                  │
                  └─ [PSRemoting無効]
                        ├─ New-CimSession (DCom)
                        └─ Get-CimInstance (Win32_Service)
```

### データフロー図

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

ComputerName ───────▶ 接続方式判定
                            │
                            ├─ WMI/CIM ──▶ MSDTCサービス情報
                            │
                            ├─ Registry ──▶ セキュリティ設定
                            │     (HKLM:\Software\Microsoft\MSDTC\Security)
                            │
                            └─ Registry ──▶ CID情報
                                  (HKCR:\CID\*\Description)
                            │
                            ▼
                     PSCustomObject ───────▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaMsdtc.ps1 | `public/Get-DbaMsdtc.ps1` | ソース | メイン処理 |
| Test-PSRemoting.ps1 | `private/functions/Test-PSRemoting.ps1` | ソース | リモート接続テスト |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | リモート実行ヘルパー |
| Stop-Function.ps1 | `private/functions/flowcontrol/Stop-Function.ps1` | ソース | エラー処理 |
| Write-Message.ps1 | `private/functions/flowcontrol/Write-Message.ps1` | ソース | ログ出力 |
