# 画面設計書 111-管理者リセット

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるSQL Server管理者リセット機能（Reset-DbaAdmin）の設計仕様を記述する。

### 本画面の処理概要

本機能は、SQL Serverインスタンスへの管理者アクセスを回復するための緊急リカバリツールである。パスワード紛失、アカウント無効化、認証問題などにより管理者アクセスができなくなった場合に使用する。

**業務上の目的・背景**：SQL Serverの運用において、saアカウントのパスワード紛失、管理者アカウントの無効化・ロックアウト、または認証設定の問題により管理者アクセスができなくなるケースがある。このような緊急事態において、サーバーの再インストールを回避し、迅速にアクセスを回復するために本機能が必要となる。SQL Server 2005以降のスタンドアロンおよびクラスター構成に対応する。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから`Reset-DbaAdmin`コマンドレットを実行する。対象のSQL Serverインスタンスが稼働しているサーバーへの管理者権限（Windows管理者権限）が必要。リモートサーバーの場合はWinRM（PowerShellリモーティング）が有効である必要がある。

**主要な操作・処理内容**：
1. SQL Serverサービス（またはクラスターリソース）を停止
2. シングルユーザーモード（/mReset-DbaAdmin）でSQL Serverを再起動
3. 指定されたログインが存在しない場合は作成
4. SQLログインの場合、混合モード認証を有効化
5. ログインを有効化・アンロック
6. ログインにsysadminロールを付与
7. SQL Serverを通常モードで再起動

**画面遷移**：本機能はコマンドラインインターフェースであり、画面遷移は存在しない。処理完了後、Get-DbaLoginを内部的に呼び出してログイン情報を出力する。

**権限による表示制御**：本機能の実行には、SQL ServerインスタンスをホストするサーバーへのWindows管理者権限が必要。SQL Server内の権限は不要（アクセスできない状態を回復するため）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 210 | Reset-DbaAdmin | 主機能 | SQL Server管理者のリセット |

## 画面種別

CLIコマンド（緊急リカバリツール）

## URL/ルーティング

```powershell
Reset-DbaAdmin -SqlInstance <インスタンス名> [-Login <ログイン名>] [-SqlCredential <資格情報>] [-SecurePassword <パスワード>] [-Force] [-EnableException]
```

## 入出力項目

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|---|------|-------------|------|
| SqlInstance | DbaInstanceParameter | Yes | - | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | No | - | Login/SecurePasswordの代わりに資格情報オブジェクトを指定 |
| Login | string | No | "sa" | リセット/作成するログインアカウント |
| SecurePassword | SecureString | No | - | SQLログインのパスワード（対話的に入力も可） |
| Force | switch | No | $false | 確認プロンプトをスキップ |
| EnableException | switch | No | $false | 例外をスローする |
| WhatIf | switch | No | $false | 実行内容をシミュレート |
| Confirm | switch | No | $true | 確認プロンプトを表示 |

## 表示項目

| プロパティ名 | 型 | 説明 |
|-------------|---|------|
| ComputerName | string | SQL Serverをホストするコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| Name | string | ログイン名 |
| LoginType | string | ログインタイプ（SqlLogin/WindowsUser） |
| CreateDate | datetime | ログイン作成日時 |
| LastLogin | datetime | 最終ログイン日時 |
| IsDisabled | bool | ログイン無効フラグ |
| IsLocked | bool | ログインロックフラグ |
| IsSysAdmin | bool | sysadmin権限フラグ |

## イベント仕様

### 1-Reset-DbaAdmin実行

1. インスタンス情報（コンピュータ名、IPアドレス）を解決
2. リモートサーバーの場合、PSSessionを確立
3. Windowsログイン（\を含む）の場合、アカウントの有効性を検証
4. SQLログインの場合、パスワード入力を要求
5. SQL Serverサービス情報を取得
6. クラスター環境かどうかを確認
7. SQL Serverサービスを停止
8. シングルユーザーモードでSQL Serverを起動
9. 接続テストを実行
10. ログインを作成（存在しない場合）
11. SQLログインの場合、混合モード認証を有効化
12. ログインを有効化・アンロック
13. sysadminロールに追加
14. SQL Serverを通常モードで再起動
15. ログイン情報を取得して出力

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ログイン作成 | sys.server_principals | INSERT | 新規ログインの作成 |
| 混合モード有効化 | レジストリ | UPDATE | LoginModeを2に設定 |
| パスワード変更 | sys.sql_logins | UPDATE | パスワード更新・アンロック |
| ログイン有効化 | sys.server_principals | UPDATE | is_disabledを0に設定 |
| sysadmin付与 | sys.server_role_members | INSERT | sysadminロールへの追加 |

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

#### sys.server_principals

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | 指定されたログイン名 | ログインが存在しない場合 |
| UPDATE | is_disabled | 0 | ALTER LOGIN ... ENABLE |

#### レジストリ（xp_instance_regwrite）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | LoginMode | REG_DWORD 2 | 混合モード認証を有効化 |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 発生条件 |
|---------------|---------------|---------|
| エラー | Can't access {hostname} using PSSession | リモートサーバーへのPSSession確立失敗 |
| 警告 | Cannot resolve Windows User or Group {Login} | Windowsアカウントの解決失敗 |
| 警告 | Couldn't create Windows login | Windowsログイン作成失敗 |
| 警告 | Couldn't create SQL login | SQLログイン作成失敗 |
| 警告 | Couldn't set to Mixed Mode | 混合モード設定失敗 |
| 警告 | Couldn't unlock account | アカウントアンロック失敗 |
| 警告 | Couldn't enable login | ログイン有効化失敗 |
| 警告 | Couldn't add to sysadmin role | sysadmin追加失敗 |
| エラー | Cannot connect to WMI on {hostname} | WMI接続失敗またはサービス不存在 |
| エラー | Couldn't find SQL Server instance | インスタンスが見つからない |
| エラー | Could not stop the SQL Service | サービス停止失敗 |
| エラー | Restart failure | シングルユーザーモード起動失敗 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| PSSession確立失敗 | Stop-Functionでエラー出力、処理スキップ |
| サービス停止失敗 | サービス再起動を試行、Stop-Functionでエラー出力 |
| シングルユーザーモード起動失敗 | サービス再起動を試行、Stop-Functionでエラー出力 |
| SQL接続失敗 | 3秒待機後リトライ、失敗時はサービス再起動 |
| 各SQL操作失敗 | 警告メッセージを出力、処理続行 |
| 最終認証失敗 | Stop-Functionでメッセージ出力（ログインは動作するはず） |

## 備考

- 本機能は緊急リカバリ用途であり、通常の運用では使用しない
- SQL Server 2005以降に対応（sys.dm_db_persisted_sku_features DMVを使用）
- クラスター環境では、リソースグループ全体をオフライン/オンラインにする
- シングルユーザーモードでは/mReset-DbaAdminパラメータを使用し、このスクリプトのみが接続可能
- サービス停止・再起動を伴うため、HighインパクトのConfirmImpactが設定されている
- Microsoft.Data.SqlClientを使用してSQL Serverに接続

---

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

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

### 推奨読解順序

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

Reset-DbaAdminは出力としてDataplat.Dbatools.Loginオブジェクトを返す。これはGet-DbaLoginから取得される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | 出力型定義（行59-76）を確認 |

**読解のコツ**: PowerShellの[OutputType()]属性と.OUTPUTSドキュメントで出力オブジェクトの構造を確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | param()ブロック（行112-122）でパラメータを確認 |

**主要処理フロー**:
1. **行124-179**: begin ブロック - ユーティリティ関数定義とパラメータ処理
2. **行180-452**: process ブロック - 主要な処理ロジック
3. **行454-456**: end ブロック - 完了メッセージ

#### Step 3: サービス操作ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | 行257-312: サービス停止処理 |
| 3-2 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | 行314-343: シングルユーザーモード起動 |

#### Step 4: SQL操作ロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | 行141-171: Invoke-ResetSqlCmd内部関数 |
| 4-2 | Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | 行366-419: ログイン作成・権限付与 |

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

```
Reset-DbaAdmin
    |
    +-- ConvertTo-PlainText（内部関数）
    |       └─ SecureStringからプレーンテキストへ変換
    |
    +-- Invoke-ResetSqlCmd（内部関数）
    |       └─ Microsoft.Data.SqlClient経由でSQL実行
    |
    +-- Resolve-DbaNetworkName
    |       └─ コンピュータ名解決
    |
    +-- New-PSSession
    |       └─ リモートセッション確立
    |
    +-- Get-Service / Stop-Service / Start-Service
    |       └─ Windowsサービス操作
    |
    +-- Get-DbaCmObject
    |       └─ クラスターリソース情報取得
    |
    └── Get-DbaLogin
            └─ 最終的なログイン情報取得・出力
```

### データフロー図

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

SqlInstance ──────────────> サービス停止 ──────────────────────>
Login ─────────────────────> シングルユーザーモード起動 ───────>
SecurePassword ────────────> ログイン作成/更新 ────────────────>
                            sysadmin付与 ─────────────────────>
                            サービス再起動 ───────────────────>
                            ログイン情報取得 ─────────────────> Dataplat.Dbatools.Login
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Reset-DbaAdmin.ps1 | `public/Reset-DbaAdmin.ps1` | ソース | メイン処理 |
| Get-DbaLogin.ps1 | `public/Get-DbaLogin.ps1` | ソース | ログイン情報取得 |
| Resolve-DbaNetworkName.ps1 | `public/Resolve-DbaNetworkName.ps1` | ソース | ネットワーク名解決 |
| Get-DbaCmObject.ps1 | `public/Get-DbaCmObject.ps1` | ソース | WMI/CIMオブジェクト取得 |
