# 機能設計書 349-New-DbaLinkedServer

## 概要

本ドキュメントは、dbatools PowerShellモジュールのNew-DbaLinkedServer関数の機能設計書である。この関数はリモートSQL Serverインスタンスまたは異種データソースへの新しいリンクサーバー接続を作成する。

### 本機能の処理概要

New-DbaLinkedServer関数は、SQL Serverインスタンスに新しいリンクサーバーを作成し、リモートデータベースや異種データソースをローカルテーブルのようにクエリできるようにする。

**業務上の目的・背景**：分散データベース環境では、リモートサーバーへの接続を確立し、サーバー間でデータをクエリする必要がある。SSMSやT-SQLスクリプトで手動でリンクサーバーを構成する代わりに、この関数は一貫したセキュリティコンテキスト管理を提供しながらプロセスを自動化する。

**機能の利用シーン**：リモートSQL Serverへの接続を確立する場合、異種データソース（Oracle、Accessなど）への接続を作成する場合、PowerShellスクリプトで自動的にリンクサーバーをセットアップする場合に使用される。

**主要な処理内容**：
1. SQL Serverインスタンスに接続する
2. SMOを使用してLinkedServerオブジェクトを作成する
3. プロバイダ、データソース、カタログなどのプロパティを設定する
4. セキュリティコンテキストを構成する（マッピングされていないログイン用）
5. 作成されたリンクサーバーを返す

**関連システム・外部連携**：SQL Server SMO、OLE DBプロバイダ、リモートデータソース。

**権限による制御**：リンクサーバーを作成するための適切なSQL Server権限（ALTER ANY LINKED SERVERなど）が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | PowerShellコマンドラインから直接実行 |

## 機能種別

データ作成（リンクサーバー構成の作成）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | 有効なSQL Serverインスタンス名 |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | 有効なPSCredentialオブジェクト |
| LinkedServer | string | Yes (Test-Bound) | リンクサーバー名 | 一意の名前 |
| ServerProduct | string | No | リモートデータソースの製品名 | 任意の文字列 |
| Provider | string | No | OLE DBプロバイダ名 | 有効なプロバイダ名 |
| DataSource | string | No | リモートデータソースの接続文字列 | 有効な接続文字列 |
| Location | string | No | データソースの物理的位置情報 | 任意の文字列 |
| ProviderString | string | No | プロバイダへの追加接続プロパティ | 任意の文字列 |
| Catalog | string | No | デフォルトのデータベース/カタログ名 | 有効なデータベース名 |
| SecurityContext | string | No | セキュリティコンテキストオプション | NoConnection/WithoutSecurityContext/CurrentSecurityContext/SpecifiedSecurityContext |
| SecurityContextRemoteUser | string | No | リモートログイン名 | SpecifiedSecurityContext時に必須 |
| SecurityContextRemoteUserPassword | SecureString | No | リモートログインパスワード | SpecifiedSecurityContext時に必須 |
| InputObject | Server[] | No | パイプライン入力用サーバーオブジェクト | SMO Serverオブジェクト |
| EnableException | switch | No | 例外処理の動作を制御 | true/false |
| Confirm | switch | No | 変更前の確認 | true/false |
| WhatIf | switch | No | 実行シミュレーション | true/false |

### 入力データソース

- SqlInstance: SQL Serverインスタンス指定
- InputObject: Connect-DbaInstanceからのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Name | string | リンクサーバー名 |
| DataSource | string | リモートデータソース |
| ProviderName | string | OLE DBプロバイダ名 |
| ProductName | string | 製品名 |
| LinkedServerLogins | int | ログインマッピング数 |

### 出力先

PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.LinkedServer）

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ LinkedServerパラメータの必須チェック
   └─ SpecifiedSecurityContext時のユーザー/パスワード必須チェック

2. SQL Server接続
   └─ SqlInstance指定時: Connect-DbaInstanceで接続
   └─ InputObject指定時: そのまま使用

3. 既存チェック
   └─ 同名のリンクサーバーが既に存在する場合はエラー

4. リンクサーバー作成
   └─ SMO LinkedServerオブジェクトを作成
   └─ プロパティを設定
   └─ Create()メソッドを実行

5. セキュリティコンテキスト設定
   ├─ NoConnection: sp_droplinkedsrvlogin
   ├─ WithoutSecurityContext: sp_addlinkedsrvlogin useself=False
   ├─ CurrentSecurityContext: sp_addlinkedsrvlogin useself=True
   └─ SpecifiedSecurityContext: sp_addlinkedsrvlogin with rmtuser/rmtpassword

6. 結果出力
   └─ Get-DbaLinkedServerで作成されたリンクサーバーを取得して返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{LinkedServer指定?}
    B -->|No| C[エラー: 必須パラメータ]
    B -->|Yes| D{SpecifiedSecurityContext?}
    D -->|Yes| E{RemoteUser/Password?}
    E -->|No| F[エラー: 必須パラメータ]
    E -->|Yes| G[Connect-DbaInstance]
    D -->|No| G
    G --> H{既存リンクサーバー?}
    H -->|Yes| I[エラー: 既に存在]
    H -->|No| J{ShouldProcess?}
    J -->|WhatIf| K[シミュレーション]
    J -->|実行| L[New-Object LinkedServer]
    L --> M[プロパティ設定]
    M --> N[Create]
    N --> O{SecurityContext設定}
    O -->|NoConnection| P[sp_droplinkedsrvlogin]
    O -->|WithoutSecurityContext| Q[sp_addlinkedsrvlogin useself=False]
    O -->|CurrentSecurityContext| R[sp_addlinkedsrvlogin useself=True]
    O -->|SpecifiedSecurityContext| S[sp_addlinkedsrvlogin with user/pass]
    P --> T[Get-DbaLinkedServer]
    Q --> T
    R --> T
    S --> T
    T --> U[結果出力]
    U --> V[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | LinkedServer必須 | LinkedServerパラメータは必須 | 常に適用 |
| BR-002 | 一意性 | 同名のリンクサーバーは作成不可 | 常に適用 |
| BR-003 | SpecifiedSecurityContext | ユーザーとパスワードが必須 | SecurityContext=SpecifiedSecurityContext時 |
| BR-004 | デフォルトセキュリティコンテキスト | WithoutSecurityContextがデフォルト | SecurityContext未指定時 |
| BR-005 | プロバイダ推奨 | MSOLEDBSQLまたはMSOLEDBSQL19を推奨 | SQL Server接続時 |
| BR-006 | SQLNCLI非推奨 | SQL Server Native Clientは非推奨・削除済み | SQL Server 2022/SSMS 19以降 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リンクサーバー作成 | sys.servers | INSERT | LinkedServer.Create()実行 |
| ログイン設定 | sys.linked_logins | INSERT/UPDATE | sp_addlinkedsrvlogin/sp_droplinkedsrvlogin実行 |

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

#### sys.servers
| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name, product, provider, data_source, catalog, location, provider_string | パラメータで指定された値 | LinkedServer.Create()で挿入 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 必須パラメータ不足 | LinkedServer未指定 | LinkedServerを指定 |
| - | 必須パラメータ不足 | SpecifiedSecurityContextでユーザー/パスワード未指定 | RemoteUser/Passwordを指定 |
| - | 重複エラー | 同名のリンクサーバーが既に存在 | 異なる名前を使用または既存を削除 |
| - | 作成失敗 | プロバイダ不足など | プロバイダをインストール |

### リトライ仕様

明示的なリトライ機能はなし。

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

リンクサーバー作成とセキュリティコンテキスト設定は個別に実行される。作成成功後にセキュリティコンテキスト設定が失敗した場合、リンクサーバーは作成された状態で残る。

## パフォーマンス要件

- リンクサーバー作成は通常数秒以内で完了
- リモートデータソースへの接続検証は行わない（作成のみ）

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

- SpecifiedSecurityContext使用時はパスワードがプレーンテキストでSQL Serverに送信される
- SecurityContextRemoteUserPasswordはSecureStringとして受け取るが、SQLクエリ実行時に変換される
- 適切な権限（ALTER ANY LINKED SERVER）が必要
- ローカルログインとリモートログインのマッピングにはNew-DbaLinkedServerLoginを使用

## 備考

- Connect-DbaInstanceからのパイプライン入力をサポート
- 作成後のリンクサーバーはGet-DbaLinkedServerで取得して返される
- セキュリティコンテキストは「マッピングされていないログイン」用の設定
- 個別のログインマッピングはNew-DbaLinkedServerLoginを使用

---

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

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

### 推奨読解順序

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

出力されるLinkedServerオブジェクトの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | New-DbaLinkedServer.ps1 | `public/New-DbaLinkedServer.ps1` | 92-117行目の出力仕様コメントを確認 |

**読解のコツ**: 出力はGet-DbaLinkedServerを呼び出して取得したLinkedServerオブジェクト。

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

関数の入口と主要パラメータを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaLinkedServer.ps1 | `public/New-DbaLinkedServer.ps1` | 133-151行目のパラメータ定義を確認 |

**主要処理フロー**:
1. **133-151行目**: param()ブロックでパラメータ定義
2. **144行目**: SecurityContextのValidateSet
3. **146-147行目**: RemoteUser/RemoteUserPasswordパラメータ

#### Step 3: 入力検証ロジックを理解する

processブロック冒頭の検証を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaLinkedServer.ps1 | `public/New-DbaLinkedServer.ps1` | 154-167行目の入力検証 |

**主要処理フロー**:
- **154-157行目**: LinkedServer必須チェック
- **159-167行目**: SpecifiedSecurityContext時の追加検証

#### Step 4: 作成処理を理解する

リンクサーバー作成の本体を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | New-DbaLinkedServer.ps1 | `public/New-DbaLinkedServer.ps1` | 173-227行目の作成処理 |

**主要処理フロー**:
- **175-177行目**: 既存チェック
- **179-207行目**: LinkedServerオブジェクト作成とプロパティ設定
- **209-218行目**: セキュリティコンテキスト設定
- **221行目**: Get-DbaLinkedServerで結果を返す

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

```
New-DbaLinkedServer
    │
    ├─ Test-Bound (パラメータチェック)
    │
    ├─ Connect-DbaInstance (SqlInstance指定時)
    │
    ├─ New-Object Microsoft.SqlServer.Management.Smo.LinkedServer
    │      └─ リンクサーバーオブジェクト作成
    │
    ├─ $newLinkedServer.Create()
    │      └─ リンクサーバー作成
    │
    ├─ $server.Query() (セキュリティコンテキスト設定)
    │      ├─ sp_droplinkedsrvlogin
    │      └─ sp_addlinkedsrvlogin
    │
    └─ Get-DbaLinkedServer
           └─ 作成されたリンクサーバーを取得
```

### データフロー図

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

SqlInstance ──────▶ Connect-DbaInstance ──▶ 接続
                          │
LinkedServer ────▶ 入力検証 ──▶ バリデーション
Provider ────────┤        │
DataSource ──────┤        ▼
Catalog ─────────┤ New-Object LinkedServer ──▶ オブジェクト作成
                 │        │
                 │        ▼
                 │ プロパティ設定 ──▶ 構成
                 │        │
                 │        ▼
                 │ Create() ──▶ リンクサーバー作成
                 │        │
SecurityContext ─┘        ▼
                 sp_addlinkedsrvlogin ──▶ セキュリティ設定
                          │
                          ▼
                 Get-DbaLinkedServer ──▶ LinkedServerオブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaLinkedServer.ps1 | `public/New-DbaLinkedServer.ps1` | ソース | メイン関数 |
| Get-DbaLinkedServer.ps1 | `public/Get-DbaLinkedServer.ps1` | ソース | 作成後の取得に使用 |
| Remove-DbaLinkedServer.ps1 | `public/Remove-DbaLinkedServer.ps1` | ソース | リンクサーバー削除関数 |
| New-DbaLinkedServerLogin.ps1 | `public/New-DbaLinkedServerLogin.ps1` | ソース | ログインマッピング作成関数 |
