# 機能設計書 138-Get-DbaPrivilege

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Get-DbaPrivilege`コマンドレットに関する機能設計書です。このコマンドレットは、SQL Serverのパフォーマンスに重要なWindowsセキュリティ特権を対象コンピュータから取得する機能を提供します。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverのパフォーマンスと機能性は、サービスアカウントに付与されているWindowsの特権に依存します。特に「メモリ内のページをロック（Lock Pages in Memory）」と「ファイルの瞬時初期化（Instant File Initialization）」は、SQL Serverのパフォーマンスに直接影響する重要な特権です。本機能は、seceditコマンドを使用してローカルセキュリティポリシーをエクスポートし、5つの重要な特権の割り当て状況を監査できます。

**機能の利用シーン**：
- SQL Serverサービスアカウントに必要な特権が付与されているか確認する場合
- パフォーマンス問題のトラブルシューティング時（Lock Pages in Memory等）
- セキュリティ監査・コンプライアンス確認時
- 複数サーバー間の特権設定比較時

**主要な処理内容**：
1. 対象コンピュータへのPSRemoting接続確認
2. secedit /exportでローカルセキュリティポリシーをエクスポート
3. 5つの特権（SeBatchLogonRight, SeManageVolumePrivilege, SeLockMemoryPrivilege, SeAuditPrivilege, SeServiceLogonRight）を解析
4. SIDをユーザー名に変換
5. 各ユーザー/グループの特権保持状況をPSCustomObjectとして出力

**関連システム・外部連携**：
- seceditコマンド（Windowsセキュリティポリシーツール）
- PowerShell Remoting（Invoke-Command2）
- Windowsレジストリ・ローカルセキュリティポリシー

**権限による制御**：対象コンピュータへのローカル管理者権限が必要です。seceditの実行には管理者権限が必須です。

## 関連画面

本機能はコマンドラインツールであり、画面機能マッピングに該当する関連画面はありません。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | PowerShellコマンドラインで実行 |

## 機能種別

データ取得 / セキュリティ監査

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | No | 特権を確認するコンピュータ名。デフォルトはローカル | パイプライン入力可、エイリアス: cn, host, Server |
| Credential | PSCredential | No | リモートコンピュータへの代替資格情報 | - |
| EnableException | switch | No | 例外処理を有効化 | - |

### 入力データソース

- seceditコマンド出力（ローカルセキュリティポリシー）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| User | string | ユーザーまたはグループ名（SIDから変換） |
| LogonAsBatch | bool | SeBatchLogonRight特権を持つか |
| InstantFileInitialization | bool | SeManageVolumePrivilege（ファイルの瞬時初期化）特権を持つか |
| LockPagesInMemory | bool | SeLockMemoryPrivilege特権を持つか |
| GenerateSecurityAudit | bool | SeAuditPrivilege特権を持つか |
| LogonAsAService | bool | SeServiceLogonRight特権を持つか |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. beginブロック: SID変換関数定義
   └─ Convert-SIDToUserName関数

2. processブロック: 各コンピュータに対して処理
   ├─ Test-PSRemotingで接続確認
   │
   ├─ Invoke-Command2でリモート実行
   │     ├─ secedit /export でポリシーエクスポート
   │     ├─ Get-Contentで内容読み取り
   │     └─ Remove-Itemで一時ファイル削除
   │
   ├─ 各特権の解析
   │     ├─ SeBatchLogonRight
   │     ├─ SeManageVolumePrivilege
   │     ├─ SeLockMemoryPrivilege
   │     ├─ SeAuditPrivilege
   │     └─ SeServiceLogonRight
   │
   ├─ SIDをユーザー名に変換
   │
   └─ 全ユーザーに対してPSCustomObject出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{各ComputerNameに対して}
    B --> C[Test-PSRemoting]
    C --> D{接続可能?}
    D -->|No| E[Stop-Function]
    E --> B
    D -->|Yes| F[Invoke-Command2: secedit実行]
    F --> G[セキュリティポリシー解析]
    G --> H[SeBatchLogonRight抽出]
    H --> I[SeManageVolumePrivilege抽出]
    I --> J[SeLockMemoryPrivilege抽出]
    J --> K[SeAuditPrivilege抽出]
    K --> L[SeServiceLogonRight抽出]
    L --> M[SIDをユーザー名に変換]
    M --> N[ユニークユーザー一覧作成]
    N --> O{各ユーザーに対して}
    O --> P[PSCustomObject出力]
    P --> O
    O -->|完了| B
    B -->|完了| Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | SID変換 | *S-で始まるSIDはユーザー名に変換試行 | 常時 |
| BR-002 | ユニーク出力 | すべての特権から集約したユニークユーザー一覧を出力 | 常時 |
| BR-003 | 特権判定 | 各ユーザーが特定の特権配列に含まれるかで判定 | 常時 |
| BR-004 | 一時ファイル削除 | secedit出力の一時ファイルは処理後削除 | 常時 |

### 計算ロジック

特権エントリの解析：
- `SeBatchLogonRight = xxx,yyy` の形式で記録
- Substring(20)で`=`以降を抽出、カンマ区切りで分割
- `*S-`で始まる場合はSIDとして変換

SID変換ロジック：
```powershell
$objSID = New-Object System.Security.Principal.SecurityIdentifier($SID)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$objUser.Value
```

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

本機能はデータベースへの直接操作を行いません。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | PSRemoting接続エラー | Test-PSRemoting失敗 | Stop-Function（処理継続） |
| - | secedit実行エラー | seceditコマンド失敗 | Stop-Function（処理継続） |
| - | SID変換エラー | 不明なSID | 変換失敗時はSIDをそのまま返却 |

### リトライ仕様

リトライ処理は実装されていません。

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

データベース操作がないため、トランザクション管理は不要です。

## パフォーマンス要件

- 各コンピュータに対してsecedit 1回、ファイル読み取り1回
- 通常数秒以内で完了

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

- 対象コンピュータへのローカル管理者権限が必要
- seceditの実行には特権が必要
- セキュリティポリシー情報の取得は監査対象

## 備考

- SQL Serverサービスアカウントには以下の特権が推奨：
  - SeManageVolumePrivilege（Instant File Initialization）: データファイルの高速作成
  - SeLockMemoryPrivilege（Lock Pages in Memory）: メモリページングの防止
  - SeServiceLogonRight: サービスとしてログオン
- Set-DbaPrivilegeコマンドで特権を設定可能

---

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

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

### 推奨読解順序

#### Step 1: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 76-84行目: Convert-SIDToUserName関数 |

**読解のコツ**: SIDからNTAccountへの変換はtry/catchで囲まれ、変換失敗時は元のSIDを返却する点に注目。

#### Step 2: セキュリティポリシー取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 99-105行目: seceditによるポリシーエクスポート |

**主要処理フロー**:
1. **100行目**: 一時ファイルパス取得
2. **101行目**: `secedit /export /cfg {path}` でポリシーエクスポート
3. **102行目**: Get-Contentで読み取り
4. **103行目**: Remove-Itemで一時ファイル削除

#### Step 3: 特権解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 107-118行目: SeBatchLogonRight解析 |
| 3-2 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 124-135行目: SeManageVolumePrivilege解析 |
| 3-3 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 141-152行目: SeLockMemoryPrivilege解析 |
| 3-4 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 158-169行目: SeAuditPrivilege解析 |
| 3-5 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 175-186行目: SeServiceLogonRight解析 |

**主要処理フロー**:
- **108行目**: Where-Object で該当行を検索
- **110-116行目**: Substring + Split でユーザー一覧抽出
- **112-116行目**: SID判定と変換

#### Step 4: 出力生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | 192-203行目: ユニークユーザー集約と出力 |

**主要処理フロー**:
- **192行目**: 5つの特権リストを結合してユニーク化
- **193-203行目**: 各ユーザーに対してPSCustomObject生成
- **197-201行目**: 各特権に対して`-contains`で保持判定

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

```
Get-DbaPrivilege
    │
    ├─ begin ブロック
    │      └─ Convert-SIDToUserName関数定義
    │
    └─ process ブロック
           │
           └─ foreach ($computer in $ComputerName)
                  │
                  ├─ Test-PSRemoting
                  │      └─ [失敗時] Stop-Function
                  │
                  ├─ Invoke-Command2 (secedit実行)
                  │      ├─ secedit /export
                  │      ├─ Get-Content
                  │      └─ Remove-Item
                  │
                  ├─ 特権解析 (5種類)
                  │      ├─ SeBatchLogonRight
                  │      ├─ SeManageVolumePrivilege
                  │      ├─ SeLockMemoryPrivilege
                  │      ├─ SeAuditPrivilege
                  │      └─ SeServiceLogonRight
                  │
                  ├─ Convert-SIDToUserName (各SID)
                  │
                  └─ PSCustomObject出力
```

### データフロー図

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

ComputerName ───────▶ Test-PSRemoting
                            │
                            ▼
                     Invoke-Command2
                            │
                     secedit /export
                            │
                            ▼
                     セキュリティポリシーファイル
                            │
  SeBatchLogonRight ────────┼
  SeManageVolumePrivilege ──┼
  SeLockMemoryPrivilege ────┼──▶ 5つの特権解析
  SeAuditPrivilege ─────────┼
  SeServiceLogonRight ──────┤
                            │
                            ▼
                     SID → ユーザー名変換
                            │
                            ▼
                     ユニークユーザー集約
                            │
                            ▼
                     PSCustomObject ───────▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaPrivilege.ps1 | `public/Get-DbaPrivilege.ps1` | ソース | メイン処理 |
| Set-DbaPrivilege.ps1 | `public/Set-DbaPrivilege.ps1` | ソース | 特権設定（関連） |
| Test-PSRemoting.ps1 | `private/functions/Test-PSRemoting.ps1` | ソース | リモート接続テスト |
| Invoke-Command2.ps1 | `private/functions/Invoke-Command2.ps1` | ソース | リモート実行 |
| Stop-Function.ps1 | `private/functions/flowcontrol/Stop-Function.ps1` | ソース | エラー処理 |
