# 機能設計書 228-Set-DbaPowerPlan

## 概要

本ドキュメントは、SQL Serverホストコンピュータの電源プランを設定するdbatools PowerShellコマンドレット「Set-DbaPowerPlan」の機能設計書である。

### 本機能の処理概要

Set-DbaPowerPlanは、SQL ServerホストマシンのWindows電源プランを変更するコマンドレットである。デフォルトで「High Performance」（高パフォーマンス）に設定し、CPU周波数スケーリングによるデータベースパフォーマンスの低下を防止する。

**業務上の目的・背景**：Windows電源プランはCPU周波数スケーリングを制御し、「バランス」プランでは省電力のためにCPU周波数が動的に変化する。これはSQL Serverワークロードで重大なパフォーマンス低下を引き起こす可能性がある。本機能により、SQL Serverの最適なパフォーマンスに必要な「高パフォーマンス」電源プランを効率的に適用できる。

**機能の利用シーン**：
- SQL Server新規インストール後の初期設定
- パフォーマンス問題のトラブルシューティング
- 複数サーバーへの一括設定適用
- ベストプラクティス準拠の自動化

**主要な処理内容**：
1. Test-DbaPowerPlanによる現在の電源プラン取得
2. 指定された電源プラン（デフォルト: High Performance）の検証
3. PowerSetActiveScheme Win32 API呼び出しによる電源プラン変更
4. 変更結果の出力

**関連システム・外部連携**：WMI、PowerShellリモーティング、powrprof.dll（Win32 API）を使用。

**権限による制御**：ターゲットコンピュータへの管理者権限およびWMIアクセス権限が必要。

## 関連画面

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

## 機能種別

OS設定変更（Windows電源プラン）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstance[] | Yes | 対象Windowsコンピュータ | - |
| Credential | PSCredential | No | Windows認証用資格情報 | パイプライン入力可 |
| PowerPlan | string | No | 設定する電源プラン名 | デフォルト: High Performance |
| EnableException | switch | No | 例外有効化フラグ | - |

### 入力データソース

- PowerShellコマンドライン入力
- Get-DbaPowerPlanからのパイプライン入力（PowerPlanプロパティ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | ターゲットコンピュータ名 |
| PreviousPowerPlan | string | 変更前の電源プラン名 |
| ActivePowerPlan | string | 現在の電源プラン名（変更後） |
| IsChanged | bool | 電源プランが変更されたか |
| PreviousInstanceId | guid | 変更前の電源プランGUID（非表示） |
| ActiveInstanceId | guid | 現在の電源プランGUID（非表示） |

### 出力先

PowerShellパイプライン（標準出力）

## 処理フロー

### 処理シーケンス

```
1. 各ComputerNameに対するループ
   └─ Test-DbaPowerPlanで現在状態取得

2. 指定電源プランの検証
   └─ 対象コンピュータに存在するか確認
   └─ 存在しない場合はエラー

3. 既設定チェック
   └─ 既に指定プランの場合はスキップ

4. 電源プラン変更
   └─ コンピュータ名解決（Resolve-DbaNetworkName）
   └─ ScriptBlockでリモート実行
   └─ PowerSetActiveScheme API呼び出し

5. 結果の出力
   └─ PSCustomObjectで変更結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[各ComputerNameに対してループ]
    B --> C[Test-DbaPowerPlan実行]
    C --> D{成功?}
    D -->|No| E[エラー出力・継続]
    D -->|Yes| F{指定プラン存在?}
    F -->|No| G[エラー:プラン未インストール]
    F -->|Yes| H{既に設定済み?}
    H -->|Yes| I[現状維持出力]
    H -->|No| J{ShouldProcess確認}
    J -->|No| K[スキップ]
    J -->|Yes| L[コンピュータ名解決]
    L --> M[Invoke-Command2実行]
    M --> N[PowerSetActiveScheme呼び出し]
    N --> O{成功?}
    O -->|No| P[エラー出力]
    O -->|Yes| Q[IsChanged=true設定]
    Q --> R[結果出力]
    I --> R
    R --> S{次のコンピュータ?}
    E --> S
    G --> S
    K --> S
    P --> S
    S -->|Yes| B
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトHigh Performance | 電源プラン未指定時は「High Performance」を設定 | PowerPlan未指定時 |
| BR-002 | 存在確認 | 指定プランがコンピュータに存在するか検証 | 常時 |
| BR-003 | 変更不要スキップ | 既に指定プランの場合は変更しない | IsBestPractice = true時 |
| BR-004 | 即時反映 | 電源プラン変更は即座に有効 | 常時 |

### 計算ロジック

該当なし

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

本機能はデータベース操作を行わない。WindowsシステムAPIを直接呼び出す。

### Win32 API呼び出し

| API | DLL | 目的 |
|-----|-----|------|
| PowerSetActiveScheme | powrprof.dll | アクティブ電源プランの変更 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NamespaceError | WMI名前空間アクセス不可 | OSバージョンを確認 |
| - | CredentialError | 認証情報が無効 | 正しい資格情報を使用 |
| - | PlanNotInstalled | 指定プランが存在しない | 利用可能なプランを確認 |
| - | ConnectionError | リモート接続失敗 | WinRMとネットワークを確認 |
| - | ReturnCodeError | API呼び出し失敗 | 権限を確認 |

### リトライ仕様

名前解決にはResolve-DbaNetworkNameのTurboモードでのフォールバックがある。

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

Win32 API呼び出しはトランザクションサポートなし。即時反映される。

## パフォーマンス要件

特に定義されていない。電源プラン変更は軽量な操作である。

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

- ターゲットコンピュータへの管理者権限が必要
- WMIおよびPowerShellリモーティングのアクセス権限が必要
- 電源プラン変更は即座に有効になるため注意が必要

## 備考

- 参考資料:
  - https://support.microsoft.com/en-us/kb/2207548
  - http://www.sqlskills.com/blogs/glenn/windows-power-plan-effects-on-newer-intel-processors/
- Get-DbaPowerPlanで利用可能なプランを確認可能
- WhatIfとConfirmパラメータをサポート

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造とTest-DbaPowerPlanの出力を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaPowerPlan.ps1 | `public/Set-DbaPowerPlan.ps1` | 出力オブジェクトの構造（54-68行目の.OUTPUTSセクション） |

**読解のコツ**: PreviousInstanceIdとActiveInstanceIdはSelect-DefaultViewで非表示になる点に注目。

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

processブロック内のメイン処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaPowerPlan.ps1 | `public/Set-DbaPowerPlan.ps1` | processブロック（108-179行目） |

**主要処理フロー**:
1. **109-121行目**: Test-DbaPowerPlanで現在状態取得とエラーハンドリング
2. **123-127行目**: 指定電源プランの情報取得
3. **128-130行目**: プラン存在確認
4. **132-139行目**: PSCustomObject初期化
5. **141-144行目**: 既設定チェックとスキップ
6. **146-177行目**: 電源プラン変更処理

#### Step 3: 電源プラン変更ロジックを理解する

ScriptBlockとWin32 API呼び出しを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaPowerPlan.ps1 | `public/Set-DbaPowerPlan.ps1` | ScriptBlock（149-154行目） |

**主要処理フロー**:
- **150行目**: DllImport定義（PowerSetActiveScheme）
- **151行目**: Add-Typeでwin32関数登録
- **152行目**: API呼び出し（PowerSetActiveScheme）

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

```
Set-DbaPowerPlan
    │
    ├─ Test-DbaPowerPlan
    │      └─ 現在の電源プラン取得
    │      └─ 推奨プラン情報取得
    │
    ├─ Resolve-DbaNetworkName
    │      └─ コンピュータ名解決
    │
    └─ Invoke-Command2
           └─ PowerShellリモーティング実行
           └─ PowerSetActiveScheme (Win32 API)
```

### データフロー図

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

ComputerName ────────┐
Credential ──────────┤
PowerPlan ───────────┼──▶ Test-DbaPowerPlan
                     │    (現在状態取得)
                     │         │
                     │         ▼
                     │    プラン存在確認
                     │         │
                     │         ▼
                     │    {既設定チェック}
                     │         │
                     │   ┌─────┴─────┐
                     │   ▼           ▼
                     │ [スキップ]  [変更実行]
                     │               │
                     │               ▼
                     │    Invoke-Command2
                     │    (PowerSetActiveScheme)
                     │               │
                     │               ▼
                     └──▶ PSCustomObject
                          (PreviousPowerPlan, ActivePowerPlan, IsChanged)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaPowerPlan.ps1 | `public/Set-DbaPowerPlan.ps1` | ソース | メインコマンドレット実装 |
| Get-DbaPowerPlan.ps1 | `public/Get-DbaPowerPlan.ps1` | ソース | 電源プラン取得（関連機能） |
| Test-DbaPowerPlan.ps1 | `public/Test-DbaPowerPlan.ps1` | ソース | 電源プラン検証（依存先） |
| Resolve-DbaNetworkName.ps1 | `public/Resolve-DbaNetworkName.ps1` | ソース | コンピュータ名解決 |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | PowerShellリモーティング |
