# 機能設計書 341-Remove-DbaSpn

## 概要

本ドキュメントは、dbatools PowerShellモジュールのRemove-DbaSpn関数の機能設計書である。この関数はActive DirectoryからService Principal Name (SPN) を削除し、関連するKerberos委任設定もクリーンアップする。

### 本機能の処理概要

Remove-DbaSpn関数は、SQL ServerサービスアカウントからSPNを削除し、関連するKerberos委任エントリも自動的にクリーンアップする機能を提供する。

**業務上の目的・背景**：SQL Serverインスタンスの廃止、サービスアカウントの変更、またはKerberos認証の問題をトラブルシューティングする際に、重複または不正なSPNを削除する必要がある。不正なSPNが存在すると、Kerberos認証が失敗し、クライアントがSQL Serverに接続できなくなる可能性がある。この関数は、SPNの削除と関連する委任設定のクリーンアップを自動化することで、Active Directory環境を適切に維持することを支援する。

**機能の利用シーン**：SQL Serverインスタンスを廃止する場合、サービスアカウントを別のアカウントに変更する場合、重複SPNによるKerberos認証失敗を解決する場合、またはセキュリティ監査の一環としてSPN設定をクリーンアップする場合に使用される。

**主要な処理内容**：
1. 指定されたサービスアカウントをActive Directoryで検索する
2. servicePrincipalNameプロパティからSPNを削除する
3. msDS-AllowedToDelegateTo属性から対応する委任エントリを削除する
4. 各操作の結果を構造化されたオブジェクトとして出力する

**関連システム・外部連携**：Active Directory (System.DirectoryServices.AccountManagement を使用)、Get-DbaADObject内部関数によるADオブジェクト検索。

**権限による制御**：Active Directoryへの書き込みアクセス権が必要。指定されたCredentialパラメータを使用して認証を行う。

## 関連画面

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

## 機能種別

データ操作（Active Directoryオブジェクトの更新）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SPN | string | Yes | 削除するService Principal Name | MSSQLSvc/servername:port形式 |
| ServiceAccount | string | Yes | SPNを所有するActive Directoryアカウント | domain\username形式またはCOMPUTERNAME$形式 |
| Credential | PSCredential | No | Active Directory接続用の資格情報 | 有効なPSCredentialオブジェクト |
| EnableException | switch | No | 例外処理の動作を制御 | true/false |
| Confirm | switch | No | 変更前の確認 | true/false |
| WhatIf | switch | No | 実行されることをシミュレート | true/false |

### 入力データソース

- パイプライン入力: Test-DbaSpnの出力を直接パイプライン経由で受け取り可能
- ValueFromPipelineByPropertyName: SPN, ServiceAccount, Credentialパラメータは名前付きプロパティから自動的にバインドされる

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | string | 処理されたService Principal Name |
| ServiceAccount | string | SPNを削除したActive Directoryアカウント |
| Property | string | 変更されたAD属性 (servicePrincipalName または msDS-AllowedToDelegateTo) |
| IsSet | boolean | SPNまたは委任がまだ設定されているかどうか |
| Notes | string | 操作のステータスメッセージ |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. サービスアカウントの検索
   └─ Get-DbaADObjectを使用してActive Directoryでアカウントを検索
   └─ アカウント名が$で終わる場合はコンピュータアカウントとして検索

2. SPNの削除処理
   └─ servicePrincipalName属性からSPNを検索
   └─ SPNが見つからない場合は警告を出力
   └─ ShouldProcessで確認後、SPNを削除
   └─ CommitChanges()でADへの変更を確定

3. 委任エントリの削除処理
   └─ SPN削除が成功した場合のみ実行
   └─ msDS-AllowedToDelegateTo属性から対応エントリを削除
   └─ CommitChanges()でADへの変更を確定

4. 結果の出力
   └─ 各操作について結果オブジェクトを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Get-DbaADObjectでサービスアカウント検索]
    B --> C{アカウント発見?}
    C -->|No| D[エラー: アカウント未発見]
    C -->|Yes| E[servicePrincipalNameからSPN検索]
    E --> F{SPN存在?}
    F -->|No| G[警告: SPN not found]
    F -->|Yes| H{ShouldProcess確認}
    H -->|WhatIf| I[シミュレーション出力]
    H -->|実行| J[SPNを削除]
    J --> K[結果オブジェクト出力]
    G --> K
    K --> L{委任削除実行?}
    L -->|No| M[終了]
    L -->|Yes| N[msDS-AllowedToDelegateTo確認]
    N --> O{委任存在?}
    O -->|No| P[委任未発見を出力]
    O -->|Yes| Q[委任を削除]
    Q --> R[結果オブジェクト出力]
    P --> R
    R --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | SPN形式 | SPNはMSSQLSvc/hostname:port形式で指定する必要がある | 常に適用 |
| BR-002 | サービスアカウント形式 | domain\usernameまたはCOMPUTERNAME$形式で指定 | 常に適用 |
| BR-003 | 委任クリーンアップ | SPN削除成功時のみ委任エントリを削除 | SPN削除成功時 |
| BR-004 | コンピュータアカウント識別 | $で終わるアカウント名はコンピュータアカウントとして検索 | アカウント名の末尾が$ |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし（Active Directory操作のみ） |

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

該当なし（Active Directoryの属性操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | AD検索失敗 | ドメイン解決不可またはアクセス権不足 | 資格情報とドメイン接続を確認 |
| - | アカウント未発見 | 指定されたサービスアカウントがADに存在しない | アカウント名を確認 |
| - | プロパティアクセス不可 | サービスアカウントのプロパティ検査権限がない | 適切な権限を持つ資格情報を使用 |
| - | SPN削除失敗 | ADへの書き込み権限がない | AD管理者権限を持つアカウントで実行 |
| - | 委任削除失敗 | msDS-AllowedToDelegateTo属性への書き込み権限がない | AD管理者権限を持つアカウントで実行 |

### リトライ仕様

明示的なリトライ機能はなし。エラー発生時はStop-Functionで処理を停止し、EnableExceptionパラメータに応じて警告または例外をスローする。

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

Active Directoryの各操作（SPN削除、委任削除）は個別にCommitChanges()でコミットされる。SPN削除が失敗した場合、委任削除は実行されない。

## パフォーマンス要件

AD検索とプロパティ更新は通常数秒以内で完了。大規模なAD環境ではドメインコントローラーへのネットワーク遅延に依存。

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

- Active Directoryへの書き込みアクセス権限が必要
- 資格情報はPSCredentialオブジェクトとして安全に渡される
- WhatIfパラメータで事前に影響範囲を確認可能
- SupportsShouldProcess属性による確認プロンプト対応

## 備考

- Test-DbaSpnからのパイプライン入力をサポート
- 1回の呼び出しで最大2つのオブジェクト（SPN削除結果と委任削除結果）を出力
- 委任が元々設定されていない場合も結果オブジェクトを出力（IsSet = false, Notes = "Delegation not found"）

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Remove-DbaSpn.ps1 | `public/Remove-DbaSpn.ps1` | 149-155行目と163-169行目、184-190行目の出力オブジェクト構造を確認 |

**読解のコツ**: PowerShellのPSCustomObjectはハッシュテーブル構文で定義される。@{key=value}形式で出力プロパティが定義されている。

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

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

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

**主要処理フロー**:
1. **89-100行目**: param()ブロックでパラメータ定義
2. **91-96行目**: ValueFromPipelineByPropertyNameでパイプライン入力をサポート
3. **99行目**: EnableExceptionスイッチで例外処理動作を制御

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

processブロック内の主要処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Remove-DbaSpn.ps1 | `public/Remove-DbaSpn.ps1` | 102-195行目のprocess{}ブロック |

**主要処理フロー**:
- **103-107行目**: アカウントタイプの判定（User/Computer）
- **108-112行目**: Get-DbaADObjectでAD検索
- **113-121行目**: 検索結果のチェックとエラーハンドリング
- **125-156行目**: SPN削除処理
- **158-193行目**: 委任エントリ削除処理

#### Step 4: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaADObject.ps1 | `private/functions/Get-DbaADObject.ps1` | AD検索のロジックとIdentityType処理 |

**主要処理フロー**:
- **81-114行目**: パラメータ定義とsearchClass決定
- **116-131行目**: 内部関数Get-DbaADObjectInternalでの実際のAD検索
- **133-188行目**: ドメイン解析とオブジェクト検索

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

```
Remove-DbaSpn
    │
    ├─ Get-DbaADObject (private/functions/Get-DbaADObject.ps1)
    │      └─ System.DirectoryServices.AccountManagement.Principal.FindByIdentity
    │
    ├─ $Result.GetUnderlyingObject()
    │      └─ DirectoryEntry オブジェクト取得
    │
    ├─ $adentry.Properties['servicePrincipalName'].Remove()
    │      └─ SPN削除
    │
    ├─ $adentry.Properties['msDS-AllowedToDelegateTo'].Remove()
    │      └─ 委任削除
    │
    └─ $adentry.CommitChanges()
           └─ ADへの変更確定
```

### データフロー図

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

SPN パラメータ ───┬──▶ Get-DbaADObject() ──▶ ADアカウント検索
                  │         │
ServiceAccount ───┘         ▼
                     GetUnderlyingObject() ──▶ DirectoryEntry取得
                            │
                            ▼
                     servicePrincipalName ──▶ PSCustomObject
                     削除処理                  (SPN削除結果)
                            │
                            ▼
                     msDS-AllowedToDelegateTo ──▶ PSCustomObject
                     削除処理                     (委任削除結果)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Remove-DbaSpn.ps1 | `public/Remove-DbaSpn.ps1` | ソース | メイン関数 |
| Get-DbaADObject.ps1 | `private/functions/Get-DbaADObject.ps1` | ソース | ADオブジェクト検索の内部関数 |
| Test-DbaSpn.ps1 | `public/Test-DbaSpn.ps1` | ソース | パイプライン入力元として使用可能 |
| Set-DbaSpn.ps1 | `public/Set-DbaSpn.ps1` | ソース | 対となるSPN追加関数 |
