14 KiB
Codebase Concerns
Analysis Date: 2026-04-02
Tech Debt
Silent Error Handling (Widespread):
- Issue: 38 empty
catchblocks that suppress errors without logging - Files:
Sharepoint_ToolBox.ps1(lines 1018, 1020, 1067, 1068, 1144, 2028, 2030, etc.) - Impact: Failures go unnoticed, making debugging difficult. Users don't know why operations fail. Error conditions are hidden from logs.
- Fix approach: Add logging to all
catchblocks. UseBgLogfor background tasks,Write-Logfor UI threads. Example:catch { BgLog "Folder enumeration failed: $_" "DarkGray" }instead ofcatch {}
Resource Cleanup Issues:
- Issue: Runspace and PowerShell objects created in background jobs may not be properly disposed if exceptions occur
- Files:
Sharepoint_ToolBox.ps1lines 1040-1052, 4564-4577, 5556-5577 - Impact: Memory leaks possible if UI interactions are interrupted. Zombie runspaces could accumulate over multiple operations.
- Fix approach: Wrap all runspace/PS object creation in try-finally blocks. Ensure
$rs.Dispose()and$ps.Dispose()are called in finally block, not just in success path
Overly Broad Error Suppression:
- Issue: 27 instances of
-ErrorAction SilentlyContinuespread throughout code - Files:
Sharepoint_ToolBox.ps1(e.g., lines 1142, 1188, 2070, 4436, etc.) - Impact: Real failures indistinguishable from expected failures (e.g., list doesn't exist vs. connection failed). Masks bugs.
- Fix approach: Use selective error suppression. Only suppress when you've explicitly checked for the condition (e.g., "if list doesn't exist, create it"). Otherwise use
-ErrorAction Stopwith explicit try-catch.
Inconsistent JSON Error Handling:
- Issue: JSON parsing in
Load-Profiles,Load-Settings,Load-Templatesuses empty catch blocks - Files:
Sharepoint_ToolBox.ps1lines 61, 140, 568-570 - Impact: Corrupted JSON files silently fail and return empty defaults, losing user data silently
- Fix approach: Log actual error message. Implement validation schema. Create backup of corrupted files.
Known Bugs
Blank Client ID Warning Not Actionable:
- Symptoms: "WARNING: No Client ID returned" appears but doesn't prevent further operations or clear user input
- Files:
Sharepoint_ToolBox.ps1line 4237 - Trigger: Azure AD app registration completes but returns null ClientId (can happen with certain tenant configurations)
- Workaround: Manually register app via Azure Portal and paste Client ID
- Fix approach: Check for null ClientId before continuing, clear the warning state properly
Group Member Addition Silent Failures:
- Symptoms: Members appear not to be added to sites, but no error shown in UI
- Files:
Sharepoint_ToolBox.ps1lines 1222-1225, 5914, 5922 (try-catch with SilentlyContinue) - Trigger: User exists but cannot be added to group (permissions, licensing, or source-specific SP group issues)
- Workaround: Manual group membership assignment
- Fix approach: Replace SilentlyContinue with explicit logging of why Add-PnPGroupMember failed
Folder Metadata Loss in Template Application:
- Symptoms: Folder permissions captured correctly but not reapplied when permissions=true but structure already exists
- Files:
Sharepoint_ToolBox.ps1lines 1229-1292 (folder-level permission application depends on library structure map being built first) - Trigger: Target library created by Apply-FolderTree but permissions application logic expects library to already exist in template structure
- Workaround: Delete and recreate target library, or manually apply permissions via SharePoint UI
- Fix approach: Build library map before applying folder tree, or add validation that all referenced libraries exist
CSV Import for Bulk Operations Not Validated:
- Symptoms: Invalid CSV format silently fails, users see no clear error, form appears unresponsive
- Files:
Sharepoint_ToolBox.ps1lines 5765-5800 (CSV parsing with inadequate error context) - Trigger: CSV with missing headers, wrong delimiter, or invalid format
- Workaround: Edit CSV manually to match expected format, restart tool
- Fix approach: Add CSV schema validation before processing, show specific validation errors
Security Considerations
Client ID and Tenant URL Hardcoded in Temp Files:
- Risk: Temp registration script contains unencrypted Client ID and Tenant ID in plaintext
- Files:
Sharepoint_ToolBox.ps1lines 4210-4245 (temp file creation) - Current mitigation: Temp file cleanup attempted but not guaranteed if process crashes
- Recommendations: Use SecureString to pass credentials, delete temp file with -Force in finally block, or use named pipes instead of files
No Validation of Tenant URL Format:
- Risk: Arbitrary URLs accepted, could be typos leading to authentication against wrong tenant
- Files:
Sharepoint_ToolBox.ps1lines 4306-4317, 30-43 (Validate-Inputs) - Current mitigation: URL used as-is, relies on PnP authentication failure to catch issues
- Recommendations: Add regex validation for SharePoint tenant URLs, warn on suspicious patterns
Profile File Contains Credentials in Plaintext:
- Risk:
Sharepoint_Export_profiles.jsoncontains Client ID and Tenant URL in plaintext on disk - Files:
Sharepoint_ToolBox.ps1lines 50-72 (profile persistence) - Current mitigation: File located in user home directory (Windows ACL protection), but still plaintext
- Recommendations: Consider encrypting profile file with DPAPI, or move to Windows Credential Manager
PnP PowerShell Module Trust Not Validated:
- Risk: Module imported without version pinning, could load compromised version
- Files:
Sharepoint_ToolBox.ps1lines 151, 1151, 4218, 4521, 5833 (Import-Module PnP.PowerShell) - Current mitigation: None
- Recommendations: Pin module version in manifest, use
-MinimumVersionparameter, check module signature
Performance Bottlenecks
Synchronous UI Freezes During Large Operations:
- Problem: File search with 50,000 result limit processes all results at once, building HTML string in memory
- Files:
Sharepoint_ToolBox.ps1lines 2112-2133 (Export-SearchResultsToHTML builds entire table in string) - Cause: All results concatenated into single
$rowsstring before sending to UI - Improvement path: Implement pagination in HTML reports, stream results rather than buffering all in memory. For large datasets, chunk exports into multiple files.
Folder Storage Recursion Not Depth-Limited by Default:
- Problem:
Collect-FolderStoragerecurses unlimited depth unless explicitly capped, can take hours on deep folder structures - Files:
Sharepoint_ToolBox.ps1lines 2009-2032, 4432-4455 - Cause: CurrentDepth compared against FolderDepth limit, but FolderDepth defaults to 999 if not set
- Improvement path: Default to depth 3-4, show estimated scan time based on depth, implement cancellation token
No Parallel Processing for Multiple Sites:
- Problem: Sites processed sequentially in Permissions/Storage reports, one site blocks all others
- Files:
Sharepoint_ToolBox.ps1lines 4379-4401 (foreach loop in permissions scan) - Cause: Single-threaded approach with
Connect-PnPOnlinecontext switches - Improvement path: Queue-based processing for multiple sites (partially done for storage scans), implement async context management
HTML Report Generation for Large Duplicates List:
- Problem: Export-DuplicatesToHTML builds entire HTML in memory, slow for 10,000+ duplicates
- Files:
Sharepoint_ToolBox.ps1lines 2235-2400 (HTML string concatenation in loop) - Cause: All groups converted to HTML before writing to file
- Improvement path: Stream HTML generation, write to file incrementally, implement lazy-loading tables in browser
Fragile Areas
Language System (T() function):
- Files:
Sharepoint_ToolBox.ps1(translation lookups throughout, ~15 hardcoded English fallbacks like "Veuillez renseigner") - Why fragile: Language loading can fail silently, UI control updates hardcoded at multiple locations, no fallback chain for missing translations
- Safe modification: Add validation that all UI strings have corresponding translation keys before form creation. Create helper function that returns English default if key missing.
- Test coverage: No tests for translation system. Gaps: Missing translations for error messages, hardcoded "Veuillez renseigner" strings that bypass T() function
Profile Management:
- Files:
Sharepoint_ToolBox.ps1lines 50-127 - Why fragile: Profile list is in-memory array that syncs with JSON file. If Save-Profiles fails, changes are lost. No transaction semantics.
- Safe modification: Implement write-lock pattern. Create backup before write. Validate JSON before replacing file.
- Test coverage: No validation that profile save actually persists. Race condition if opened in multiple instances.
Runspace State Machine:
- Files:
Sharepoint_ToolBox.ps1lines 1034-1095, 4580-4650 (runspace creation, async timer polling) - Why fragile: UI state (
btnGenPerms.Enabled = false) set before runspace begins, but no explicit state reset if runspace crashes or hangs - Safe modification: Implement state enum (Idle, Running, Done, Error). Always reset state in finally block. Set timeout on runspace execution.
- Test coverage: No timeout tests. Gaps: What happens if runspace hangs indefinitely? Button remains disabled forever.
Site Picker List View:
- Files:
Sharepoint_ToolBox.ps1lines 157-250 (_Pkl-* functions) - Why fragile: AllSites list updates while UI may be reading it (SuppressCheck flag used but incomplete synchronization)
- Safe modification: Use proper locking or rebuild entire list atomically. Current approach relies on flag which may miss updates.
- Test coverage: No concurrent access tests. Gaps: What if site is checked while sort is happening?
Scaling Limits
Permissions Report HTML with Large Item Counts:
- Current capacity: Tested up to ~5,000 items, performance degrades significantly
- Limit: HTML table becomes unusable in browser above 10,000 rows (sorting, filtering slow)
- Scaling path: Implement client-side virtual scrolling in HTML template, paginate into multiple reports, add server-side filtering before export
File Search Result Limit:
- Current capacity: 50,000 result maximum hardcoded
- Limit: Beyond 50,000 files, results truncated without warning
- Scaling path: Implement pagination in SharePoint Search API, show "more results available" warning, allow user to refine search
Runspace Queue Processing:
- Current capacity: Single queue per scan, sequential processing
- Limit: If background job produces messages faster than timer dequeues, queue could grow unbounded
- Scaling path: Implement back-pressure (slow producer if queue > 1000 items), implement priority queue
Profile JSON File Size:
- Current capacity: Profiles loaded entirely into memory, no limit on file size
- Limit: If user creates 1,000+ profiles, JSON file becomes slow to load/save
- Scaling path: Implement profile paging, index file by profile name, lazy-load profile details
Dependencies at Risk
PnP.PowerShell Module Version Mismatch:
- Risk: Module API changes between major versions, cmdlet parameter changes
- Impact: Features relying on specific cmdlet parameters break silently
- Migration plan: Pin to stable version range in script header. Create version compatibility matrix. Test against 2-3 stable versions.
System.Windows.Forms Dependency:
- Risk: WinForms support in PowerShell 7 is deprecated, future versions may not ship it
- Impact: GUI completely broken on future PowerShell versions
- Migration plan: Consider migrating to WPF or cross-platform GUI framework (Avalonia). Current WinForms code is tied to Assembly loading.
Missing Critical Features
No Operation Cancellation:
- Problem: Running operations (permissions scan, storage metrics, file search) cannot be stopped mid-execution
- Blocks: User stuck waiting for slow operations to complete, no way to abort except kill process
No Audit Log:
- Problem: No record of who ran what operation, what results were exported, when last backup occurred
- Blocks: Compliance, troubleshooting
No Dry-Run for Most Operations:
- Problem: Only version cleanup has dry-run. Permission changes, site creation applied immediately without preview
- Blocks: Prevents risk assessment before making changes
Test Coverage Gaps
PnP Connection Failures:
- What's not tested: Connection timeouts, intermittent network issues, authentication failures mid-operation
- Files:
Sharepoint_ToolBox.ps1lines 36, 157, 170, 2036, 4458, etc. (Connect-PnPOnline calls) - Risk: Tool may hang indefinitely if connection drops. No retry logic.
- Priority: High
Malformed JSON Resilience:
- What's not tested: Templates.json, Profiles.json, Settings.json with invalid JSON, missing fields, type mismatches
- Files:
Sharepoint_ToolBox.ps1lines 61, 140, 568 (ConvertFrom-Json) - Risk: Tool fails to start or loses user data
- Priority: High
Large-Scale Operations:
- What's not tested: Permissions scan on site with 50,000+ items, storage metrics on 10,000+ folders, file search returning 40,000+ results
- Files: Bulk scanning functions throughout
- Risk: Memory exhaustion, timeout, UI freeze
- Priority: Medium
Runspace Cleanup on Error:
- What's not tested: Runspace exception handling, cleanup if UI window closes during background operation
- Files:
Sharepoint_ToolBox.ps1lines 1040-1052, 4564-4577, 5556-5577 - Risk: Zombie processes, resource leaks
- Priority: Medium
CSV Format Validation:
- What's not tested: Invalid column headers, wrong delimiter, missing required columns in bulk operations
- Files:
Sharepoint_ToolBox.ps1lines 5765-5800 - Risk: Silent failures, partial data import
- Priority: Medium
Concerns audit: 2026-04-02