|
| 1 | +# Copilot Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is **AsBuiltReport.System.Resources**, a PowerShell module for the [AsBuiltReport](https://github.com/AsBuiltReport) framework. It generates "As-Built" documentation reports (HTML, Word, Text) describing system resources (date/time, timezone, uptime, PowerShell host info, and top CPU processes) from a local or remote machine. |
| 6 | + |
| 7 | +## Lint & Validation Commands |
| 8 | + |
| 9 | +```powershell |
| 10 | +# Validate the module manifest |
| 11 | +Test-ModuleManifest .\AsBuiltReport.System.Resources\AsBuiltReport.System.Resources.psd1 |
| 12 | +
|
| 13 | +# Run PSScriptAnalyzer with project settings |
| 14 | +Invoke-ScriptAnalyzer -Path .\AsBuiltReport.System.Resources\Src -Settings .\.github\workflows\PSScriptAnalyzerSettings.psd1 -Recurse |
| 15 | +
|
| 16 | +# Run PSScriptAnalyzer on a single file |
| 17 | +Invoke-ScriptAnalyzer -Path .\AsBuiltReport.System.Resources\Src\Private\Get-AbrDate.ps1 -Settings .\.github\workflows\PSScriptAnalyzerSettings.psd1 |
| 18 | +``` |
| 19 | + |
| 20 | +No automated test suite exists. PSScriptAnalyzer linting is the CI quality gate, enforced via `.github/workflows/PSScriptAnalyzer.yml` on every push and PR. |
| 21 | + |
| 22 | +## Generating a Report (Manual Testing) |
| 23 | + |
| 24 | +```powershell |
| 25 | +# Install prerequisites |
| 26 | +Install-Module AsBuiltReport.Core, AsBuiltReport.Chart, AsBuiltReport.Diagram -Force |
| 27 | +
|
| 28 | +# Generate a report against localhost |
| 29 | +New-AsBuiltReport -Report System.Resources -Target localhost -Format Html -OutputFolderPath C:\Reports -Verbose |
| 30 | +
|
| 31 | +# Generate a default config file |
| 32 | +New-AsBuiltReportConfig -Report System.Resources -FolderPath C:\Config |
| 33 | +``` |
| 34 | + |
| 35 | +## Architecture |
| 36 | + |
| 37 | +### Entry Point Flow |
| 38 | + |
| 39 | +``` |
| 40 | +New-AsBuiltReport (AsBuiltReport.Core framework) |
| 41 | + └─ Invoke-AsBuiltReport.System.Resources [Src/Public/] |
| 42 | + └─ For each $Target: |
| 43 | + ├─ Get-AbrDate |
| 44 | + ├─ Get-AbrTimeZone |
| 45 | + ├─ Get-AbrUptime |
| 46 | + │ └─ Get-SystemUptime (WMI fallback for PS 5.1) |
| 47 | + ├─ Get-AbrPSHost |
| 48 | + └─ Get-AbrProcessInfo |
| 49 | + ├─ Get-AbrProcessDiagram |
| 50 | + └─ Export-AbrDiagram |
| 51 | +``` |
| 52 | + |
| 53 | +### Module Loader |
| 54 | + |
| 55 | +`AsBuiltReport.System.Resources.psm1` auto-discovers and dot-sources all `.ps1` files under `Src/Public/` and `Src/Private/`, then exports **both** public and private functions. Private functions must be exported because the AsBuiltReport.Core framework invokes them within its document script block scope. |
| 56 | + |
| 57 | +### Framework-Injected Variables |
| 58 | + |
| 59 | +The AsBuiltReport.Core framework injects these variables into module scope before execution — do not redefine them: |
| 60 | + |
| 61 | +| Variable | Purpose | |
| 62 | +|---|---| |
| 63 | +| `$ReportConfig` | Parsed JSON configuration object | |
| 64 | +| `$InfoLevel` | Per-section detail level (0=disabled, 1=summary, 2=detailed) | |
| 65 | +| `$Options` | Feature flags (diagrams, themes, exports) | |
| 66 | +| `$Target` | Array of system names to document | |
| 67 | +| `$System` | Current target being iterated | |
| 68 | +| `$reportTranslate` | Localization string hashtable | |
| 69 | +| `$Report` | Report metadata (ShowTableCaptions, etc.) | |
| 70 | + |
| 71 | +### Report Section Pattern |
| 72 | + |
| 73 | +Every section in `Src/Private/` follows the same structure: |
| 74 | + |
| 75 | +1. **Narrow localization scope** — `$reportTranslate = $reportTranslate.GetAbr<Feature>` |
| 76 | +2. **Collect data** — use standard PowerShell cmdlets or WMI |
| 77 | +3. **Check InfoLevel** — wrap output in `if ($InfoLevel.<Section> -ge 1)` blocks |
| 78 | +4. **Render with PScribo** — use `Section`, `Table`, `Paragraph`, `Image` etc. |
| 79 | + |
| 80 | +### PowerShell Edition Detection |
| 81 | + |
| 82 | +Use `$PSVersionTable.PSEdition` to branch between PS 5.1 (Desktop) and PS 7+ (Core): |
| 83 | + |
| 84 | +```powershell |
| 85 | +if ($PSVersionTable.PSEdition -eq 'Core') { |
| 86 | + # Use modern cmdlets (e.g., Get-Uptime) |
| 87 | +} else { |
| 88 | + # Use WMI / CIM (e.g., Get-SystemUptime helper) |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +## Key Conventions |
| 93 | + |
| 94 | +### Naming |
| 95 | + |
| 96 | +- **Private functions:** `Get-Abr<Feature>` (e.g., `Get-AbrDate`, `Get-AbrProcessInfo`) |
| 97 | +- **WMI/compatibility helpers:** `Get-System<Task>` (e.g., `Get-SystemUptime`) |
| 98 | +- **Public entry point:** `Invoke-AsBuiltReport.System.Resources` |
| 99 | +- One function per file; filename matches function name exactly. |
| 100 | + |
| 101 | +### Table Data Pattern |
| 102 | + |
| 103 | +Always build table rows as ordered hashtables promoted to `[PSCustomObject]`, using localized strings as keys: |
| 104 | + |
| 105 | +```powershell |
| 106 | +$InObj = [Ordered]@{ |
| 107 | + $($reportTranslate.Date) = $Date.ToString('yyyy-MM-dd') |
| 108 | + $($reportTranslate.Hour) = $Date.ToString('HH:mm:ss') |
| 109 | +} |
| 110 | +$SystemDateInfo += [PSCustomObject]$InObj |
| 111 | +``` |
| 112 | + |
| 113 | +### Table Rendering Pattern |
| 114 | + |
| 115 | +Always set explicit `ColumnWidths` and conditionally add a caption: |
| 116 | + |
| 117 | +```powershell |
| 118 | +$TableParams = @{ |
| 119 | + Name = "Table Name" |
| 120 | + List = $true |
| 121 | + ColumnWidths = 40, 60 |
| 122 | +} |
| 123 | +if ($Report.ShowTableCaptions) { |
| 124 | + $TableParams['Caption'] = "- $($TableParams.Name)" |
| 125 | +} |
| 126 | +$data | Table @TableParams |
| 127 | +``` |
| 128 | + |
| 129 | +### Localization |
| 130 | + |
| 131 | +- Each language lives in `Language/<locale>/SystemResources.psd1` as a nested hashtable. |
| 132 | +- Narrow to the relevant subtable at the top of each function: `$reportTranslate = $reportTranslate.GetAbr<Feature>` |
| 133 | +- When adding new string keys, add them to **all 26+ language files** under `Language/`. |
| 134 | + |
| 135 | +### Diagram Pipeline |
| 136 | + |
| 137 | +Diagrams use Graphviz via `AsBuiltReport.Diagram`. The pipeline is always: |
| 138 | +1. `Get-AbrProcessDiagram` — builds the graph object |
| 139 | +2. `Export-AbrDiagram` — calls `New-Diagrammer`, embeds base64 in report, and optionally writes to disk |
| 140 | + |
| 141 | +Diagram features are gated by `$Options.EnableDiagrams`. |
| 142 | + |
| 143 | +### PSScriptAnalyzer Exclusions |
| 144 | + |
| 145 | +The following rules are intentionally suppressed (see `.github/workflows/PSScriptAnalyzerSettings.psd1`): |
| 146 | +- `PSUseToExportFieldsInManifest` |
| 147 | +- `PSReviewUnusedParameter` |
| 148 | +- `PSUseDeclaredVarsMoreThanAssignments` |
| 149 | +- `PSAvoidGlobalVars` |
| 150 | +- `PSUseSingularNouns` |
| 151 | +- `PSAvoidUsingWriteHost` |
| 152 | + |
| 153 | +Do not add `[SuppressMessage]` attributes for these — the settings file handles them globally. |
| 154 | + |
| 155 | +### Code Style |
| 156 | + |
| 157 | +- Indentation: **4 spaces** (no tabs) |
| 158 | +- Line length: **115 characters** max |
| 159 | +- Opening brace on same line; closing brace on its own line |
| 160 | +- PascalCase for all function and parameter names |
| 161 | +- Use correct PowerShell cmdlet casing (`Get-ChildItem`, not `get-childitem`) |
| 162 | + |
| 163 | +## Branch & Release Strategy |
| 164 | + |
| 165 | +- Feature branches merge into **`dev`** (never directly into `master`) |
| 166 | +- `master` is the release branch; a GitHub release publication triggers the CI pipeline to publish to PowerShell Gallery |
| 167 | +- Follow [Keep a Changelog](https://keepachangelog.com/) format for `CHANGELOG.md` entries |
0 commit comments