# 機能設計書 229-Set-DbaPrivilege

## 概要

本ドキュメントは、SQL Serverサービスアカウントに重要なWindows特権を付与するdbatools PowerShellコマンドレット「Set-DbaPrivilege」の機能設計書である。

### 本機能の処理概要

Set-DbaPrivilegeは、SQL Serverのパフォーマンスとセキュリティに必要なWindows特権（Lock Pages in Memory、Instant File Initialization、Batch Logon、Service Logon、Generate Security Audits）をSQL Serverサービスアカウントに付与するコマンドレットである。ローカルセキュリティポリシーを編集するためのGUI操作を不要にし、複数サーバーへの一括設定を可能にする。

**業務上の目的・背景**：SQL Serverの最適なパフォーマンスには、いくつかのWindows特権が必要である。Lock Pages in Memory（LPIM）はメモリのページングを防止し、Instant File Initialization（IFI）はデータベースファイル作成を高速化する。これらの特権を手動で設定するのは煩雑であり、本機能により自動化と標準化が可能になる。

**機能の利用シーン**：
- SQL Server新規インストール後の初期設定
- パフォーマンス最適化のための特権付与
- セキュリティポリシー準拠のための設定
- 複数サーバーへの一括設定適用

**主要な処理内容**：
1. 現在のセキュリティポリシーのエクスポート（secedit）
2. SQL Serverサービスアカウントの取得
3. 指定された特権の設定ファイル編集
4. seceditによるポリシーの適用
5. 一時ファイルのクリーンアップ

**関連システム・外部連携**：secedit.exe（Windowsセキュリティポリシーツール）、WMI、PowerShellリモーティングを使用。

**権限による制御**：ターゲットコンピュータへのローカル管理者権限が必要。

## 関連画面

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

## 機能種別

OS設定変更（Windowsセキュリティポリシー）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | 対象Windowsコンピュータ | デフォルト: $env:COMPUTERNAME |
| Credential | PSCredential | No | Windows認証用資格情報 | - |
| Type | string[] | Yes | 付与する特権の種類 | ValidateSet: 'IFI', 'LPIM', 'BatchLogon', 'SecAudit', 'ServiceLogon' |
| User | string | No | 特権を付与するユーザー | 指定なし時はSQL Serverサービスアカウント |
| EnableException | switch | No | 例外有効化フラグ | - |

### 入力データソース

- PowerShellコマンドライン入力
- パイプライン入力（ComputerNameプロパティ経由）

## 出力仕様

### 出力データ

本機能は出力オブジェクトを返さない。処理状況はWrite-Messageを通じてVerboseレベルで出力される。

### 出力先

なし（設定操作のみ）

## 処理フロー

### 処理シーケンス

```
1. beginブロック
   └─ SID変換関数の定義（Convert-UserNameToSID）
   └─ ComputerNameの重複除去

2. 各ComputerNameに対するループ
   └─ 昇格権限チェック
   └─ PSリモーティング可能性確認

3. 現在のセキュリティポリシーエクスポート
   └─ secedit /export /cfg で一時ファイル出力

4. SQL Serverサービスアカウント取得
   └─ -User指定時はその値を使用
   └─ 未指定時はGet-DbaServiceで取得

5. 各特権タイプに対する設定
   └─ BatchLogon: SeBatchLogonRight
   └─ IFI: SeManageVolumePrivilege
   └─ LPIM: SeLockMemoryPrivilege
   └─ SecAudit: SeAuditPrivilege
   └─ ServiceLogon: SeServiceLogonRight

6. ポリシーの適用
   └─ secedit /configure /cfg でポリシー適用

7. 一時ファイル削除
   └─ secpolByDbatools.cfg を削除
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[各ComputerNameに対してループ]
    B --> C{ShouldProcess確認}
    C -->|No| D[スキップ]
    C -->|Yes| E[昇格権限チェック]
    E --> F{PSリモーティング可能?}
    F -->|No| G[警告出力・継続]
    F -->|Yes| H[secedit export実行]
    H --> I{User指定?}
    I -->|Yes| J[指定ユーザー使用]
    I -->|No| K[Get-DbaService実行]
    K --> L{サービスアカウント取得?}
    L -->|No| M[警告出力・継続]
    L -->|Yes| N[各Type処理]
    J --> N
    N --> O[SID変換]
    O --> P[ポリシーファイル編集]
    P --> Q[secedit configure実行]
    Q --> R[一時ファイル削除]
    R --> S{次のコンピュータ?}
    D --> S
    G --> S
    M --> S
    S -->|Yes| B
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ローカル管理者必須 | ターゲットコンピュータへのローカル管理者権限が必要 | 常時 |
| BR-002 | PSリモーティング必須 | PowerShellリモーティングが有効である必要がある | 常時 |
| BR-003 | サービスアカウント自動検出 | -User未指定時はSQL Serverエンジンのサービスアカウントを使用 | User未指定時 |
| BR-004 | SID変換 | ユーザー名をSIDに変換してポリシーファイルに追加 | 常時 |
| BR-005 | 既存設定保持 | 既に設定されている場合は重複追加しない | SIDマッチ時 |

### 計算ロジック

特権名とレジストリキーの対応:
- IFI → SeManageVolumePrivilege
- LPIM → SeLockMemoryPrivilege
- BatchLogon → SeBatchLogonRight
- SecAudit → SeAuditPrivilege
- ServiceLogon → SeServiceLogonRight

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

本機能はデータベース操作を行わない。Windowsセキュリティポリシーを直接編集する。

### seceditコマンド使用

| コマンド | 目的 |
|---------|------|
| secedit /export /cfg | 現在のセキュリティポリシーをエクスポート |
| secedit /configure /cfg | 編集したポリシーを適用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ElevationRequired | 管理者権限なし | 管理者として実行 |
| - | RemotingFailed | PSリモーティング不可 | WinRMサービスを確認 |
| - | NoServiceAccount | サービスアカウント取得失敗 | -Userパラメータを使用 |
| - | SeceditFailed | secedit実行失敗 | ポリシー構文を確認 |

### リトライ仕様

リトライ処理は実装されていない。エラー発生時はStop-Functionで処理を停止し、-Continueにより次のコンピュータに進む。

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

seceditによるポリシー適用はトランザクションサポートなし。適用後は即座に有効。

## パフォーマンス要件

特に定義されていない。ポリシー変更は軽量な操作である。

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

- ターゲットコンピュータへのローカル管理者権限が必要
- PowerShellリモーティング（WinRM）が有効である必要がある
- 特権の不適切な付与はセキュリティリスクになる可能性がある
- 一時ファイル（secpolByDbatools.cfg）は処理後に削除される

## 備考

- LPIMは大量メモリ環境でのパフォーマンス向上に効果的
- IFIはデータベースファイル作成/拡張を大幅に高速化
- WhatIfとConfirmパラメータをサポート
- 設定操作のみのため出力オブジェクトなし

---

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

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

### 推奨読解順序

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

SID変換関数とスクリプトブロックの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | $ResolveAccountToSID関数定義（79-84行目） |

**読解のコツ**: Convert-UserNameToSID関数はリモートマシン上で実行されるため、文字列として定義されている。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | beginブロック（78-87行目） |
| 2-2 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | processブロック（88-237行目） |

**主要処理フロー**:
1. **91-92行目**: Test-ElevationRequirementで昇格権限チェック
2. **93-97行目**: secedit /exportでポリシーエクスポート
3. **99-105行目**: サービスアカウント取得
4. **106-223行目**: 各Type別のポリシー編集処理

#### Step 3: 特権設定ロジックを理解する

各特権タイプの設定処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | BatchLogon処理（117-137行目） |
| 3-2 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | IFI処理（138-158行目） |
| 3-3 | Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | LPIM処理（159-179行目） |

**主要処理フロー**:
- **各Type共通パターン**:
  1. Get-Contentで該当行を検索
  2. SIDに変換
  3. 行が存在しない場合は新規追加
  4. SIDが含まれていない場合は追加
  5. 既に存在する場合はスキップ

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

```
Set-DbaPrivilege
    │
    ├─ begin {}
    │      └─ $ResolveAccountToSID関数定義
    │
    ├─ Test-ElevationRequirement
    │
    ├─ Test-PSRemoting
    │
    ├─ Invoke-Command2 (secedit export)
    │      └─ secedit /export /cfg
    │
    ├─ Get-DbaService (-User未指定時)
    │      └─ SQL Serverサービスアカウント取得
    │
    ├─ Invoke-Command2 (ポリシー編集)
    │      └─ Convert-UserNameToSID
    │      └─ Get-Content / Set-Content
    │      └─ secedit /configure /cfg
    │
    └─ Invoke-Command2 (一時ファイル削除)
           └─ Remove-Item
```

### データフロー図

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

ComputerName ────────┐
Credential ──────────┼──▶ Test-ElevationRequirement
Type ────────────────┤         │
User ────────────────┘         ▼
                        secedit /export
                               │
                               ▼
                        Get-DbaService (User未指定時)
                               │
                               ▼
                        各Type別ポリシー編集
                        ├─ SID変換
                        └─ Set-Content
                               │
                               ▼
                        secedit /configure
                               │
                               ▼
                        一時ファイル削除
                               │
                               ▼
                        なし（出力オブジェクトなし）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | ソース | メインコマンドレット実装 |
| Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | ソース | 現在の特権設定取得（関連機能） |
| Get-DbaService.ps1 | `public/Get-DbaService.ps1` | ソース | サービスアカウント取得 |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | PowerShellリモーティング |
