# 機能設計書 429-Add-DbaRegServer

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Add-DbaRegServer`コマンドレットに関する機能設計書である。このコマンドレットは、SQL ServerインスタンスをCentral Management Server（CMS）またはローカルサーバーグループに登録する機能を提供する。

### 本機能の処理概要

`Add-DbaRegServer`は、SQL ServerインスタンスをSSMS（SQL Server Management Studio）の登録済みサーバーとして登録するコマンドレットである。Central Management Server（企業全体の管理用）またはLocal Server Groups（個人用整理）のいずれかに登録できる。

**業務上の目的・背景**：複数のSQL Serverインスタンスを管理するDBAにとって、登録済みサーバーは効率的な接続管理の基盤となる。CMSを使用すると、グループ化されたサーバーに対して一括でクエリを実行したり、ポリシーを適用したりできる。本機能により、接続詳細を毎回手動で入力する必要なく、SSMSから迅速にサーバーへ接続できるようになる。

**機能の利用シーン**：
- 新しいSQL Serverインスタンスを登録済みサーバーに追加する場合
- 複数のサーバーをグループ化して管理する場合
- CMS環境を構築する場合
- 既存の接続情報を保存して再利用する場合
- 自動化スクリプトでサーバー登録を一括実行する場合

**主要な処理内容**：
1. 対象のサーバーグループを取得または作成する
2. RegisteredServerオブジェクトを作成する
3. 接続情報を設定する（サーバー名、説明、接続文字列など）
4. サーバーを登録する
5. 登録結果を返却する

**関連システム・外部連携**：SQL Server Registered Servers機能と連携し、Microsoft.SqlServer.Management.RegisteredServers名前空間のオブジェクトを使用する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | SQL Server Management Studio - Registered Servers | 参照画面 | SSMS上での登録済みサーバー追加に相当 |

## 機能種別

データ登録（INSERT相当）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | CMS使用時のターゲットSQL Serverインスタンス | 有効なSQL Server接続文字列 |
| SqlCredential | PSCredential | No | CMS接続用の代替資格情報 | 有効なPSCredentialオブジェクト |
| ServerName | string | Yes（ServerObject未指定時） | 登録するサーバーの実際の接続名/アドレス | なし |
| Name | string | No | SSMS上で表示される名前。未指定時はServerName | なし |
| Description | string | No | 登録サーバーの説明 | なし |
| Group | object | No | 登録先のサーバーグループ。ネスト可（例: "Production\OLTP"） | なし |
| ActiveDirectoryTenant | string | No | Azure AD認証用のテナントID | なし |
| ActiveDirectoryUserId | string | No | Azure AD認証用のユーザープリンシパル名 | なし |
| ConnectionString | string | No | カスタム接続文字列 | なし |
| OtherParams | string | No | 追加の接続文字列パラメータ | なし |
| InputObject | ServerGroup[] | No | Get-DbaRegServerGroupからのパイプライン入力 | なし |
| ServerObject | Server[] | No | Connect-DbaInstanceからのパイプライン入力 | なし |
| WhatIf | switch | No | 実行内容を表示するのみ | なし |
| Confirm | switch | No | 実行前に確認を求める | なし |
| EnableException | switch | No | 例外をスローするモードを有効化 | なし |

### 入力データソース

- SQL Serverインスタンス直接指定（SqlInstanceパラメータ）
- Get-DbaRegServerGroupからのパイプライン入力（InputObjectパラメータ）
- Connect-DbaInstanceからのパイプライン入力（ServerObjectパラメータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | string | SSMS上で表示される登録サーバー名 |
| ServerName | string | 実際のSQL Server接続文字列/インスタンス名 |
| Group | string | サーバーグループ階層パス |
| Description | string | 登録サーバーの説明 |
| Source | string | 登録元（Central Management Servers, Local Server Groups, Azure Data Studio） |
| ComputerName | string | CMSまたはローカル登録場所のコンピュータ名 |
| InstanceName | string | CMSまたはローカル登録場所のインスタンス名 |
| SqlInstance | string | CMSの完全なSQL Server識別子 |
| ParentServer | object | 親サーバーストアオブジェクトへの参照 |
| Id | int | 登録サーバーの一意識別子 |
| ConnectionString | string | 接続文字列 |
| SecureConnectionString | SecureString | 暗号化された接続文字列 |
| ActiveDirectoryTenant | string | Azure ADテナントID |
| ActiveDirectoryUserId | string | Azure ADユーザープリンシパル名 |
| OtherParams | string | 追加の接続パラメータ |
| CredentialPersistenceType | string | 資格情報の保存方法 |
| ServerType | string | サーバーの種類（DatabaseEngine等） |

### 出力先

- PowerShellパイプライン（標準出力）
- Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerオブジェクトとして出力

## 処理フロー

### 処理シーケンス

```
1. processブロック
   ├─ パラメータ検証（ServerName/ServerObjectのいずれかが必要）
   ├─ Name未指定時の補完
   ├─ SqlInstance/InputObject未指定時（ローカル登録）
   │   ├─ Group指定時 → Get-DbaRegServerGroupで取得、なければ作成
   │   └─ Group未指定時 → ルートグループ（Id=1）を取得
   ├─ SqlInstance指定時（CMS登録）
   │   ├─ Group指定時 → Get-DbaRegServerGroupで取得、なければ作成
   │   └─ Group未指定時 → ルートグループ（Id=1）を取得
   └─ 各サーバーグループへの登録
       ├─ Azure Data Studioの場合はエラー
       ├─ ServerObject指定時
       │   └─ 接続情報をServerObjectから取得して登録
       └─ ServerName指定時
           └─ パラメータから登録情報を設定して登録
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ServerName/ServerObject?}
    B -->|なし| C[Stop-Function]
    B -->|あり| D{Name指定?}
    D -->|No| E[Name = ServerName or ServerObject.Name]
    D -->|Yes| F{SqlInstance/InputObject?}
    E --> F
    F -->|なし（ローカル）| G{Group指定?}
    F -->|あり（CMS）| H{Group指定?}
    G -->|Yes| I[Get-DbaRegServerGroup]
    G -->|No| J[Get-DbaRegServerGroup -Id 1]
    H -->|Yes| K[Get-DbaRegServerGroup -SqlInstance]
    H -->|No| L[Get-DbaRegServerGroup -SqlInstance -Id 1]
    I --> M{グループ存在?}
    K --> M
    M -->|No| N[Add-DbaRegServerGroup]
    M -->|Yes| O[InputObjectに追加]
    N --> O
    J --> O
    L --> O
    O --> P[各reggroup処理]
    P --> Q{Azure Data Studio?}
    Q -->|Yes| R[Stop-Function]
    Q -->|No| S{ServerObject?}
    S -->|Yes| T[ServerObjectから接続情報設定]
    S -->|No| U[パラメータから接続情報設定]
    T --> V[New-Object RegisteredServer]
    U --> V
    V --> W[Create]
    W --> X[Get-DbaRegServer]
    X --> Y{次のグループ?}
    R --> Y
    Y -->|Yes| P
    Y -->|No| Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パラメータ必須 | ServerName/ServerObjectのいずれかが必要 | すべての実行 |
| BR-002 | Name自動補完 | Name未指定時はServerNameまたはServerObject.Nameを使用 | Name未指定時 |
| BR-003 | グループ自動作成 | 指定されたグループが存在しない場合は自動作成 | Group指定時 |
| BR-004 | Azure Data Studio非対応 | Azure Data Studioのグループには登録不可 | Azure Data Studioグループ |
| BR-005 | ServerObject接続情報 | ServerObject使用時は接続文字列とSecureConnectionStringを継承 | ServerObject指定時 |
| BR-006 | 資格情報保存 | ServerObject使用時はCredentialPersistenceType=PersistLoginNameAndPassword | ServerObject指定時 |

### 計算ロジック

特になし。パラメータ値はそのまま登録情報に適用される。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| CMS登録 | msdb.dbo.sysmanagement_shared_registered_servers | INSERT | CMS登録サーバー情報の追加 |
| ローカル登録 | - | ファイル書き込み | ローカルXMLファイルへの保存 |

### テーブル別操作詳細

#### msdb.dbo.sysmanagement_shared_registered_servers（CMS使用時）

| 操作 | 項目（カラム名） | 更新値・条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | Name パラメータ | 表示名 |
| INSERT | server_name | ServerName パラメータ | 接続先 |
| INSERT | description | Description パラメータ | 説明 |
| INSERT | server_group_id | グループのID | 所属グループ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Function | ServerName/ServerObject未指定 | いずれかを指定 |
| - | Stop-Function | Azure Data Studioグループへの登録試行 | 別のグループを使用 |
| - | Stop-Function | 登録失敗 | エラーメッセージを確認 |

### リトライ仕様

リトライ処理は実装されていない。エラー時は-Continueで次のグループを処理。

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

各登録操作は個別に実行される。明示的なトランザクション制御は実装されていない。

## パフォーマンス要件

特に規定なし。軽量なメタデータ登録処理。

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

- SQL Server認証、Windows認証、Azure AD認証をサポート
- 接続資格情報はPSCredentialオブジェクトで安全に管理
- ServerObject使用時はSecureConnectionStringで資格情報を保護
- Azure AD認証の設定（ActiveDirectoryTenant, ActiveDirectoryUserId）をサポート

## 備考

- 著者はChrissy LeMaire
- SupportsShouldProcess対応（WhatIf/Confirm）
- 既存の登録サーバーをインポートする場合はImport-DbaRegServerを使用
- Azure Data Studioの登録サーバーには対応していない

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | .OUTPUTSセクション（81-108行目）で出力オブジェクトの構造を理解 |

**読解のコツ**: Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerはSMO登録サーバー名前空間のオブジェクト。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | パラメータ定義（135-152行目）で入力の受け取り方を確認 |

**主要処理フロー**:
1. **154-165行目**: パラメータ検証とName補完
2. **167-191行目**: ローカル登録時のグループ取得/作成
3. **193-214行目**: CMS登録時のグループ取得/作成
4. **216-270行目**: 各グループへの登録処理

#### Step 3: 登録ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | ServerObject使用時の登録（228-252行目） |
| 3-2 | Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | ServerName使用時の登録（253-268行目） |

**主要処理フロー**:
- **237-246行目**: RegisteredServerオブジェクト作成（ServerObject使用）
- **255-262行目**: RegisteredServerオブジェクト作成（ServerName使用）
- **248, 264行目**: Get-DbaRegServerで登録結果取得

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

```
Add-DbaRegServer
    │
    ├─ Get-DbaRegServerGroup
    │      └─ サーバーグループ取得
    │
    ├─ Add-DbaRegServerGroup
    │      └─ サーバーグループ作成（存在しない場合）
    │
    ├─ New-Object RegisteredServer
    │      └─ 登録サーバーオブジェクト作成
    │
    ├─ RegisteredServer.Create()
    │      └─ 登録実行
    │
    └─ Get-DbaRegServer
           └─ 登録結果取得
```

### データフロー図

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

SqlInstance ───────┐
ServerName        ├──▶ Get-DbaRegServerGroup ───▶ ServerGroup
Group             │           │
                  │           ▼
                  │   {グループなければ}
                  │   Add-DbaRegServerGroup
                  │           │
                  │           ▼
ServerObject ─────┴──▶ New-Object RegisteredServer
ConnectionString              │
Description                   ▼
                       RegisteredServer.Create()
                              │
                              ▼
                       Get-DbaRegServer ───────▶ RegisteredServer
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Add-DbaRegServer.ps1 | `public/Add-DbaRegServer.ps1` | ソース | メイン機能の実装 |
| Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | ソース | 登録サーバー取得 |
| Get-DbaRegServerGroup.ps1 | `public/Get-DbaRegServerGroup.ps1` | ソース | サーバーグループ取得 |
| Add-DbaRegServerGroup.ps1 | `public/Add-DbaRegServerGroup.ps1` | ソース | サーバーグループ作成 |
| Import-DbaRegServer.ps1 | `public/Import-DbaRegServer.ps1` | ソース | 登録サーバーインポート（関連機能） |
| Copy-DbaRegServer.ps1 | `public/Copy-DbaRegServer.ps1` | ソース | 登録サーバーコピー（関連機能） |
