# 画面設計書 230-孤立ファイル検索

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける孤立ファイル検索機能の設計仕様を定義する。SQL Serverインスタンスにアタッチされていないデータベースファイル（.mdf、.ldf、.ndf）を検出し、ディスクスペースのクリーンアップや管理を支援する機能を提供するCLIインターフェースである。

### 本画面の処理概要

本機能は、xp_dirtreeで取得したファイルシステム上のファイルと、sys.master_filesで管理されているアタッチ済みファイルを比較し、孤立ファイル（アタッチされていないが存在するデータベースファイル）を特定する。デフォルトでは、データディレクトリ、ログディレクトリ、システムパス、および現在使用中のデータベースファイルが存在するディレクトリを検索する。

**業務上の目的・背景**：データベースの削除、デタッチ、リストア失敗などの後、孤立したデータベースファイルがディスク上に残ることがある。これらのファイルはディスクスペースを消費し続けるが、SQL Serverの管理ツールでは検出が困難である。本機能は、孤立ファイルを効率的に特定し、ストレージのクリーンアップを支援する。

**画面へのアクセス方法**：PowerShellコンソールから以下のコマンドを実行することでアクセスする。
- `Find-DbaOrphanedFile` - 孤立ファイルの検索

**主要な操作・処理内容**：
1. SQL Serverが使用中のファイル一覧の取得
2. ファイルシステム上のデータベースファイルの列挙
3. 孤立ファイルの特定（差分検出）
4. ローカルパス/UNCパスでの結果出力
5. 追加パス/追加ファイルタイプの検索

**画面遷移**：本機能はCLIコマンドであり、画面遷移は存在しない。ストレージ監査やクリーンアップスクリプトで使用される。

**権限による表示制御**：sysadmin権限が必要。SQL Server 2000以上が対象。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Find-DbaOrphanedFile | 主機能 | 孤立ファイルの検索 |
| - | Get-DbaFile | 関連機能 | xp_dirtreeによるファイル列挙（類似機能） |
| - | Connect-DbaInstance | 関連機能 | SQL Serverインスタンスへの接続確立 |
| - | Remove-Item | 関連機能 | 検出後のファイル削除（ユーザー操作） |

## 画面種別

CLIコマンド（PowerShell関数）

## URL/ルーティング

PowerShellコマンドレット：
- `Find-DbaOrphanedFile`

## 入出力項目

### Find-DbaOrphanedFile パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | No | SQL Server認証用資格情報 |
| Path | string[] | No | 追加検索ディレクトリ |
| FileType | string[] | No | 追加ファイル拡張子（ドットなし） |
| LocalOnly | switch | No | ローカルパスのみ出力 |
| RemoteOnly | switch | No | UNCパスのみ出力 |
| Recurse | switch | No | サブディレクトリも検索 |
| EnableException | switch | No | 例外処理モードの切り替え |

### デフォルト検索対象

| ファイルタイプ | 説明 |
|--------------|------|
| mdf | プライマリデータファイル |
| ldf | ログファイル |
| ndf | セカンダリデータファイル |

### 除外対象システムファイル

| ファイル名 | 説明 |
|----------|------|
| distmdl.ldf, distmdl.mdf | 配布データベーステンプレート |
| mssqlsystemresource.ldf, mssqlsystemresource.mdf | システムリソースデータベース |
| model_msdbdata.mdf, model_msdblog.ldf | モデルMSDBデータ/ログ |
| model_replicatedmaster.mdf, model_replicatedmaster.ldf | レプリケートマスターモデル |

## 表示項目

### 通常出力（デフォルト）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全インスタンス名 |
| Filename | string | ローカルファイルパス |
| RemoteFilename | string | UNCパス |

### LocalOnly出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | string | ローカルファイルパス |

### RemoteOnly出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | string | UNCパス |

## イベント仕様

### 1-ファイル情報収集処理

SQL Serverが使用中のファイルを収集する処理：

1. Connect-DbaInstanceでSQL Serverに接続
2. Get-SqlFileStructure関数でsys.master_files（またはsysaltfiles）からファイル一覧を取得
3. SQL Server 2005未満の場合はフルテキストカタログも収集
4. 各ファイルの親ディレクトリを収集

### 2-検索パス構築処理

検索対象ディレクトリを構築する処理：

1. sys.master_filesから取得したファイルの親ディレクトリを追加
2. $server.RootDirectory\DATAを追加
3. デフォルトデータパス、ログパスを追加
4. MasterDBPath、MasterDBLogPathを追加
5. ユーザー指定のPathパラメータを追加
6. 重複を排除してソート

### 3-ファイル列挙処理

xp_dirtreeでファイルシステムを検索する処理：

1. Get-SQLDirTreeQuery関数でSQLクエリを構築
2. 一時テーブル#enumを作成
3. 各パスに対してxp_dirtreeを実行
4. SQL Server 2005以上の場合：CTEでフルパスを構築
5. SQL Server 2000の場合：単純なSELECT
6. システムファイル、特殊ディレクトリを除外
7. 指定拡張子でフィルタリング

### 4-孤立ファイル特定処理

差分検出で孤立ファイルを特定する処理：

1. dirtreefilesの各ファイルパスを正規化（Format-Path関数）
2. sqlfilesの各ファイルパスを正規化
3. dirtreefilesにあってsqlfilesにないファイルを抽出
4. システムファイルを除外
5. 結果をPSCustomObject（または文字列）で出力

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Find-DbaOrphanedFile | tempdb（一時テーブル） | CREATE/INSERT/SELECT | ファイル情報の一時格納 |
| Find-DbaOrphanedFile | sys.master_files | SELECT | アタッチ済みファイル情報取得 |
| Find-DbaOrphanedFile | (なし) | EXEC | xp_dirtree実行 |

### テーブル別更新項目詳細

本機能は参照のみであり、永続的なデータベース更新は行わない。

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 発生条件 |
|------|-------------|---------------|---------|
| Error | - | Failure | 接続失敗時 |
| Debug | - | Adding paths | パス追加処理時 |
| Debug | - | (SQLクエリ内容) | クエリ詳細表示時 |
| Verbose | - | No orphaned files found | 孤立ファイルなし時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 接続エラー | Stop-FunctionでConnectionErrorカテゴリ、Continue |
| クエリ実行エラー | エラー内容を伝播 |

## 備考

- sysadmin権限が必要
- SQL Server 2000以上をサポート（sysaltfilesとsys.master_filesの分岐処理）
- SQL Server 2005以上ではCTEでフルパス構築
- Recurseスイッチでサブディレクトリも検索可能
- 特殊ディレクトリ（xtp, $FSLOG, $HKv2, filestream.hdr）は除外
- システムファイル（distmdl等）は除外
- パス内の特殊文字は正規化（アンダースコアに置換）
- Linux/macOSでのパス区切り文字変換をサポート
- LocalOnlyとRemoteOnlyは排他的パラメータセット

---

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

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

### 推奨読解順序

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

出力されるPSCustomObjectの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Find-DbaOrphanedFile.ps1 | `public/Find-DbaOrphanedFile.ps1` | 402-421行目の出力オブジェクト構造 |

**読解のコツ**: LocalOnly/RemoteOnlyスイッチにより出力形式が変わる。

#### Step 2: SQLファイル構造取得を理解する

sys.master_filesからの情報取得を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Find-DbaOrphanedFile.ps1 | `public/Find-DbaOrphanedFile.ps1` | 278-310行目のGet-SqlFileStructure関数 |

**主要処理フロー**:
1. **286-289行目**: SQL Server 2000用クエリ（sysaltfiles）と2005以上用クエリ（sys.master_files）の分岐
2. **297-306行目**: SQL Server 2008未満のフルテキストカタログ対応

#### Step 3: xp_dirtreeクエリ構築を理解する

動的SQLクエリの構築ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Find-DbaOrphanedFile.ps1 | `public/Find-DbaOrphanedFile.ps1` | 129-276行目のGet-SQLDirTreeQuery関数 |

**主要処理フロー**:
- **132-142行目**: #enum一時テーブル作成
- **144-155行目**: xp_dirtree実行とparent更新
- **157-251行目**: SQL Server 2005以上用CTE（フルパス構築）
- **252-264行目**: SQL Server 2000用単純SELECT
- **266行目**: Recurseフラグによる深度設定（0=無制限、1=直下のみ）

#### Step 4: 孤立ファイル特定を理解する

差分検出ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Find-DbaOrphanedFile.ps1 | `public/Find-DbaOrphanedFile.ps1` | 369-424行目のprocess後半 |

**主要処理フロー**:
- **372-374行目**: sqlfilesを正規化してvalidリストを構築
- **378-385行目**: dirtreefilesの拡張子でmatchingリストを構築
- **391-424行目**: matchingにあってvalidにないファイルを孤立ファイルとして出力

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

```
Find-DbaOrphanedFile
    |
    +-- Connect-DbaInstance
    |
    +-- Get-SqlFileStructure（アタッチ済みファイル取得）
    |       +-- sys.master_files / sysaltfiles
    |       +-- sp_help_fulltext_catalogs（SQL 2008未満）
    |
    +-- Get-SqlDefaultPaths（デフォルトパス取得）
    |
    +-- Get-SQLDirTreeQuery（SQLクエリ構築）
    |       +-- xp_dirtree
    |       +-- CTE（SQL 2005以上）
    |
    +-- ExecuteWithResults
    |
    +-- Format-Path（パス正規化）
    |
    +-- Join-AdminUnc（UNCパス変換）
    |
    +-- Select-DefaultView（出力整形）
```

### データフロー図

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

SqlInstance -------> Get-SqlFileStructure -------> sqlfiles (アタッチ済み)
                     sys.master_files

Path/FileType -------> Get-SQLDirTreeQuery -------> dirtreefiles (ファイルシステム)
                       xp_dirtree

                       差分検出: dirtreefiles - sqlfiles
                               ↓
                       孤立ファイル特定
                               ↓
LocalOnly/RemoteOnly -------> 出力形式選択 -------> PSCustomObject / string
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Find-DbaOrphanedFile.ps1 | `public/Find-DbaOrphanedFile.ps1` | ソース | 孤立ファイル検索機能 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続確立（依存） |
| Get-DbaFile.ps1 | `public/Get-DbaFile.ps1` | ソース | 類似のxp_dirtree処理（参考） |
