# 機能設計書 588-Watch-DbaDbLogin

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Watch-DbaDbLogin`コマンドレットに関する機能設計書です。本機能は複数のSQL Serverインスタンス間のアクティブな接続をモニタリングし、クライアント詳細を中央の追跡テーブルにログ記録します。

### 本機能の処理概要

`Watch-DbaDbLogin`は、sys.dm_exec_sessionsおよびsys.dm_exec_requests DMVを照会してリアルタイムの接続アクティビティを取得し、ログイン名、クライアントホスト名、アプリケーション名、データベース使用状況、タイムスタンプを中央モニタリングテーブルに記録します。

**業務上の目的・背景**：サーバーマイグレーションやアプリケーション更新を計画する際、不十分な接続ドキュメントが問題となります。5〜10分ごとに数週間実行することで、誰がどこから何に接続しているかの包括的な状況を把握できます。忘れられたアプリケーションの特定、マイグレーション時の接続文字列の検証、実際のドキュメントに頼らないデータベース使用パターンの文書化に役立ちます。

**機能の利用シーン**：
- サーバーマイグレーション計画時の接続状況調査
- アプリケーション更新前の影響分析
- 監査目的での接続履歴追跡
- 未知のアプリケーション接続の発見
- データベース使用パターンの分析

**主要な処理内容**：
1. 保存先SQL Serverインスタンスへの接続
2. モニタリング対象サーバーリストの取得（CMS、ファイル、パイプライン）
3. 各対象サーバーへの接続
4. sys.dm_exec_sessions/dm_exec_requests DMVの照会
5. ローカル接続とシステムデータベースのフィルタリング
6. Write-DbaDbTableDataによる結果の保存

**関連システム・外部連携**：Central Management Server (CMS)、Get-DbaRegServer、Write-DbaDbTableDataを使用します。

**権限による制御**：最も正確な結果を得るにはsysadmin権限が推奨されます。SQL Server 2005以上に対応しています。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 166 | ログイン監視 | 主機能 | ログインの監視 |

## 機能種別

監視 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance | No | 監視データを保存するSQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | 保存先インスタンス接続用の代替資格情報 | - |
| Database | string | No | 監視データを保存するデータベース | - |
| Table | string | No | 監視データを保存するテーブル（デフォルト: DbaTools-WatchDbLogins） | - |
| SqlCms | string | No | モニタリング対象サーバーを取得するCMSサーバー | - |
| ServersFromFile | string | No | モニタリング対象サーバー一覧ファイルパス | ファイル存在確認 |
| InputObject | Server[] | No | パイプラインからの接続済みサーバーオブジェクト | - |
| EnableException | switch | No | 例外をスローするモード | - |

### 入力データソース

- Central Management Server (CMS) からの登録サーバー
- テキストファイルからのサーバー一覧
- パイプラインからの接続済みサーバーオブジェクト
- 対象サーバーのsys.dm_exec_sessions/dm_exec_requests DMV

## 出力仕様

### 出力データ

本機能はパイプライン出力を行いません。データは指定されたデータベーステーブルに直接書き込まれます。

保存されるテーブルの列：

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | モニタリング対象のコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| LoginTime | DateTime | ログイン時刻 |
| Login | string | ログイン名 |
| Host | string | クライアントホスト名 |
| Program | string | アプリケーション名 |
| DatabaseId | int | データベースID |
| Database | string | データベース名 |
| IsSystem | bit | システムプロセスかどうか |
| CaptureTime | DateTime | データ取得時刻 |

### 出力先

指定されたSQL ServerインスタンスのDatabaseパラメータで指定されたデータベース内のTableパラメータで指定されたテーブル（デフォルト: DbaTools-WatchDbLogins）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ SqlCms、ServersFromFile、InputObjectのいずれかが必要

2. 保存先インスタンスへの接続
   └─ Connect-DbaInstance

3. モニタリング対象サーバーの取得
   └─ SqlCms: Get-DbaRegServerで取得
   └─ ServersFromFile: Get-Contentでファイル読み込み
   └─ InputObject: パイプラインから受け取り

4. 各対象サーバーへの接続
   └─ Connect-DbaInstance（MinimumVersion 9）

5. sysadmin権限チェック
   └─ Test-SqlSaでチェック、権限なしの場合はスキップ

6. DMVクエリ実行
   └─ SQL 2008-2010: database_idがrequestからのみ取得可能
   └─ SQL 2012+: sessionからもdatabase_id取得可能

7. 結果のフィルタリング
   └─ ローカルサーバー接続を除外
   └─ システムデータベース（master, msdb, model, tempdb）を除外
   └─ 除外対象プログラム（SSMS Query, SQL Management）を除外

8. データの保存
   └─ ConvertTo-DbaDataTableで変換
   └─ Write-DbaDbTableDataでテーブルに書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlCms/ServersFromFile/InputObject指定?}
    B -->|No| C[エラー終了]
    B -->|Yes| D[Connect-DbaInstance 保存先]
    D --> E{接続成功?}
    E -->|No| C
    E -->|Yes| F{SqlCms指定?}
    F -->|Yes| G[Get-DbaRegServer]
    F -->|No| H{ServersFromFile指定?}
    H -->|Yes| I[Get-Content ファイル読み込み]
    H -->|No| J[InputObjectを使用]
    G --> K[各サーバーへ接続]
    I --> K
    J --> K
    K --> L{sysadmin権限?}
    L -->|No| M[警告、スキップ]
    L -->|Yes| N{SQL Serverバージョン?}
    N -->|2008-2010| O[旧形式SQLクエリ]
    N -->|2012+| P[新形式SQLクエリ]
    O --> Q[クエリ実行]
    P --> Q
    Q --> R[ローカル/システムDB除外]
    R --> S{データあり?}
    S -->|No| T[次のサーバーへ]
    S -->|Yes| U[Write-DbaDbTableData]
    U --> T
    M --> T
    T --> V{次のサーバー?}
    V -->|Yes| K
    V -->|No| W[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-588-01 | サーバーリストソース必須 | SqlCms、ServersFromFile、InputObjectのいずれかが必要 | 常時 |
| BR-588-02 | sysadmin推奨 | sysadmin権限がない場合は結果が不十分なためスキップ | 常時 |
| BR-588-03 | ローカル接続除外 | 対象サーバー自身からの接続は除外 | 常時 |
| BR-588-04 | システムDB除外 | master, msdb, model, tempdbは除外 | 常時 |
| BR-588-05 | 特定プログラム除外 | SSMS Query、SQL Managementプログラムは除外 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セッション情報取得 | sys.dm_exec_sessions | SELECT | アクティブセッション情報取得 |
| リクエスト情報取得 | sys.dm_exec_requests | SELECT | アクティブリクエスト情報取得 |
| 監視データ保存 | [Table] | INSERT | 監視結果をテーブルに挿入 |

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

#### 監視テーブル（DbaTools-WatchDbLogins）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | 全列 | DMVから取得した接続情報 | AutoCreateTable有効 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InputError | サーバーリストソースなし | Stop-Function |
| - | ConnectionError | 保存先接続失敗 | Stop-Function |
| - | CMSError | CMSアクセス失敗 | Stop-Function |
| - | FileNotFoundError | サーバーファイルなし | Stop-Function |
| - | ConnectionError | 対象サーバー接続失敗 | Stop-Function、次のサーバーへ |

### リトライ仕様

リトライ処理なし。各サーバーは独立して処理されます。

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

Write-DbaDbTableDataによる書き込みは各サーバーごとに実行されます。

## パフォーマンス要件

- 5〜10分間隔での定期実行を想定
- 多数のサーバーを監視する場合は処理時間に注意

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

- 対象サーバーでのsysadmin権限が推奨
- SQL Server 2005以上対応（MinimumVersion 9）
- 接続情報が中央テーブルに保存されるためアクセス制御に注意

## 備考

- テーブルが存在しない場合は自動作成（AutoCreateTable）
- SQL Serverバージョンによってdatabase_id取得元が異なる
- スケジュールタスクやSQL Agent Jobで定期実行を推奨

---

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

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

### 推奨読解順序

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

保存されるデータ構造とDMVクエリを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 172-184行目: SQL 2008-2010用クエリ |
| 1-2 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 186-200行目: SQL 2012+用クエリ |

**読解のコツ**: SQL Serverバージョンによってsessionからdatabase_idを取得できるかが異なります。2012以降はsession.database_idも使用可能です。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 94-108行目: パラメータ定義 |

**主要処理フロー**:
1. **96-99行目**: SqlInstance、SqlCredential、Database、Table
2. **100-103行目**: SqlCms、ServersFromFile
3. **104-107行目**: InputObject

#### Step 3: サーバーリストの取得

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 111-114行目: パラメータ検証 |
| 3-2 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 129-144行目: CMS/ファイルからの取得 |

**主要処理フロー**:
- **111-114行目**: SqlCms/ServersFromFile/InputObjectのいずれかが必要
- **129-135行目**: SqlCms指定時はGet-DbaRegServerで取得
- **137-144行目**: ServersFromFile指定時はGet-Contentで読み込み

#### Step 4: DMVクエリとデータ保存

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 164-169行目: sysadminチェック |
| 4-2 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 171-200行目: バージョン別SQLクエリ |
| 4-3 | Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | 204-208行目: フィルタリングとデータ保存 |

**主要処理フロー**:
- **166-169行目**: Test-SqlSaでsysadmin確認、なければ警告してスキップ
- **171行目**: versionMajor <= 10（SQL 2008-2010）かチェック
- **204行目**: ローカルサーバー接続を除外
- **205行目**: システムDBと除外プログラムを除外
- **208行目**: ConvertTo-DbaDataTable + Write-DbaDbTableDataで保存

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

```
Watch-DbaDbLogin
    │
    ├─ Connect-DbaInstance (保存先)
    │      └─ 監視データ保存先への接続
    │
    ├─ Get-DbaRegServer (SqlCms時)
    │      └─ CMSから登録サーバー取得
    │
    ├─ Get-Content (ServersFromFile時)
    │      └─ ファイルからサーバー一覧取得
    │
    ├─ Connect-DbaInstance (各対象サーバー)
    │      └─ MinimumVersion 9
    │
    ├─ Test-SqlSa
    │      └─ sysadmin権限チェック
    │
    ├─ $instance.Query()
    │      └─ DMVクエリ実行
    │
    ├─ ConvertTo-DbaDataTable
    │      └─ 結果をDataTableに変換
    │
    └─ Write-DbaDbTableData
           └─ テーブルへの書き込み
```

### データフロー図

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

SqlCms ────────────────▶ Get-DbaRegServer ─────────────▶ $servers
ServersFromFile ───────▶ Get-Content ──────────────────▶ $servers
InputObject ───────────▶ ─────────────────────────────▶ $InputObject
                              │
                         Connect-DbaInstance ──────────▶ 各サーバー接続
                              │
                         DMVクエリ実行 ────────────────▶ $procs
                              │
                         フィルタリング ───────────────▶ 外部クライアント接続
                              │
SqlInstance/Database ──▶ Write-DbaDbTableData ────────▶ テーブル保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Watch-DbaDbLogin.ps1 | `public/Watch-DbaDbLogin.ps1` | ソース | メイン処理 |
| Get-DbaRegServer.ps1 | `public/Get-DbaRegServer.ps1` | ソース | CMS登録サーバー取得 |
| Write-DbaDbTableData.ps1 | `public/Write-DbaDbTableData.ps1` | ソース | テーブルデータ書き込み |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
