# 画面設計書 145-登録済みサーバー管理

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける登録済みサーバー（Registered Server）管理機能の設計仕様を定義する。

### 本画面の処理概要

SSMS（SQL Server Management Studio）、Azure Data Studio、およびCentral Management Server（CMS）に登録されたSQL Serverインスタンス情報を管理する機能群を提供する。DBAは登録済みサーバーを使用して、環境内の複数のSQL Serverインスタンスを整理し、素早く接続できる。

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

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドを実行する。
- `Get-DbaRegServer` - 登録済みサーバーの取得
- `Add-DbaRegServer` - 登録済みサーバーの追加
- `Remove-DbaRegServer` - 登録済みサーバーの削除
- `Copy-DbaRegServer` - 登録済みサーバーのコピー
- `Export-DbaRegServer` - 登録済みサーバーのエクスポート
- `Import-DbaRegServer` - 登録済みサーバーのインポート
- `Move-DbaRegServer` - 登録済みサーバーの移動

**主要な操作・処理内容**：
1. サーバー取得（Get-DbaRegServer）：CMS、ローカルSSMS、Azure Data Studioから登録済みサーバーを取得
2. サーバー追加（Add-DbaRegServer）：CMSまたはローカルに新しいサーバーを登録
3. サーバー削除（Remove-DbaRegServer）：登録済みサーバーを削除
4. サーバーコピー（Copy-DbaRegServer）：登録済みサーバーを別のCMSにコピー
5. エクスポート（Export-DbaRegServer）：登録済みサーバーをXMLファイルに出力
6. インポート（Import-DbaRegServer）：XMLファイルから登録済みサーバーを読み込み
7. サーバー移動（Move-DbaRegServer）：登録済みサーバーを別のグループに移動

**画面遷移**：CLIベースのため画面遷移は存在しない。Get-DbaRegServerの出力を他のdbatoolsコマンドにパイプすることで、複数サーバーへの一括操作が可能。

**権限による表示制御**：CMSへのアクセスにはSQL Server接続権限が必要。ローカル登録済みサーバーへのアクセスにはファイルシステム権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 250 | Get-DbaRegServer | 主機能 | 登録済みサーバーの取得 |
| 20 | Add-DbaRegServer | 主機能 | 登録済みサーバーの追加 |
| 335 | Remove-DbaRegServer | 主機能 | 登録済みサーバーの削除 |
| 82 | Copy-DbaRegServer | 主機能 | 登録済みサーバーのコピー |
| 125 | Export-DbaRegServer | 主機能 | 登録済みサーバーのエクスポート |
| 166 | Import-DbaRegServer | 主機能 | 登録済みサーバーのインポート |
| 285 | Move-DbaRegServer | 主機能 | 登録済みサーバーの移動 |
| - | Get-DbaRegServerGroup | 補助機能 | サーバーグループの取得 |
| - | Get-DbaRegServerStore | 補助機能 | サーバーストアの取得 |

## 画面種別

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

## URL/ルーティング

```powershell
# ローカル登録済みサーバーの取得
Get-DbaRegServer

# CMSから登録済みサーバーを取得
Get-DbaRegServer -SqlInstance sqlcms

# 特定グループのサーバーを取得
Get-DbaRegServer -SqlInstance sqlcms -Group "Production\OLTP"

# パターンでフィルタリング
Get-DbaRegServer -SqlInstance sqlcms -Pattern "^prod"

# サーバーを追加
Add-DbaRegServer -SqlInstance sqlcms -ServerName sql01 -Name "Production DB" -Group "Production"

# サーバーを削除
Remove-DbaRegServer -SqlInstance sqlcms -ServerName sql01

# エクスポート
Export-DbaRegServer -SqlInstance sqlcms -Path C:\temp\servers.xml

# インポート
Import-DbaRegServer -SqlInstance sqlcms -Path C:\temp\servers.xml

# サーバーを移動
Move-DbaRegServer -SqlInstance sqlcms -ServerName sql01 -Group "Archive"
```

## 入出力項目

### Get-DbaRegServer パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | CMSインスタンス（未指定時はローカル） |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Name | string[] | No | 表示名でフィルタリング |
| ServerName | string[] | No | サーバー名でフィルタリング |
| Pattern | string[] | No | 正規表現パターンでフィルタリング |
| ExcludeServerName | string[] | No | 除外するサーバー名 |
| Group | string[] | No | グループでフィルタリング |
| ExcludeGroup | string[] | No | 除外するグループ |
| Id | int[] | No | IDでフィルタリング |
| IncludeSelf | switch | No | CMSインスタンス自身を含める |
| ResolveNetworkName | switch | No | DNS解決を実行 |
| IncludeLocal | switch | No | ローカルサーバーも含める |
| EnableException | switch | No | 例外処理モードの有効化 |

### Add-DbaRegServer パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | No | CMSインスタンス（未指定時はローカル） |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| ServerName | string | Yes* | 登録するサーバー名 |
| Name | string | No | 表示名（未指定時はServerName） |
| Description | string | No | 説明 |
| Group | object | No | 登録先グループ |
| ActiveDirectoryTenant | string | No | Azure ADテナントID |
| ActiveDirectoryUserId | string | No | Azure ADユーザー名 |
| ConnectionString | string | No | 接続文字列 |
| OtherParams | string | No | 追加接続パラメータ |
| InputObject | ServerGroup[] | No | パイプライン入力用グループ |
| ServerObject | Server[] | No | SMO Serverオブジェクト |
| EnableException | switch | No | 例外処理モードの有効化 |

*ServerNameまたはServerObjectのいずれかが必須。

## 表示項目

### Get-DbaRegServer 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | string | 登録済みサーバーの表示名 |
| ServerName | string | SQL Serverの接続文字列/インスタンス名 |
| Group | string | グループパス（階層構造、\区切り） |
| Description | string | 登録済みサーバーの説明 |
| Source | string | ソース（Central Management Servers/Local Server Groups/Azure Data Studio） |
| ComputerName | string | NetBIOSコンピュータ名（ResolveNetworkName時） |
| FQDN | string | 完全修飾ドメイン名（ResolveNetworkName時） |
| IPAddress | string | IPアドレス（ResolveNetworkName時） |
| ConnectionString | string | 復号化された接続文字列 |
| SecureConnectionString | SecureString | 暗号化された接続文字列 |
| Id | int | 内部ID |
| ServerType | string | サーバータイプ（DatabaseEngine等） |
| CredentialPersistenceType | string | 資格情報の保存タイプ |

## イベント仕様

### 1-登録済みサーバー取得

**Get-DbaRegServer 実行時**

1. SqlInstance指定時：Get-DbaRegServerStoreでCMSストアを取得
2. Group指定時：Get-DbaRegServerGroupでグループを取得、GetDescendantRegisteredServers()で配下サーバーを取得
3. SqlInstance未指定またはIncludeLocal指定時：
   - ローカルSSMSのRegSrvr.xmlファイルを読み込み
   - Azure Data Studioの接続情報を読み込み
4. Name/ServerName/Pattern/ExcludeServerName/Id等でフィルタリング
5. ConnectionStringWithEncryptedPasswordから接続文字列を復号化
6. ResolveNetworkName指定時：Resolve-DbaNetworkNameでDNS解決
7. Select-DefaultViewでデフォルト表示プロパティを設定

### 2-登録済みサーバー追加

**Add-DbaRegServer 実行時**

1. ServerNameまたはServerObjectの入力検証
2. Group指定時：Get-DbaRegServerGroupでグループを取得、なければAdd-DbaRegServerGroupで作成
3. 各登録先グループに対して：
   - Azure Data Studioの場合はエラー（書き込み不可）
   - RegisteredServerオブジェクトを作成
   - ServerName/Description/ConnectionString等を設定
   - Create()メソッドで登録
4. Get-DbaRegServerで登録結果を取得して出力

### 3-登録済みサーバー削除

**Remove-DbaRegServer 実行時**

1. Get-DbaRegServerで対象サーバーを取得
2. Azure Data Studioの場合はエラー
3. ShouldProcessで確認
4. Drop()メソッドで削除

### 4-エクスポート

**Export-DbaRegServer 実行時**

1. Get-DbaRegServerで対象サーバーを取得
2. XMLファイルにシリアライズして出力
3. CredentialパスワードはBase64エンコード

### 5-インポート

**Import-DbaRegServer 実行時**

1. XMLファイルを読み込み
2. 各サーバー情報をAdd-DbaRegServerで登録

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| サーバー取得 | msdb.dbo.sysmanagement_shared_registered_servers | SELECT | CMSサーバー情報読み取り |
| サーバー追加 | msdb.dbo.sysmanagement_shared_registered_servers | INSERT | CMSサーバー登録 |
| サーバー削除 | msdb.dbo.sysmanagement_shared_registered_servers | DELETE | CMSサーバー削除 |

ローカル登録済みサーバーの場合はRegSrvr.xmlファイルの読み書きとなり、データベース操作は発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| MSG001 | エラー | "You must specify either ServerName or ServerObject" | 入力パラメータ不足 |
| MSG002 | エラー | "Cannot access Central Management Server 'X'" | CMS接続失敗 |
| MSG003 | エラー | "You cannot use dbatools to remove or add registered servers in Azure Data Studio" | Azure Data Studio書き込み試行 |
| MSG004 | エラー | "Failed to add X on target" | サーバー追加失敗 |
| MSG005 | 情報 | "Adding CMS instance" | IncludeSelf使用時 |

## 例外処理

| 例外条件 | 対応処理 |
|---------|---------|
| CMS接続失敗 | Stop-Functionでエラー記録、Continueで次インスタンスへ |
| Azure Data Studio書き込み試行 | Stop-Functionでエラー記録、処理停止 |
| サーバー追加失敗 | Stop-Functionでエラー記録、Continueで次グループへ |
| DNS解決失敗 | 警告なしでスキップ、処理継続 |

## 備考

- Azure Data Studioの登録済みサーバーは読み取り専用（追加・削除・移動不可）
- ローカル登録済みサーバーはユーザープロファイル下のRegSrvr.xmlに保存
- CMSはmsdbデータベースのsysmanagement_*テーブルに保存
- 接続文字列のパスワードはDPAPI（Data Protection API）で暗号化
- Patternパラメータは正規表現構文をサポート
- グループは\区切りの階層パス（例：Production\OLTP\Primary）

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 69-101行目: .OUTPUTSセクション |
| 1-2 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | 81-108行目: .OUTPUTSセクション |

**読解のコツ**: RegisteredServerはSMOオブジェクトであり、Source/Group等のプロパティはAdd-Memberで追加される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 155-173行目: パラメータ定義 |
| 2-2 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 196-225行目: CMS/ローカルサーバー取得 |
| 2-3 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | 136-152行目: パラメータ定義 |

**主要処理フロー（Get-DbaRegServer）**:
- **206行目**: Get-DbaRegServerStoreでCMSストアを取得
- **212行目**: Get-DbaRegServerGroupでグループ取得
- **217行目**: GetDescendantRegisteredServers()でサーバー取得
- **228-276行目**: ローカル/Azure Data Studioサーバー取得

#### Step 3: ローカル/Azure Data Studio処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 228-276行目: ローカルファイル読み込み |
| 3-2 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 229行目: LocalFileStore.DomainInstanceName |
| 3-3 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 240-273行目: Azure Data Studio接続処理 |

**主要処理フロー**:
- **232-234行目**: InitChildObjectsメソッドでローカルストアを初期化
- **242行目**: Get-ADSConnectionでAzure Data Studio接続情報取得
- **260行目**: RegisteredServerオブジェクトを動的生成

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 278-301行目: フィルタリング処理 |
| 4-2 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 327-336行目: パスワード復号化 |
| 4-3 | Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | 353-370行目: DNS解決処理 |

**主要処理フロー**:
- **180-182行目**: Unprotect-String関数でDPAPI復号化
- **329-332行目**: 接続文字列からパスワードを復号化
- **355行目**: Resolve-DbaNetworkNameでDNS解決

#### Step 5: サーバー追加処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | 167-191行目: ローカルグループ取得/作成 |
| 5-2 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | 216-270行目: サーバー登録処理 |
| 5-3 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | 237-246行目: RegisteredServerオブジェクト作成 |

**主要処理フロー**:
- **171-174行目**: Get-DbaRegServerGroupでグループ取得
- **181-184行目**: Add-DbaRegServerGroupでグループ作成
- **237行目**: RegisteredServerコンストラクタ呼び出し
- **246行目**: Create()メソッドで永続化

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

```
Get-DbaRegServer
    │
    ├─ Get-DbaRegServerStore (CMSストア取得)
    │      └─ Connect-DbaInstance
    │
    ├─ Get-DbaRegServerGroup (グループ取得)
    │      └─ GetDescendantRegisteredServers()
    │
    ├─ [ローカル/Azure Data Studio]
    │      ├─ LocalFileStore.DomainInstanceName
    │      ├─ InitChildObjects() (リフレクション)
    │      └─ Get-ADSConnection
    │
    ├─ [フィルタリング]
    │      ├─ Where-Object Name/ServerName/Id
    │      └─ Pattern正規表現マッチ
    │
    ├─ Unprotect-String (パスワード復号化)
    │      └─ ProtectedData.Unprotect (DPAPI)
    │
    └─ Resolve-DbaNetworkName (DNS解決)

Add-DbaRegServer
    │
    ├─ Test-Bound (入力検証)
    │
    ├─ Get-DbaRegServerGroup (グループ取得)
    │
    ├─ Add-DbaRegServerGroup (グループ作成)
    │
    └─ [foreach reggroup]
           │
           ├─ RegisteredServer()コンストラクタ
           │
           ├─ プロパティ設定
           │      ├─ ServerName
           │      ├─ Description
           │      ├─ ConnectionString
           │      └─ CredentialPersistenceType
           │
           ├─ Create() (永続化)
           │
           └─ Get-DbaRegServer (登録確認)
```

### データフロー図

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

SqlInstance ───────▶ Get-DbaRegServerStore ───▶ ServerStore
                              │
                              ▼
                     Get-DbaRegServerGroup
                              │
                              ▼
                     GetDescendantRegisteredServers()
                              │
IncludeLocal ─────────────────┼──────────────────────────────▶
                              │                              │
                              ▼                              ▼
                     LocalFileStore                  Azure Data Studio
                              │                              │
                              ├──────────────────────────────┘
                              ▼
                     [フィルタリング]
                     Name/ServerName/Pattern/ExcludeServerName
                              │
                              ▼
                     [パスワード復号化]                   RegisteredServer
                     Unprotect-String                    │
                              │                          ├─ Name
                              ▼                          ├─ ServerName
                     [DNS解決]                           ├─ Group
                     Resolve-DbaNetworkName              ├─ Description
                              │                          ├─ Source
                              ▼                          ├─ ConnectionString
                     Select-DefaultView                  └─ (その他)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | ソース | 登録済みサーバー取得 |
| Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | ソース | 登録済みサーバー追加 |
| Remove-DbaRegServer.ps1 | `public/Remove-DbaRegServer.ps1` | ソース | 登録済みサーバー削除 |
| Copy-DbaRegServer.ps1 | `public/Copy-DbaRegServer.ps1` | ソース | 登録済みサーバーコピー |
| Export-DbaRegServer.ps1 | `public/Export-DbaRegServer.ps1` | ソース | エクスポート |
| Import-DbaRegServer.ps1 | `public/Import-DbaRegServer.ps1` | ソース | インポート |
| Move-DbaRegServer.ps1 | `public/Move-DbaRegServer.ps1` | ソース | 移動 |
| Get-DbaRegServerStore.ps1 | `public/Get-DbaRegServerStore.ps1` | ソース | ストア取得 |
| Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | ソース | グループ取得 |
