# 機能設計書 246-Test-DbaDbOwner

## 概要

本ドキュメントは、セキュリティコンプライアンスとベストプラクティス適用のために、不正な所有権を持つデータベースを特定する機能 `Test-DbaDbOwner` の設計仕様を記載する。

### 本機能の処理概要

この機能は、各データベースの現在の所有者をターゲットログインと比較し、期待される所有者と一致しないデータベースのみを返す。デフォルトでは「sa」（または「sa」が変更された場合は名前変更されたsysadminアカウント）に対してチェックするが、任意の有効なログインを指定可能。

**業務上の目的・背景**：データベースは個別のユーザーアカウントではなく、特定のアカウント（通常はsa）によって所有されるべきという一般的なセキュリティコンプライアンス要件に対応する。所有権の不一致は、スケジュールされたジョブ、メンテナンスプラン、セキュリティポリシーに問題を引き起こす可能性がある。

**機能の利用シーン**：
- セキュリティ監査でのデータベース所有者確認
- データベース標準化の一環としての所有者統一
- トラブルシューティング（ジョブ実行エラー原因特定）
- コンプライアンスレポート作成

**主要な処理内容**：
1. 指定されたSQL Serverインスタンスからデータベース一覧を取得
2. ターゲットログインの決定（指定なしの場合はsysadminアカウント）
3. 各データベースの現在の所有者とターゲット所有者を比較
4. 所有者情報と一致状況を含むオブジェクトを出力

**関連システム・外部連携**：Get-DbaDatabase関数を使用してデータベース情報を取得。

**権限による制御**：データベースへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

バリデーション / 監査処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | ターゲットSQL Serverインスタンス | Position 0 |
| SqlCredential | PSCredential | No | 代替資格情報 | 有効なPowerShell資格情報 |
| Database | object[] | No | チェック対象データベース | - |
| ExcludeDatabase | object[] | No | 除外するデータベース | - |
| TargetLogin | string | No | 期待されるデータベース所有者ログイン | デフォルトはsa |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | No | パイプライン入力されるデータベースオブジェクト | - |
| EnableException | switch | No | 例外のスロー有効化 | - |

### 入力データソース

- PowerShellコマンドライン引数
- パイプライン入力（InputObject / SqlInstance）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名（computer\instance） |
| Database | string | チェック対象のデータベース名 |
| DBState | string | データベースの現在の状態（Online、Offline、Restoringなど） |
| CurrentOwner | string | データベースの現在の所有者ログイン名 |
| TargetOwner | string | 期待されるデータベース所有者ログイン名（コンプライアンスターゲット） |
| OwnerMatch | bool | 現在の所有者がターゲット所有者と一致するか |

### 出力先

- PowerShellパイプライン出力（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. 入力の検証
   └─ SqlInstanceまたはInputObjectの指定確認
2. データベース一覧の取得
   └─ SqlInstance指定時：Get-DbaDatabase経由で取得
   └─ InputObject指定時：パイプライン入力を使用
3. 各データベースに対してループ処理
   └─ ターゲットログインの決定（未指定時はID=1のログイン）
   └─ ターゲットログインの存在確認
   └─ 所有者比較と結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject or SqlInstance?}
    B -->|なし| C[Stop-Function]
    B -->|SqlInstance| D[Get-DbaDatabase]
    B -->|InputObject| E[パイプライン入力使用]
    D --> F{各DBをループ}
    E --> F
    F --> G{TargetLogin指定?}
    G -->|No| H[ID=1のログインを取得]
    G -->|Yes| I[指定されたTargetLogin使用]
    H --> J[TargetLogin存在確認]
    I --> J
    J --> K[所有者比較]
    K --> L[結果出力]
    L --> F
    F -->|完了| M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-246-1 | デフォルトターゲット | TargetLogin未指定時はID=1のログイン（通常sa）を使用 | TargetLoginパラメータなしの場合 |
| BR-246-2 | 所有者一致判定 | データベース所有者がターゲットログインと一致するか判定 | 各データベースに対して |
| BR-246-3 | saリネーム検出 | saアカウントがリネームされた場合も正しく検出 | 常時 |

### 計算ロジック

ターゲットログイン決定：
```powershell
if (Test-Bound -ParameterName TargetLogin -Not) {
    $TargetLogin = ($server.logins | Where-Object { $_.id -eq 1 }).Name
}
```

所有者一致判定：
```powershell
OwnerMatch = ($db.owner -eq $TargetLogin)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| データベース取得 | SMO Database | SELECT | データベースリストとプロパティを取得 |
| ログイン取得 | SMO Logins | SELECT | サーバーログイン一覧を取得 |

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

#### SMOオブジェクト

| 操作 | 項目（プロパティ名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | $db.Owner | - | データベースの現在の所有者 |
| SELECT | $db.Status | - | データベースの状態 |
| SELECT | $server.logins | id -eq 1 | sysadminログイン |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ParameterError | パラメータエラー | SqlInstanceもInputObjectも指定なし | Stop-Functionで処理終了 |
| LoginNotFound | 警告 | TargetLoginがインスタンスに存在しない | Write-Messageで警告出力 |

### リトライ仕様

リトライ処理なし。

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- Get-DbaDatabase経由でのデータベース取得
- データベース数に応じて処理時間が増加

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

- SQL Server認証、Windows認証、Active Directory認証をサポート
- データベースへのアクセス権限が必要
- ベストプラクティス参照: http://weblogs.sqlteam.com/dang/archive/2008/01/13/Database-Owner-Troubles.aspx

## 備考

- 返される結果はすべてOwnerMatch = falseのデータベースのみ（不一致検出用）
- パイプライン入力でGet-DbaDatabase -OnlyAccessibleと連携可能

---

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

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

### 推奨読解順序

#### Step 1: コマンド構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Test-DbaDbOwner.ps1 | `public/Test-DbaDbOwner.ps1` | パラメータ定義、コメントベースヘルプ |

**読解のコツ**: パイプライン入力の2つの方法（SqlInstance経由とInputObject直接）に注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Test-DbaDbOwner.ps1 | `public/Test-DbaDbOwner.ps1` | processブロックでの処理フロー |

**主要処理フロー**:
1. **100-102行目**: 入力パラメータの検証
2. **104-106行目**: SqlInstance指定時のデータベース取得
3. **109-117行目**: ターゲットログインの決定
4. **119-122行目**: TargetLoginの存在確認
5. **124-135行目**: 所有者比較と結果出力

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

```
Test-DbaDbOwner
    │
    ├─ Get-DbaDatabase
    │      └─ データベース一覧取得
    │
    ├─ Test-Bound
    │      └─ パラメータバインド確認
    │
    ├─ $server.logins
    │      └─ sysadminログイン取得
    │
    └─ Select-DefaultView
           └─ 出力プロパティフィルタリング
```

### データフロー図

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

SqlInstance    ───▶ Get-DbaDatabase ───▶ $InputObject
      or
InputObject    ───▶ 直接使用 ───▶ $InputObject
                           │
                           ▼
                    ターゲットログイン決定 ───▶ $TargetLogin
                           │
                           ▼
                    所有者比較 ───▶ PSCustomObject
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Test-DbaDbOwner.ps1 | `public/Test-DbaDbOwner.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース一覧取得 |
| Set-DbaDbOwner.ps1 | `public/Set-DbaDbOwner.ps1` | ソース | 所有者変更（関連） |
