# 機能設計書 698-Update-DbaServiceAccount

## 概要

本ドキュメントは、SQL Server EngineおよびAgentサービスのサービスアカウントまたはパスワードを変更するdbatools PowerShellコマンド `Update-DbaServiceAccount` の機能設計書です。

### 本機能の処理概要

`Update-DbaServiceAccount` は、SQL Server EngineおよびAgentサービスのサービスアカウント資格情報を更新するか、パスワードのみを変更する機能です。アカウント変更時には、変更を適用するために影響を受けるサービスが自動的に再起動されます。パスワードのみの更新では、即座に変更を有効にしたい場合を除き、再起動は不要です。

**業務上の目的・背景**：SQL Serverサービスアカウントの管理は、セキュリティとコンプライアンスの観点から重要です。パスワードのローテーション、ドメインアカウントへの変更、サービスアカウントの標準化などの運用タスクを効率化します。また、ネットワーク証明書を使用しているサービスでは、アカウント変更時に証明書の削除と再適用を自動的に処理します。

**機能の利用シーン**：
- セキュリティコンプライアンスに基づくパスワードローテーション
- サービスアカウントのドメインアカウントへの変更
- ローカルシステムアカウントへの変更
- サービスアカウントの標準化

**主要な処理内容**：
1. パラメータ検証とサービスアカウント情報の準備
2. 対象サービスの取得（ServiceNameまたはInputObject）
3. Engineサービスの場合はSQL Agent状態を保存
4. ネットワーク証明書の一時的な削除（Engineサービスでアカウント変更時）
5. サービスアカウントまたはパスワードの変更
6. ネットワーク証明書の再適用（必要な場合）
7. SQL Agentの再起動（Engineサービスのアカウント変更後）

**関連システム・外部連携**：Windows Service Control Manager、SQL Server SMO WMI、ネットワーク証明書

**権限による制御**：対象コンピューターでのローカル管理者権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | コマンドライン | 主画面 | PowerShellコンソールからの直接実行 |

## 機能種別

サービス管理 / 構成変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | サービスアカウント変更対象のコンピューター名 | ServiceNameパラメータセット、デフォルト$env:COMPUTERNAME |
| Credential | PSCredential | No | コンピューターへの接続用資格情報 | なし |
| InputObject | object[] | Yes (InputObject) | Get-DbaServiceからのサービスオブジェクト | パイプライン入力、InputObjectパラメータセット |
| ServiceName | string[] | Yes (ServiceName) | 更新するSQL Serverサービス名 | ServiceNameパラメータセット |
| Username | string | No | DOMAIN\Usernameフォーマットのサービスアカウント名 | ServiceCredentialと排他 |
| ServiceCredential | PSCredential | No | サービスアカウントのドメインアカウントとパスワード | Usernameと排他 |
| PreviousPassword | SecureString | No | パスワード変更時の現在のパスワード | 非管理者ユーザーで必要 |
| SecurePassword | SecureString | No | 新しいパスワード | 未指定時はプロンプト表示 |
| NoRestart | switch | No | サービスの自動再起動を防止 | なし |
| EnableException | switch | No | 例外を有効にし、try/catchでのキャッチを可能にする | なし |
| WhatIf | switch | No | 実行せずに処理内容を表示 | なし |
| Confirm | switch | No | 実行前に確認プロンプトを表示 | なし |

### 入力データソース

- Get-DbaServiceから取得したサービスオブジェクト
- パイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | サービスが実行されているコンピューター名 |
| ServiceName | string | Windowsサービス名 |
| State | string | 更新後のサービス状態（Running, Stopped等） |
| StartName | string | 更新後のサービスアカウント名 |
| Status | string | 操作の結果（Successful, Failed） |
| Message | string | 詳細なステータスメッセージ |

### 出力先

PowerShellパイプライン (Microsoft.SqlServer.Management.Smo.Wmi.SqlService)

## 処理フロー

### 処理シーケンス

```
1. begin ブロック
   ├─ svcCollection初期化
   ├─ スクリプトブロック定義（アカウント変更、パスワード変更）
   ├─ パラメータ検証（Username/ServiceCredential排他チェック）
   ├─ アクションタイプ決定（Account or Password）
   └─ システムログイン名の正規化（NETWORKSERVICE, LOCALSYSTEM, LOCALSERVICE）

2. process ブロック
   ├─ ServiceNameパラメータセットの場合
   │   └─ ComputerNameとServiceNameをsvcCollectionに追加
   └─ InputObjectパラメータセットの場合
       └─ サービスオブジェクトから情報をsvcCollectionに追加

3. end ブロック
   └─ 各サービスに対してループ
      ├─ Get-DbaServiceでサービス情報取得
      ├─ パスワード入力（必要な場合）
      ├─ Engineサービスの場合はSQL Agent状態を保存
      ├─ ShouldProcess確認
      ├─ アカウント変更の場合
      │   ├─ ネットワーク証明書の削除（存在する場合）
      │   ├─ Invoke-ManagedComputerCommandでアカウント変更
      │   └─ ネットワーク証明書の再適用（存在していた場合）
      ├─ パスワード変更の場合
      │   └─ Invoke-ManagedComputerCommandでパスワード変更
      ├─ SQL Agentの再起動（Engineサービスのアカウント変更後、NoRestart未指定時）
      └─ 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[パラメータ検証]
    B --> C{Username or ServiceCredential?}
    C -->|Username| D[actionType=Account]
    C -->|ServiceCredential| D
    C -->|Neither| E[actionType=Password]
    D --> F[システムログイン正規化]
    E --> G[サービスコレクション構築]
    F --> G
    G --> H{各サービスループ}
    H --> I[Get-DbaServiceでサービス取得]
    I --> J{パスワード入力必要?}
    J -->|Yes| K[パスワードプロンプト]
    J -->|No| L{Engineサービス?}
    K --> L
    L -->|Yes| M[SQL Agent状態保存]
    L -->|No| N{ShouldProcess?}
    M --> N
    N -->|No| O[結果出力]
    N -->|Yes| P{actionType?}
    P -->|Account| Q[証明書削除チェック]
    Q --> R[アカウント変更]
    R --> S[証明書再適用チェック]
    S --> T{SQL Agent再起動?}
    P -->|Password| U[パスワード変更]
    U --> O
    T -->|Yes| V[Start-DbaService Agent]
    T -->|No| O
    V --> O
    O --> W{次のサービス?}
    W -->|Yes| H
    W -->|No| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 権限要件 | ローカル管理者権限が必要 | 常時 |
| BR-002 | パラメータ排他 | UsernameとServiceCredentialは同時に指定不可 | 常時 |
| BR-003 | システムアカウント | NETWORKSERVICE, LOCALSYSTEM, LOCALSERVICEはパスワード不要 | システムアカウント指定時 |
| BR-004 | MSAアカウント | $で終わるアカウントはパスワード不要 | MSAアカウント指定時 |
| BR-005 | NT Serviceアカウント | NT Service\で始まるアカウントはパスワード不要 | NT Serviceアカウント指定時 |
| BR-006 | 証明書処理 | Engineサービスでアカウント変更時、証明書の削除と再適用を実行 | Engineサービスのアカウント変更時 |
| BR-007 | SQL Agent再起動 | Engineサービスのアカウント変更後、実行中だったSQL Agentを再起動 | NoRestart未指定時 |
| BR-008 | PowerBIReportServer | PowerBIReportServerサービスはサポート対象外 | 常時 |

### 計算ロジック

システムログイン名の正規化:
```powershell
$trimmedUsername = (Split-Path $Username -Leaf).Trim().Replace(' ', '')
if ($trimmedUsername -in 'NETWORKSERVICE', 'LOCALSYSTEM', 'LOCALSERVICE') {
    $currentCredential = New-Object System.Management.Automation.PSCredential ($credUserName, (New-Object System.Security.SecureString))
}
```

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

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

本機能はデータベースを直接操作しませんが、SQL Serverサービスのアカウント変更によりサービスが再起動され、一時的にデータベース接続が中断されます。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | サービス操作 | サービスアカウント変更とサービス再起動 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | パラメータエラー | UsernameとServiceCredentialを同時に指定 | いずれか一方のみを指定 |
| InvalidArgument | パスワード不一致 | 確認パスワードが一致しない | 正しいパスワードを再入力 |
| N/A | サービス未検出 | 指定サービスが見つからない | サービス名を確認 |
| N/A | 接続エラー | コンピューターに接続できない | コンピューター名とネットワーク接続を確認 |
| N/A | アカウント変更失敗 | アカウント変更が失敗 | 資格情報と権限を確認 |

### リトライ仕様

明示的なリトライ機能は実装されていません。

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

サービスアカウント変更はアトミック操作ではありません。証明書の削除後にアカウント変更が失敗した場合、証明書が失われる可能性があります（警告メッセージで通知）。

## パフォーマンス要件

サービスの再起動を伴うため、操作完了までに時間がかかる場合があります。

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

- 対象コンピューターでのローカル管理者権限が必要
- パスワードはSecureStringで安全に処理
- システムアカウント（NETWORKSERVICE, LOCALSYSTEM, LOCALSERVICE）への変更をサポート
- 管理サービスアカウント (MSA) への変更をサポート
- ShouldProcess/Confirmによる実行前確認

## 備考

- SQL Server EngineおよびAgentサービスがサポート対象
- 他のサービス（Reporting Services、Analysis Services等）は古いSQL Serverバージョンで失敗する可能性
- PowerBIReportServerサービスはサポート対象外
- NoRestartを指定した場合、変更は次回サービス再起動まで有効になりません

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaService出力 | (Get-DbaService参照) | ServiceName, ServiceType, InstanceName, ComputerName, StartName などのプロパティ構造 |

**読解のコツ**: Update-DbaServiceAccountは Get-DbaService から取得したサービスオブジェクトを処理するか、ServiceNameパラメータで直接指定します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Update-DbaServiceAccount.ps1 | `public/Update-DbaServiceAccount.ps1` | メイン関数の構造、パラメータ定義 |

**主要処理フロー**:
1. **124-144行目**: パラメータ定義（2つのパラメータセット: ServiceName, InputObject）
2. **145-191行目**: begin ブロック - スクリプトブロック定義、パラメータ検証、アクションタイプ決定
3. **192-226行目**: process ブロック - サービスコレクション構築
4. **228-309行目**: end ブロック - メイン処理

**特に重要な処理**:
- **147-151行目**: アカウント変更スクリプトブロック
- **152-156行目**: パスワード変更スクリプトブロック
- **248-263行目**: ネットワーク証明書の処理
- **290-298行目**: SQL Agent再起動処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaService.ps1 | `public/Get-DbaService.ps1` | サービス情報取得 |
| 3-2 | Invoke-ManagedComputerCommand | (内部関数) | WMIを介したサービス操作 |
| 3-3 | Get-DbaNetworkConfiguration | (内部関数) | ネットワーク証明書取得 |
| 3-4 | Remove-DbaNetworkCertificate | (内部関数) | ネットワーク証明書削除 |
| 3-5 | Set-DbaNetworkCertificate | (内部関数) | ネットワーク証明書設定 |
| 3-6 | Start-DbaService.ps1 | `public/Start-DbaService.ps1` | サービス開始 |

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

```
Update-DbaServiceAccount
    │
    ├─ Resolve-DbaNetworkName (197, 214行目)
    │      └─ コンピューター名解決
    │
    ├─ Get-DbaService (230, 244, 302行目)
    │      └─ サービス情報取得
    │
    ├─ Get-DbaNetworkConfiguration (258行目)
    │      └─ ネットワーク証明書情報取得
    │
    ├─ Remove-DbaNetworkCertificate (261行目)
    │      └─ ネットワーク証明書削除
    │
    ├─ Invoke-ManagedComputerCommand (265, 273行目)
    │      └─ アカウント/パスワード変更実行
    │
    ├─ Set-DbaNetworkCertificate (269行目)
    │      └─ ネットワーク証明書再設定
    │
    └─ Start-DbaService (293行目)
           └─ SQL Agent再起動
```

### データフロー図

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

ComputerName ───▶ Resolve-DbaNetworkName ───▶ 解決済みコンピューター名
                         │
ServiceName ─────────▶ svcCollection構築
                         │
InputObject ─────────▶   │
                         ▼
Username/ServiceCredential ───▶ 認証情報準備
                         │
SecurePassword ──────▶   │
                         ▼
                  Get-DbaService ───▶ サービスオブジェクト
                         │
                         ▼
                  証明書処理（必要な場合）
                         │
                         ▼
                  Invoke-ManagedComputerCommand ───▶ アカウント/パスワード変更
                         │
                         ▼
                  SQL Agent再起動（必要な場合）
                         │
                         ▼
                  SqlService オブジェクト
                  (ComputerName, ServiceName, State,
                   StartName, Status, Message)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Update-DbaServiceAccount.ps1 | `public/Update-DbaServiceAccount.ps1` | ソース | メイン機能実装 |
| Get-DbaService.ps1 | `public/Get-DbaService.ps1` | ソース | サービス情報取得 |
| Start-DbaService.ps1 | `public/Start-DbaService.ps1` | ソース | サービス開始 |
| Update-DbaServiceAccount.Tests.ps1 | `tests/Update-DbaServiceAccount.Tests.ps1` | テスト | テストコード |
