# 画面設計書 146-登録済みサーバーグループ

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるCentral Management Server（CMS）のサーバーグループ管理機能の設計仕様を定義する。

### 本画面の処理概要

CMSまたはローカルSSMSに登録されたサーバーグループ（組織構造コンテナ）を管理する機能群を提供する。サーバーグループは、複数のSQL Serverインスタンスを階層構造で整理するための組織単位であり、環境（本番/開発/テスト）、部門、機能などによる論理的なグループ化を可能にする。

**業務上の目的・背景**：エンタープライズ環境では数十から数百のSQL Serverインスタンスを管理することが一般的である。サーバーグループを使用することで、これらのインスタンスを論理的な階層構造で整理し、特定グループに対する一括操作やクエリ実行が可能になる。本機能を使用することで、CMSのグループ構造をプログラムで操作・管理できる。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドを実行する。
- `Get-DbaRegServerGroup` - サーバーグループの取得
- `Add-DbaRegServerGroup` - サーバーグループの追加
- `Move-DbaRegServerGroup` - サーバーグループの移動
- `Remove-DbaRegServerGroup` - サーバーグループの削除

**主要な操作・処理内容**：
1. グループ取得（Get-DbaRegServerGroup）：CMSまたはローカルからサーバーグループを取得
2. グループ追加（Add-DbaRegServerGroup）：新しいサーバーグループを作成
3. グループ移動（Move-DbaRegServerGroup）：既存グループを別の親グループに移動
4. グループ削除（Remove-DbaRegServerGroup）：サーバーグループを削除

**画面遷移**：CLIベースのため画面遷移は存在しない。Get-DbaRegServerGroupの出力をAdd-DbaRegServer等にパイプすることで、グループへのサーバー追加が可能。

**権限による表示制御**：CMSへのアクセスにはSQL Server接続権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 251 | Get-DbaRegServerGroup | 主機能 | サーバーグループの取得 |
| 21 | Add-DbaRegServerGroup | 主機能 | サーバーグループの追加 |
| 286 | Move-DbaRegServerGroup | 主機能 | サーバーグループの移動 |
| 336 | Remove-DbaRegServerGroup | 主機能 | サーバーグループの削除 |
| - | Get-DbaRegServerStore | 補助機能 | サーバーストアの取得 |

## 画面種別

コマンドラインインターフェース（CLI）/ PowerShell関数

## URL/ルーティング

```powershell
# CMSからサーバーグループを取得
Get-DbaRegServerGroup -SqlInstance sqlcms

# 特定グループを取得
Get-DbaRegServerGroup -SqlInstance sqlcms -Group "Production"

# ネストされたサブグループを取得
Get-DbaRegServerGroup -SqlInstance sqlcms -Group "Production\OLTP"

# グループを追加
Add-DbaRegServerGroup -SqlInstance sqlcms -Name "NewGroup"

# ネストされたグループを追加
Add-DbaRegServerGroup -SqlInstance sqlcms -Name "NewSubGroup" -Group "Production"

# グループを移動
Move-DbaRegServerGroup -SqlInstance sqlcms -Group "OldLocation\MyGroup" -NewGroup "NewLocation"

# グループを削除
Remove-DbaRegServerGroup -SqlInstance sqlcms -Group "ObsoleteGroup"
```

## 入出力項目

### Get-DbaRegServerGroup パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | CMSインスタンス（未指定時はローカル） |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Group | object[] | No | 取得対象グループ名（階層パス対応） |
| ExcludeGroup | object[] | No | 除外するグループ名 |
| Id | int[] | No | グループIDでフィルタリング |
| EnableException | switch | No | 例外処理モードの有効化 |

### Add-DbaRegServerGroup パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | CMSインスタンス |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Name | string | Yes | 作成するグループ名 |
| Description | string | No | グループの説明 |
| Group | object | No | 親グループ |
| InputObject | ServerGroup[] | No | パイプライン入力用親グループ |
| EnableException | switch | No | 例外処理モードの有効化 |

## 表示項目

### Get-DbaRegServerGroup 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | CMSホストのコンピュータ名 |
| InstanceName | string | CMSのインスタンス名 |
| SqlInstance | string | CMSの完全インスタンス名 |
| Name | string | グループ名 |
| DisplayName | string | 表示名 |
| Description | string | グループの説明 |
| ServerGroups | collection | 子グループコレクション |
| RegisteredServers | collection | グループ内の登録済みサーバー |

## イベント仕様

### 1-サーバーグループ取得

**Get-DbaRegServerGroup 実行時**

1. Get-DbaRegServerStoreでサーバーストアを取得
2. Group指定時：
   - ServerGroupオブジェクトの場合はGet-RegServerGroupReverseParse
   - DatabaseEngineServerGroup\プレフィックスを除去
   - バックスラッシュで分割して階層をたどる
   - ServerGroups[]インデクサーで各レベルのグループを取得
3. Group未指定時：
   - DatabaseEngineServerGroup.ServerGroupsで全ルートグループを取得
4. ExcludeGroup指定時：
   - 再帰的にGet-DbaRegServerGroupを呼び出し除外対象を取得
   - Urn.Valueで比較してフィルタリング
5. Id指定時：
   - Id=1はDatabaseEngineServerGroup（ルート）
   - それ以外はGetDescendantRegisteredServers().Parentから検索
6. Add-Memberでプロパティを追加
7. Select-DefaultViewでデフォルト表示プロパティを設定

### 2-サーバーグループ追加

**Add-DbaRegServerGroup 実行時**

1. InputObjectまたはGroup指定時は親グループを取得
2. 親グループ未指定時はルートグループ（DatabaseEngineServerGroup）を使用
3. ServerGroupコンストラクタで新規グループオブジェクト作成
4. Description設定
5. Create()メソッドで永続化
6. Get-DbaRegServerGroupで作成結果を返却

### 3-サーバーグループ移動

**Move-DbaRegServerGroup 実行時**

1. Get-DbaRegServerGroupで移動対象グループを取得
2. NewGroupで移動先グループを取得
3. グループをコピーして新規作成
4. 配下のサーバーとサブグループを再帰的に移動
5. 元のグループを削除

### 4-サーバーグループ削除

**Remove-DbaRegServerGroup 実行時**

1. Get-DbaRegServerGroupで削除対象グループを取得
2. ShouldProcessで確認
3. Drop()メソッドで削除

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| グループ取得 | msdb.dbo.sysmanagement_shared_server_groups | SELECT | グループ情報読み取り |
| グループ追加 | msdb.dbo.sysmanagement_shared_server_groups | INSERT | 新規グループ作成 |
| グループ移動 | msdb.dbo.sysmanagement_shared_server_groups | UPDATE/DELETE/INSERT | グループ構造変更 |
| グループ削除 | msdb.dbo.sysmanagement_shared_server_groups | DELETE | グループ削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| MSG001 | エラー | "Cannot access Central Management Server 'X'" | CMS接続失敗 |
| MSG002 | 情報 | "Processing X" | グループ処理中 |
| MSG003 | 情報 | "Parsed X" | 階層パース成功 |
| MSG004 | 情報 | "Added X" | グループ追加成功 |
| MSG005 | 情報 | "Added all root server groups" | ルートグループ取得 |
| MSG006 | 情報 | "Excluding X" | グループ除外 |
| MSG007 | 情報 | "Filtering for id X. Id 1 = default." | ID検索 |

## 例外処理

| 例外条件 | 対応処理 |
|---------|---------|
| CMS接続失敗 | Stop-Functionでエラー記録、Continueで次インスタンスへ |
| グループ未存在 | 空の結果を返却、エラーなし |
| グループ追加失敗 | Stop-Functionでエラー記録、処理停止 |

## 備考

- Id=1はルートグループ（DatabaseEngineServerGroup）を表す
- グループパスはバックスラッシュ（\）区切りの階層パス
- DatabaseEngineServerGroup\プレフィックスは自動除去
- ローカルファイルストアの場合、ComputerName/InstanceName/SqlInstanceは表示されない
- ServerGroupオブジェクトはSMOオブジェクトで、ServerGroups/RegisteredServersコレクションを持つ

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 51-68行目: .OUTPUTSセクション |
| 1-2 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 184-194行目: プロパティ追加と出力 |

**読解のコツ**: ServerGroupはSMOオブジェクトで、ServerGroups（子グループ）とRegisteredServers（登録済みサーバー）のコレクションを持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 91-100行目: パラメータ定義 |
| 2-2 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 104-115行目: サーバーストア取得 |

**主要処理フロー**:
- **107行目**: Get-DbaRegServerStoreでCMSストアを取得
- **114行目**: SqlInstance未指定時はローカルストアを取得

#### Step 3: グループ検索ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 118-155行目: Group指定時の検索ロジック |
| 3-2 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 129-142行目: 階層パス解析 |
| 3-3 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 156-159行目: Group未指定時の処理 |

**主要処理フロー**:
- **121-123行目**: ServerGroupオブジェクトをパス文字列に変換
- **125-127行目**: DatabaseEngineServerGroup\プレフィックス除去
- **129-142行目**: バックスラッシュ分割と階層探索
- **132行目**: DatabaseEngineServerGroupから開始
- **135行目**: ServerGroups[]インデクサーで子グループ取得

#### Step 4: フィルタリングと出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 166-170行目: ExcludeGroup処理 |
| 4-2 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 172-179行目: Id検索処理 |
| 4-3 | Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | 184-195行目: 出力処理 |

**主要処理フロー**:
- **167行目**: 再帰呼び出しで除外対象を取得
- **169行目**: Urn.Valueで比較除外
- **174-178行目**: Id=1はルート、それ以外はGetDescendantRegisteredServers().Parentから検索

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

```
Get-DbaRegServerGroup
    │
    ├─ Get-DbaRegServerStore (サーバーストア取得)
    │      └─ Connect-DbaInstance (CMS時)
    │
    ├─ [Group指定時]
    │      ├─ Get-RegServerGroupReverseParse (オブジェクト→パス変換)
    │      ├─ DatabaseEngineServerGroup\除去
    │      └─ 階層探索
    │             └─ ServerGroups[]インデクサー
    │
    ├─ [ExcludeGroup指定時]
    │      └─ Get-DbaRegServerGroup (再帰呼び出し)
    │
    ├─ [Id指定時]
    │      ├─ Id=1 → DatabaseEngineServerGroup
    │      └─ Id≠1 → GetDescendantRegisteredServers().Parent
    │
    └─ Select-DefaultView (出力)
```

### データフロー図

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

SqlInstance ───────▶ Get-DbaRegServerStore ───▶ ServerStore
                              │
                              ▼
                     DatabaseEngineServerGroup
                              │
         ┌────────────────────┼────────────────────┐
         ▼                    ▼                    ▼
    Group指定           Group未指定           Id指定
         │                    │                    │
         ▼                    ▼                    ▼
    階層パス解析         ServerGroups          Id=1: Root
    Split(\)             全取得              Id≠1: 検索
         │                    │                    │
         └────────────────────┴────────────────────┘
                              │
                              ▼
                     [ExcludeGroup フィルタ]
                              │
                              ▼
                     Add-Member プロパティ追加
                              │
                              ▼                          ServerGroup
                     Select-DefaultView                  │
                                                        ├─ ComputerName
                                                        ├─ InstanceName
                                                        ├─ SqlInstance
                                                        ├─ Name
                                                        ├─ DisplayName
                                                        ├─ Description
                                                        ├─ ServerGroups
                                                        └─ RegisteredServers
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | ソース | グループ取得 |
| Add-DbaRegServerGroup.ps1 | `public/Add-DbaRegServerGroup.ps1` | ソース | グループ追加 |
| Move-DbaRegServerGroup.ps1 | `public/Move-DbaRegServerGroup.ps1` | ソース | グループ移動 |
| Remove-DbaRegServerGroup.ps1 | `public/Remove-DbaRegServerGroup.ps1` | ソース | グループ削除 |
| Get-DbaRegServerStore.ps1 | `public/Get-DbaRegServerStore.ps1` | ソース | ストア取得 |
| Get-RegServerGroupReverseParse.ps1 | `internal/functions/` | ソース | オブジェクト→パス変換 |
