# Coding Conventions **Analysis Date:** 2026-04-02 ## Naming Patterns **Functions:** - PascalCase for public functions: `Write-Log`, `Get-ProfilesFilePath`, `Load-Profiles`, `Save-Profiles`, `Show-InputDialog` - Verb-Noun format using standard PowerShell verbs: Get-, Load-, Save-, Show-, Export-, Apply-, Validate-, Merge-, Refresh-, Switch- - Private/internal functions prefixed with underscore: `_Pkl-FormatMB`, `_Pkl-Sort`, `_Pkl-Repopulate`, `_Tpl-Repopulate`, `_Tpl-Log` - Descriptive names reflecting operation scope: `Get-SiteStorageMetrics`, `Collect-FolderStorage`, `Collect-WebStorage`, `Export-PermissionsToHTML` **Variables:** - camelCase for local variables: `$message`, `$color`, `$data`, `$index`, `$siteSrl` - PascalCase for control variables and form elements: `$form`, `$LogBox`, `$ClientId`, `$SiteURL` - Prefixed script-scope variables with `$script:` for shared state: `$script:LogBox`, `$script:Profiles`, `$script:SelectedSites`, `$script:_pkl`, `$script:_tpl` - Abbreviated but meaningful names in tight loops: `$s` (site), `$e` (event), `$i` (index), `$m` (message), `$c` (color) - Hashtable keys use camelCase: `@{ name = "...", clientId = "...", tenantUrl = "..." }` **Parameters:** - Type hints included in function signatures: `[string]$Message`, `[array]$Data`, `[switch]$IncludeSubsites`, `[int]$CurrentDepth` - Optional parameters use `= $null` or `= $false` defaults: `[string]$Color = "LightGreen"`, `[System.Windows.Forms.Form]$Owner = $null` - Single-letter abbreviated parameters in nested functions: `param($s, $e)` for event handlers **File/Directory Names:** - Single main script file: `Sharepoint_ToolBox.ps1` - Settings/profile files: `Sharepoint_Settings.json`, `Sharepoint_Export_profiles.json`, `Sharepoint_Templates.json` - Generated report files use pattern: `{ReportType}_{site/date}_{timestamp}.{csv|html}` ## Code Style **Formatting:** - No explicit formatter configured - Indentation: 4 spaces (PowerShell default) - Line length: practical limit around 120 characters (some HTML generation lines exceed this) - Braces on same line for blocks: `function Name { ... }`, `if ($condition) { ... }` - Region markers used for file organization: `#region ===== Section Name =====` and `#endregion` **Regions Organization (in `Sharepoint_ToolBox.ps1`):** - Shared Helpers (utility functions) - Profile Management (profile CRUD, loading/saving) - Settings (configuration handling) - Site Picker (dialog and list management) - Template Management (capture, apply, storage) - HTML Export: Permissions and Storage (report generation) - PnP: Permissions and Storage Metrics (SharePoint API operations) - File Search (advanced file search functionality) - Transfer (file/folder transfer operations) - Bulk Site Creation (site creation from templates) - Internationalization (multi-language support) - GUI (main form and controls definition) - Event Handlers (button clicks, selections, menu actions) - Structure (folder tree CSV parsing) **Comments:** - Inline comments explain non-obvious logic: `# Groups rows that share the same Users + Permissions` - Block comments precede major sections: `# -- Top bar --`, `# -- Site list (ListView with columns) --` - Section separators use dashes: `# ── Profile Management ─────────────────────────────────` - Descriptive comments in complex functions explain algorithm: `# Recursively collects subfolders up to $MaxDepth levels deep` - No JSDoc/TSDoc style - pure text comments ## Import Organization **Module Imports:** - `Add-Type -AssemblyName` for .NET assemblies at script start: - `System.Windows.Forms` for UI controls - `System.Drawing` for colors and fonts - `Import-Module PnP.PowerShell` dynamically when needed in background runspace blocks - No explicit order beyond UI assemblies first ## Error Handling **Patterns:** - Broad `try-catch` blocks with minimal logging: `try { ... } catch {}` - Silent error suppression common: empty catch blocks swallow exceptions - Explicit error capture in key operations: `catch { $Sync.Error = $_.Exception.Message }` - Error logging via `Write-Log` with color coding: - Red for critical failures: `Write-Log "Erreur: $message" "Red"` - Yellow for informational messages: `Write-Log "Processing..." "Yellow"` - DarkGray for skipped items: `Write-Log "Skipped: $reason" "DarkGray"` - Exception messages extracted and logged: `$_.Exception.Message` - Validation checks return boolean: `if ([string]::IsNullOrWhiteSpace(...)) { return $false }` ## Logging **Framework:** Native `Write-Log` function + UI RichTextBox display **Patterns:** ```powershell function Write-Log { param([string]$Message, [string]$Color = "LightGreen") if ($script:LogBox -and !$script:LogBox.IsDisposed) { # Append to UI with timestamp and color $script:LogBox.AppendText("$(Get-Date -Format 'HH:mm:ss') - $Message`n") } Write-Host $Message # Also output to console } ``` **Logging locations:** - Long-running operations log to RichTextBox in real-time via background runspace queue - Background functions use custom `BgLog` helper that queues messages: `function BgLog([string]$m, [string]$c="LightGreen")` - Colors indicate message type: LightGreen (success), Yellow (info), Cyan (detail), DarkGray (skip), Red (error) - Timestamps added automatically: `HH:mm:ss` format ## Validation **Input Validation:** - Null/whitespace checks: `[string]::IsNullOrWhiteSpace($variable)` - Array/collection size checks: `$array.Count -gt 0`, `$items -and $items.Count -gt 0` - Index bounds validation: `if ($idx -lt 0 -or $idx -ge $array.Count) { return }` - UI MessageBox dialogs for user-facing errors: `[System.Windows.Forms.MessageBox]::Show(...)` - Function-level validation via `Validate-Inputs` pattern ## String Handling **HTML Escaping:** - Custom `EscHtml` function escapes special characters for HTML generation: ```powershell function EscHtml([string]$s) { return $s -replace '&','&' -replace '<','<' -replace '>','>' -replace '"','"' } ``` - Applied to all user-supplied data rendered in HTML reports **String Interpolation:** - Double-quoted strings with `$variable` expansion: `"URL: $url"` - Format operator for complex strings: `"Template '{0}' saved" -f $name` - Localization helper function `T` for i18n strings: `T "profile"`, `T "btn.save"` ## Function Design **Size:** Functions range from 5-50 lines for utilities, 100+ lines for complex operations **Parameters:** - Explicit type declarations required - Optional parameters use default values - Switch parameters for boolean flags: `[switch]$IncludeSubsites` - Complex objects passed as reference (arrays, hashtables) **Return Values:** - Functions return results or arrays: `return @()`, `return $data` - Boolean results for validation: `return $true` / `return $false` - PSCustomObject for structured data: `[PSCustomObject]@{ Name = ...; Value = ... }` - Void operations often silent or logged ## Object/Struct Patterns **PSCustomObject for Data:** ```powershell [PSCustomObject]@{ name = "value" clientId = "value" capturedAt = (Get-Date -Format 'dd/MM/yyyy HH:mm') options = @{ structure = $true; permissions = $true } } ``` **Hashtable for Mutable State:** ```powershell $script:_pkl = @{ AllSites = @() CheckedUrls = [System.Collections.Generic.HashSet[string]]::new() SortCol = 0 SortAsc = $true } ``` **Synchronized Hashtable for Thread-Safe State:** ```powershell $sync = [hashtable]::Synchronized(@{ Done = $false Error = $null Queue = [System.Collections.Generic.Queue[object]]::new() }) ``` ## Class/Type Usage - Minimal custom classes; primarily uses `[PSCustomObject]` - Extensive use of .NET types: - `[System.Windows.Forms.*]` for UI controls - `[System.Drawing.Color]` for colors - `[System.Drawing.Font]` for typography - `[System.Drawing.Point]`, `[System.Drawing.Size]` for positioning - `[System.Collections.Generic.HashSet[string]]` for efficient lookups - `[System.Collections.Generic.Queue[object]]` for message queues - `[System.Management.Automation.Runspaces.*]` for background execution ## Date/Time Formatting **Consistent format:** `dd/MM/yyyy HH:mm` (European format) - Used for timestamps in reports and logs - Timestamps in logs: `HH:mm:ss` - Storage/file metrics: `dd/MM/yyyy HH:mm` ## Performance Patterns **Batch Operations:** - Form updates wrapped in `BeginUpdate()` / `EndUpdate()` to prevent flickering - ListView population optimized: clear, populate, sort in batch **Threading:** - Long-running PnP operations execute in separate runspace - Main UI thread communicates via synchronized hashtable + timer polling - Async UI updates via `Timer` with `DoEvents()` for responsiveness --- *Convention analysis: 2026-04-02*