# 画面設計書 127-特権設定

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける特権設定管理機能の設計仕様を定義する。SQL Serverサービスアカウントに必要なWindows特権（LPIM、IFI、バッチログオン等）の監査と設定を行い、パフォーマンスの最適化を支援する。

### 本画面の処理概要

**業務上の目的・背景**：SQL Serverのパフォーマンスと正常動作には、特定のWindows特権がサービスアカウントに付与されている必要がある。特に重要な特権は以下の5つである：
- **Lock Pages in Memory (LPIM)**: メモリをページングファイルにスワップされることを防ぎ、大規模メモリ環境でのパフォーマンスを向上
- **Instant File Initialization (IFI)**: データファイルの作成・拡張時のゼロ初期化をスキップし、操作を高速化
- **Logon as Batch**: バッチジョブとしてログオン（SQL Agent等で使用）
- **Generate Security Audits**: セキュリティ監査ログへの書き込み
- **Logon as a Service**: サービスとしてログオン

本機能群は、seceditコマンドを使用してローカルセキュリティポリシーをエクスポート・解析し、これらの特権の監査と設定を自動化する。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドレットを実行してアクセスする。
```powershell
Get-DbaPrivilege -ComputerName <コンピュータ名>
Set-DbaPrivilege -ComputerName <コンピュータ名> -Type LPIM,IFI
```

**主要な操作・処理内容**：
1. **Get-DbaPrivilege**: secedit /exportでセキュリティポリシーをエクスポートし、5つの特権を持つユーザー/グループを取得
2. **Set-DbaPrivilege**: SQL Serverサービスアカウントを自動検出（またはカスタム指定）し、セキュリティポリシーを更新

**画面遷移**：本機能はCLIコマンドであり、GUI画面遷移は存在しない。Get-DbaPrivilegeで現状確認後、Set-DbaPrivilegeで設定変更を行う流れが一般的。

**権限による表示制御**：
- ローカル管理者権限が必須
- リモートコンピュータの操作にはPowerShellリモーティング権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 138 | Get-DbaPrivilege | 主機能 | 特権の取得 |
| 229 | Set-DbaPrivilege | 主機能 | 特権の設定 |

## 画面種別

CLI（コマンドラインインターフェース） - 複数コマンドレット

## URL/ルーティング

PowerShellコマンドレット:
- `Get-DbaPrivilege`
- `Set-DbaPrivilege`

## 入出力項目

### Get-DbaPrivilege パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| ComputerName | DbaInstanceParameter[] | No | $env:COMPUTERNAME | 情報を取得するコンピュータ名 |
| Credential | PSCredential | No | - | 代替Windows資格情報 |
| EnableException | switch | No | $false | 例外を有効化 |

### Set-DbaPrivilege パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| ComputerName | DbaInstanceParameter[] | No | $env:COMPUTERNAME | 設定対象のコンピュータ名 |
| Credential | PSCredential | No | - | 代替Windows資格情報 |
| Type | string[] | Yes | - | 設定する特権タイプ（IFI, LPIM, BatchLogon, SecAudit, ServiceLogon） |
| User | string | No | - | カスタムユーザーアカウント |
| EnableException | switch | No | $false | 例外を有効化 |
| WhatIf | switch | No | - | 実行内容のプレビュー |
| Confirm | switch | No | - | 実行前の確認 |

## 表示項目

### Get-DbaPrivilege 出力プロパティ

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| User | string | ユーザーまたはグループ名 |
| LogonAsBatch | bool | SeBatchLogonRight特権を持つか |
| InstantFileInitialization | bool | SeManageVolumePrivilege特権を持つか |
| LockPagesInMemory | bool | SeLockMemoryPrivilege特権を持つか |
| GenerateSecurityAudit | bool | SeAuditPrivilege特権を持つか |
| LogonAsAService | bool | SeServiceLogonRight特権を持つか |

### Set-DbaPrivilege 出力

本コマンドはオブジェクトを返さない。Verboseレベルで進捗メッセージを出力する。

## イベント仕様

### 1-特権取得（Get-DbaPrivilege）

指定されたコンピュータの特権設定を監査する。

**処理フロー**:
1. `Test-PSRemoting`でリモーティング可否を確認
2. `Invoke-Command2`でリモートコンピュータにてsecedit /exportを実行
3. secpolByDbatools.cfgを一時ファイルとして作成・読み込み
4. SeBatchLogonRightを解析してバッチログオン特権を持つユーザーを取得
5. SeManageVolumePrivilegeを解析してIFI特権を持つユーザーを取得
6. SeLockMemoryPrivilegeを解析してLPIM特権を持つユーザーを取得
7. SeAuditPrivilegeを解析してセキュリティ監査特権を持つユーザーを取得
8. SeServiceLogonRightを解析してサービスログオン特権を持つユーザーを取得
9. SID形式のエントリをConvert-SIDToUserNameで名前に変換
10. 全特権のユーザーをマージし、ユニークなユーザーごとにPSCustomObjectを出力

### 2-特権設定（Set-DbaPrivilege）

SQL Serverサービスアカウントに特権を付与する。

**処理フロー**:
1. `Test-ElevationRequirement`で管理者権限を確認
2. `Test-PSRemoting`でリモーティング可否を確認
3. secedit /exportでセキュリティポリシーをエクスポート
4. Userパラメータ指定時はそのユーザーを使用、未指定時は`Get-DbaService -Type Engine`でサービスアカウントを検出
5. Typeパラメータで指定された各特権について：
   - 既存の設定を読み取り
   - ユーザーのSIDを取得（Convert-UserNameToSID）
   - 未設定の場合は[Privilege Rights]セクションに新規追加
   - 設定済みだがユーザーがない場合はユーザーを追加
   - 既に設定済みの場合はスキップ
6. secedit /configure で変更を適用
7. 一時ファイルを削除

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

本機能はSQL Serverデータベースにはアクセスしない。Windowsローカルセキュリティポリシーを取得・変更する。

### 操作別影響一覧

| 操作（イベント） | 対象リソース | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Get-DbaPrivilege | Local Security Policy | READ | セキュリティポリシーの読み取り |
| Set-DbaPrivilege | Local Security Policy | UPDATE | セキュリティポリシーの更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 発生条件 |
|-------------|------|---------|---------|
| - | Error | "Failure on $computer" | PSリモーティングテスト失敗 |
| - | Verbose | "Exporting Privileges on $computer and cleaning up temporary files" | エクスポート開始 |
| - | Verbose | "Getting Batch Logon Privileges on $computer" | バッチログオン特権取得 |
| - | Verbose | "No users with Batch Logon Rights on $computer" | 特権保持者なし |
| - | Verbose | "Added $acc to Lock Pages in Memory Privileges on $env:ComputerName" | LPIM特権付与成功 |
| - | Verbose | "$acc already has Lock Pages in Memory Privilege on $env:ComputerName" | 既に付与済み |
| - | Warning | "No SQL Service Accounts found on $Computer" | サービスアカウント検出失敗 |
| - | Warning | "Failed to connect to $Computer" | 接続失敗 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| PSリモーティング失敗 | Stop-Functionでエラーを出力し、次のコンピュータの処理を継続 |
| SQLサービスアカウント未検出 | 警告を出力してスキップ |
| secedit実行失敗 | Stop-Functionでエラーを出力 |
| SID変換失敗 | 元のSIDをそのまま返す |

## 備考

- 特権名とWindows内部名のマッピング：
  - IFI: SeManageVolumePrivilege
  - LPIM: SeLockMemoryPrivilege
  - BatchLogon: SeBatchLogonRight
  - SecAudit: SeAuditPrivilege
  - ServiceLogon: SeServiceLogonRight
- seceditの出力ではユーザーがSID形式（*S-1-5-...）で表示される場合がある
- Set-DbaPrivilegeはSupportsShouldProcessを実装しており、-WhatIfと-Confirmが使用可能
- User未指定時はGet-DbaService -Type EngineでSQL Serverサービスアカウントを自動検出

---

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

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

### 推奨読解順序

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

出力オブジェクトのプロパティ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 行194-202のPSCustomObjectで出力構造を確認 |

**読解のコツ**: 5つの特権それぞれのWindows内部名（Se*）を理解する。

#### Step 2: エントリーポイントを理解する（Get-DbaPrivilege）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | processブロック（行89-209） |

**主要処理フロー**:
1. **76-84行**: Convert-SIDToUserName内部関数の定義
2. **86行**: ComputerNameの重複排除
3. **91-95行**: Test-PSRemotingでリモーティング確認
4. **99-105行**: Invoke-Command2でsecedit /exportを実行
5. **107-122行**: SeBatchLogonRightの解析
6. **124-139行**: SeManageVolumePrivilegeの解析
7. **141-156行**: SeLockMemoryPrivilegeの解析
8. **158-173行**: SeAuditPrivilegeの解析
9. **175-190行**: SeServiceLogonRightの解析
10. **192-203行**: ユーザーマージとオブジェクト出力

#### Step 3: Set-DbaPrivilegeを理解する

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

**主要処理フロー**:
1. **79-85行**: Convert-UserNameToSID関数のスクリプトブロック定義
2. **92-97行**: secedit /exportでポリシーエクスポート
3. **99-105行**: SQLサービスアカウントの取得（自動または指定）
4. **108-223行**: Invoke-Command2内でのスクリプトブロック実行
5. **117-136行**: BatchLogon特権の処理
6. **138-157行**: IFI特権の処理
7. **159-178行**: LPIM特権の処理
8. **180-200行**: SecAudit特権の処理
9. **201-221行**: ServiceLogon特権の処理
10. **222行**: secedit /configureで変更適用
11. **225行**: 一時ファイル削除

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

```
Get-DbaPrivilege
    |
    +-- Test-PSRemoting
    |
    +-- Invoke-Command2
    |      +-- secedit /export /cfg
    |      +-- Get-Content (secpolByDbatools.cfg)
    |      +-- Remove-Item (secpolByDbatools.cfg)
    |
    +-- secPol解析
    |      +-- SeBatchLogonRight解析
    |      +-- SeManageVolumePrivilege解析
    |      +-- SeLockMemoryPrivilege解析
    |      +-- SeAuditPrivilege解析
    |      +-- SeServiceLogonRight解析
    |
    +-- Convert-SIDToUserName
    |      +-- System.Security.Principal.SecurityIdentifier
    |      +-- Translate to NTAccount
    |
    +-- [PSCustomObject] 出力

Set-DbaPrivilege
    |
    +-- Test-ElevationRequirement
    |
    +-- Test-PSRemoting
    |
    +-- Invoke-Command2 (secedit /export)
    |
    +-- [User未指定時] Get-DbaService -Type Engine
    |
    +-- Invoke-Command2 (特権設定)
    |      +-- Convert-UserNameToSID
    |      +-- セキュリティポリシー更新
    |      +-- secedit /configure /db secedit.sdb
    |
    +-- Invoke-Command2 (一時ファイル削除)
```

### データフロー図

```
[Get-DbaPrivilege]

ComputerName ──────────> Test-PSRemoting ─────────────────>
                                |
                                v
                        Invoke-Command2 ──────────────────>
                        (secedit /export)
                                |
                                v
                        CFGファイル解析 ───────────────────>
                                |
                        +-------+-------+-------+-------+
                        |       |       |       |       |
                        v       v       v       v       v
                    Batch   IFI    LPIM   Audit Service
                        |       |       |       |       |
                        +-------+-------+-------+-------+
                                |
                                v
                        Convert-SIDToUserName ────────────> ユーザー名
                                |
                                v
                        ユーザーマージ ───────────────────> ユニークユーザー
                                |
                                v
                        PSCustomObject ───────────────────> 出力

---

[Set-DbaPrivilege]

ComputerName ──────────> Test-ElevationRequirement ───────>
                                |
                                v
                        Test-PSRemoting ──────────────────>
                                |
                                v
                        secedit /export ──────────────────>
                                |
                                v
User ──────────────────> [指定あり?] ─────────────────────>
                                |
                        +-------+-------+
                        |               |
                        v               v
                    Userを使用     Get-DbaService
                                        |
                                        v
                                    StartName取得
                                        |
                                +-------+-------+
                                        |
                                        v
Type ──────────────────> 特権処理 ────────────────────────>
                        (IFI, LPIM, BatchLogon, etc.)
                                |
                                v
                        Convert-UserNameToSID ────────────> SID
                                |
                                v
                        CFGファイル更新 ──────────────────>
                                |
                                v
                        secedit /configure ───────────────>
                                |
                                v
                        一時ファイル削除 ─────────────────> 完了
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | ソース | 特権監査 |
| Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | ソース | 特権設定 |
| Invoke-Command2.ps1 | `internal/functions/Invoke-Command2.ps1` | 内部関数 | リモートコマンド実行 |
| Test-PSRemoting.ps1 | `internal/functions/Test-PSRemoting.ps1` | 内部関数 | PSリモーティング確認 |
| Test-ElevationRequirement.ps1 | `internal/functions/Test-ElevationRequirement.ps1` | 内部関数 | 管理者権限確認 |
| Get-DbaService.ps1 | `public/Get-DbaService.ps1` | 依存コマンド | SQLサービス情報取得 |
