# 機能設計書 162-Invoke-DbaAdvancedUpdate

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Invoke-DbaAdvancedUpdate`コマンドレットに関する機能設計書である。このコマンドは、リモートコンピュータにSQL Serverアップデートとパッチをインストールし、自動的な再起動管理を行う機能を提供する。

### 本機能の処理概要

Invoke-DbaAdvancedUpdateは、ターゲットコンピュータ上でSQL Server KBアップデートを実行し、パッチファイルの展開、setup.exeの適切なパラメータでの実行、必要に応じたシステム再起動の管理を行う。この関数はUpdate-DbaInstanceの内部ロジックを処理し、特定のSQL Serverインスタンスまたはマシン上の全インスタンスに対するアップデートアクションを処理する。

**業務上の目的・背景**：
SQL Serverの脆弱性修正やパフォーマンス改善のためには、定期的なパッチ適用が不可欠である。しかし、大規模環境では手動でのパッチ適用は時間がかかり、エラーが発生しやすい。このコマンドは、パッチ適用プロセスを自動化し、複数のアップデートを順番に適用する際の再起動シーケンスを管理することで、DBAの作業負荷を大幅に軽減する。

**機能の利用シーン**：
- 月次セキュリティパッチの適用
- SQL ServerのCU（累積更新プログラム）の適用
- 複数サーバーへの一括パッチ適用
- メンテナンスウィンドウ中の自動化されたアップグレード作業
- 災害復旧環境の構築時のパッチレベル統一

**主要な処理内容**：
1. ターゲットコンピュータの保留中再起動チェック
2. 必要に応じた事前再起動の実行
3. 最も空き容量のあるドライブの検出（展開先）
4. パッチファイルの展開（/x オプション）
5. setup.exeの実行（/quiet、/allinstances または /instancename、/IAcceptSQLServerLicenseTerms）
6. 終了コードの評価と再起動の必要性判定
7. 一時ファイルのクリーンアップ
8. 結果の返却

**関連システム・外部連携**：
- Update-DbaInstance（親コマンド、アクションプランの作成）
- WinRM（リモート実行）
- Get-DbaDiskSpace（ディスク空き容量の確認）
- Invoke-Program/Invoke-Command2（リモートプログラム実行）
- Test-PendingReboot（保留中再起動のチェック）

**権限による制御**：
- ターゲットコンピュータへのWinRMアクセス権限が必要
- SQL Serverセットアップを実行できる管理者権限が必要
- ネットワーク共有上のリポジトリにアクセスする場合はCredSSP認証が推奨

## 関連画面

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

## 機能種別

データ連携 / システム管理 / パッチ適用

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | string | No | SQL Serverアップデートをインストールするリモートコンピュータ | - |
| Action | object[] | No | Update-DbaInstanceが作成したアップデートアクションプランオブジェクト | TargetLevel, KB, Installer等のプロパティ必須 |
| Restart | bool | No | パッチ適用後に自動的に再起動するかどうか | - |
| Credential | PSCredential | No | リモートサーバーへのログイン資格情報 | - |
| Authentication | string | No | WinRM認証プロトコル（デフォルト: Credssp） | ValidateSet |
| ExtractPath | string | No | アップデートファイルを展開するディレクトリパス | - |
| ArgumentList | string[] | No | setup.exeに渡す追加のコマンドライン引数 | - |
| NoPendingRenameCheck | switch | No | 保留中ファイル名変更チェックをスキップ | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- Action配列（Update-DbaInstanceから渡されるアップデートプラン）
- リモートコンピュータ上のディスク情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TargetLevel | string | インストールされたSQL Serverパッチレベル |
| KB | string | 適用されたパッチのKB番号 |
| Installer | string | 使用されたKBインストーラファイルのパス |
| MajorVersion | string | SQL Serverのメジャーバージョン（例: 2019, 2022） |
| Build | string | インストールの特定のビルド番号 |
| InstanceName | string | ターゲットのSQL Serverインスタンス名（nullの場合は全インスタンス） |
| Successful | boolean | アップデートインストールが正常に完了したかどうか |
| Restarted | boolean | このアップデートの一部としてコンピュータが再起動されたかどうか |
| ExitCode | int | SQL Server setup.exeプログラムが返した終了コード |
| ExtractPath | string | ターゲットコンピュータでアップデートファイルが展開されたディレクトリパス |
| Log | string | setup.exeインストールプロセスからの出力ログ |
| Notes | string[] | インストール中に発生したエラーメッセージ、警告、またはステータスノートの配列 |

### 出力先

コンソール（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. 初期化
   ├─ 再起動パラメータの設定
   └─ restarted変数の初期化
2. 保留中再起動のチェック
   ├─ Test-PendingReboot呼び出し
   └─ 再起動が必要かつRestartパラメータがtrueの場合:
       └─ Restart-Computer実行
3. 各Actionのループ処理
   ├─ 出力オブジェクトの初期化
   ├─ 展開先ドライブの決定
   │   ├─ ExtractPath指定あり: 指定パス使用
   │   └─ ExtractPath指定なし: Get-DbaDiskSpaceで最大空き容量ドライブ検出
   ├─ 展開パスの生成（dbatools_KB{番号}_Extract_{GUID}）
   ├─ パッチファイルの展開（/x:"展開パス" /quiet）
   ├─ setup.exe実行
   │   ├─ SQL 2008の場合: /quiet + /instancename or /allinstances
   │   └─ SQL 2008以降: 上記 + /IAcceptSQLServerLicenseTerms
   ├─ 終了コード評価
   ├─ 一時ファイルのクリーンアップ
   └─ 再起動チェックと実行（終了コード3010または保留中再起動）
4. 結果オブジェクトの出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[保留中再起動チェック]
    B --> C{再起動必要?}
    C -->|Yes & Restart=true| D[コンピュータ再起動]
    C -->|No| E[Actionループ開始]
    D --> E

    E --> F{ExtractPath指定?}
    F -->|Yes| G[指定パス使用]
    F -->|No| H[Get-DbaDiskSpaceで最大空きドライブ検出]
    G --> I[展開パス生成]
    H --> I

    I --> J[パッチファイル展開]
    J --> K{展開成功?}
    K -->|No| L[エラー処理・出力]
    K -->|Yes| M[setup.exe実行]

    M --> N{インストール成功?}
    N -->|No| O[エラー処理]
    N -->|Yes| P[Successful=true]
    O --> Q[一時ファイルクリーンアップ]
    P --> Q

    Q --> R[保留中再起動チェック]
    R --> S{再起動必要?}
    S -->|Yes & Restart=true| T[コンピュータ再起動]
    S -->|No| U[結果出力]
    T --> U

    U --> V{次のAction?}
    V -->|Yes| E
    V -->|No| W[終了]
    L --> W
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 事前再起動 | 保留中再起動がある場合、パッチ適用前に再起動を実行 | Restart=trueかつ保留中再起動あり |
| BR-002 | 展開先自動選択 | ExtractPath未指定時は最も空き容量のあるドライブを選択 | ExtractPath未指定時 |
| BR-003 | SQL 2008互換 | SQL Server 2008（ビルド10.0.*）では/IAcceptSQLServerLicenseTermsを省略 | Build like "10.0.*" |
| BR-004 | 終了コード3010 | 終了コード3010は再起動が必要であることを示す | ExitCode=3010 |
| BR-005 | GUIDベース展開パス | 展開パスにGUIDを含めて一意性を確保 | 常時 |

### 計算ロジック

**展開パスの生成**:
```
{ドライブ}\dbatools_KB{KB番号}_Extract_{GUID（ハイフン除去）}
```

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

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

該当なし（SQL Serverサービスレベルでの操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | リモートコンピュータへの接続失敗 | Stop-Function、Notes配列に追加 |
| - | ExtractionError | パッチファイルの展開失敗 | Stop-Function、Notes配列に追加、処理中断 |
| - | InstallationError | setup.exeの実行失敗 | Stop-Function、Notes配列に追加 |
| - | RestartError | 再起動の失敗 | Stop-Function、Notes配列に追加 |
| - | CleanupWarning | 一時ファイルのクリーンアップ失敗 | 警告ログ、Notes配列に追加（処理は継続） |

### リトライ仕様

リトライ機能なし（エラー発生時は出力オブジェクトにNotes追加後、返却）

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

該当なし（ファイルシステムおよびサービスレベル操作）

## パフォーマンス要件

- パッチファイルの展開と適用に数分から数十分かかる可能性がある
- 再起動待機時間は環境により異なる

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

- CredSSP認証はダブルホップ問題を回避するために必要
- 資格情報はリモートコンピュータへの管理者アクセスに使用
- 展開パスにはセキュリティ考慮が必要（一時ファイルは自動削除）

## 備考

- Update-DbaInstanceから内部的に呼び出されることを想定
- SQL Server 2000以降のバージョンをサポート
- 複数のアップデートを連続適用する場合、各アップデート間で自動再起動を管理

---

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

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

### 推奨読解順序

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

Actionオブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Action構造 | Update-DbaInstanceから生成 | TargetLevel, KB, Installer, MajorVersion, Build, InstanceNameプロパティ |

**読解のコツ**: Actionオブジェクトは親コマンドUpdate-DbaInstanceが生成するプランオブジェクト。各プロパティがインストール先とパッチを特定する。

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

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

**主要処理フロー**:
1. **99-112行目**: パラメータ定義
2. **113-143行目**: 初期化と事前再起動チェック
3. **146-259行目**: 各Actionのループ処理

#### Step 3: 展開とインストール処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | 展開先決定ロジック | 161-177行目 | Get-DbaDiskSpaceによる空き容量チェック |
| 3-2 | パッチ展開処理 | 180-190行目 | Invoke-Programによる展開実行 |
| 3-3 | setup.exe実行 | 191-214行目 | バージョン判定とパラメータ構築 |

**主要処理フロー**:
- **161-177行目**: ExtractPath未指定時の自動選択ロジック
- **178行目**: 展開パス生成（GUID付き）
- **184行目**: Invoke-Programで展開（/x:"パス" /quiet）
- **192-201行目**: インスタンス指定とバージョン判定
- **204行目**: setup.exe実行

#### Step 4: クリーンアップと再起動処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | 一時ファイル削除 | 220-234行目 | Invoke-CommandWithFallBackによるクリーンアップ |
| 4-2 | 再起動処理 | 235-257行目 | 終了コード3010判定と再起動実行 |

**主要処理フロー**:
- **225-228行目**: セキュリティチェック（パス検証）後に削除
- **242行目**: ExitCode=3010または保留中再起動で再起動実行

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

```
Update-DbaInstance (親コマンド)
    │
    └─ Invoke-DbaAdvancedUpdate
           │
           ├─ Test-PendingReboot
           │      └─ 保留中再起動のチェック
           │
           ├─ Restart-Computer (事前再起動)
           │
           ├─ Get-DbaDiskSpace
           │      └─ 最大空き容量ドライブの検出
           │
           ├─ Invoke-Command2
           │      └─ システムドライブのフォールバック取得
           │
           ├─ Invoke-Program
           │      ├─ パッチファイル展開 (/x /quiet)
           │      └─ setup.exe実行
           │
           ├─ Invoke-CommandWithFallBack
           │      └─ 一時ファイルクリーンアップ
           │
           └─ Restart-Computer (インストール後再起動)
```

### データフロー図

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

Action配列 ───────────▶ ループ処理 ──────────────────────┐
(TargetLevel,KB,etc)           │                          │
                               ▼                          │
                      ┌────────────────────┐              │
ComputerName ────────▶│ 保留中再起動チェック │              │
                      └────────────────────┘              │
                               │                          │
                               ▼                          │
                      ┌────────────────────┐              │
Credential ──────────▶│ パッチファイル展開   │              ├──▶ PSCustomObject
Authentication ──────▶│ setup.exe実行       │              │    (Successful,
                      └────────────────────┘              │     ExitCode,
                               │                          │     Log, Notes等)
ExtractPath ─────────▶ 展開先パス決定                      │
                               │                          │
                               ▼                          │
ArgumentList ────────▶ setup.exeパラメータ                 │
                               │                          │
                               ▼                          │
                      ┌────────────────────┐              │
Restart ─────────────▶│ 再起動管理          │──────────────┘
                      └────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Invoke-DbaAdvancedUpdate.ps1 | `public/Invoke-DbaAdvancedUpdate.ps1` | ソース | メイン関数定義 |
| Update-DbaInstance.ps1 | `public/Update-DbaInstance.ps1` | ソース | 親コマンド、アクションプラン生成 |
| Get-DbaDiskSpace.ps1 | `public/Get-DbaDiskSpace.ps1` | ソース | ディスク空き容量確認 |
| Test-PendingReboot | 内部関数 | ソース | 保留中再起動チェック |
| Invoke-Program | 内部関数 | ソース | リモートプログラム実行 |
