Skip to content

feat: Modernized 2026 Edition — PowerShell 7.4 WPF Module (v1.3.0)#8

Open
dutch2005 wants to merge 4 commits intolazywinadmin:masterfrom
dutch2005:modernize/v1.3.0-psmodule
Open

feat: Modernized 2026 Edition — PowerShell 7.4 WPF Module (v1.3.0)#8
dutch2005 wants to merge 4 commits intolazywinadmin:masterfrom
dutch2005:modernize/v1.3.0-psmodule

Conversation

@dutch2005
Copy link
Copy Markdown

@dutch2005 dutch2005 commented Apr 10, 2026

Summary

A complete rewrite of LazyWinAdmin as a native PowerShell 7.4+ WPF module, preserving the original 2012 source files in LazyWinAdmin/ and Sources/ directories untouched.

The new module (LazyWinAdminModule/) provides the same on-premises capabilities as the original — services, software inventory, hardware, network, registry, RDP toggle, Active Directory — plus cloud integration (Entra ID, Intune, Exchange Online, Azure Resource Graph), a Device Compliance tab, and a full Pester v5 test suite.


Why this rewrite?

2012 original 2026 edition
PowerShell 2.0, WinForms (SAPIEN) 7.4+, native WPF module
UI threading Synchronous — UI freezes during operations Async via Start-ThreadJob + ConcurrentQueue + DispatcherTimer
Cloud None Entra ID, Intune, Exchange Online, Azure
CIM / WMI Get-WmiObject, Win32_Product (triggers MSI repair) Get-CimInstance, StdRegProv registry enumeration
Tests None 228 Pester v5 tests, 0 failures
Admin No elevation detection Status bar indicator + Restart as Admin

Files changed

LazyWinAdminModule/              ← NEW (entire directory)
├── LazyWinAdminModule.psd1      Module manifest (v1.3.0, requires PS 7.4+)
├── LazyWinAdminModule.psm1      Root module — auto-loads all Private/Public/UI/Classes
├── Classes/
│   └── ApplicationState.ps1    Shared state: SyncHash, RunspacePool, UIQueue (ConcurrentQueue)
├── Private/                    24 private functions (documented, all mockable)
│   ├── Connect-ExchangeSession.ps1
│   ├── Connect-ModernCloud.ps1
│   ├── Get-AzureResourceSummary.ps1
│   ├── Get-ComputerADInfo.ps1
│   ├── Get-ComputerHardware.ps1
│   ├── Get-ComputerLocalGroup.ps1
│   ├── Get-ComputerLocalUser.ps1
│   ├── Get-ComputerMotherboard.ps1
│   ├── Get-ComputerNetwork.ps1
│   ├── Get-ComputerRegistryValue.ps1
│   ├── Get-ComputerService.ps1
│   ├── Get-ComputerSoftware.ps1
│   ├── Get-ComputerUptime.ps1
│   ├── Get-DeviceComplianceStatus.ps1
│   ├── Get-EntraIdentity.ps1
│   ├── Get-ExchangeMailboxPermission.ps1
│   ├── Get-IntuneDevice.ps1
│   ├── Get-IntuneManagementScript.ps1
│   ├── Invoke-ComputerRegistry.ps1
│   ├── Invoke-ComputerServiceControl.ps1   ← Start/Stop/Restart services
│   ├── Set-ComputerRDP.ps1
│   ├── Set-DeviceComplianceItem.ps1
│   ├── Set-ExchangeMailboxPermission.ps1
│   └── Test-ComputerPort.ps1
├── Public/
│   └── Start-LazyWinAdmin.ps1  Entry point — WPF window, all handlers, async dispatch
├── UI/
│   └── MainView.xaml           11-tab WPF layout
└── Tests/
    ├── Integrity.Tests.ps1     File structure, manifest, XAML validity
    ├── Functions.Tests.ps1     228 tests covering all 24 private functions
    └── Run-Tests.ps1           Test runner (auto-installs Pester 5+ if missing)
README.md                       ← UPDATED with full docs, quick start, architecture

The LazyWinAdmin/ and Sources/ legacy directories are not modified.


Key architectural decisions

Async pattern

All button handlers dispatch to Start-ThreadJob. When a job completes, a Register-ObjectEvent handler enqueues the result into a System.Collections.Concurrent.ConcurrentQueue. A DispatcherTimer (50 ms tick) drains the queue on the WPF UI thread — no Dispatcher.Invoke needed in callbacks, no cross-thread issues possible.

CIM local routing

Get-CimInstance -ComputerName localhost in PowerShell 7+ routes through WinRM (WSMan), which stalls for 30 s if WinRM is stopped and can fill the Start-ThreadJob pool (max 5 slots), freezing the UI. All 24 CIM-based functions detect a local target ($isLocal check) and omit -ComputerName entirely.

Security

  • OData $filter injection: search terms have ''' before Graph API calls
  • LDAP injection: AD filter input is validated against [^\w\s\*\@\.\-] pattern
  • No Win32_Product (triggers MSI consistency repair across all installed applications)
  • SamAccountName excluded from AD user results (PII)
  • Exchange ClientSecret stored only as SecureString, never as plain text

Quick start

# Install required modules (first time only)
Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Users, `
    Microsoft.Graph.Groups, Microsoft.Graph.DeviceManagement, `
    Az.Accounts, Az.ResourceGraph -Scope CurrentUser

# Optional: Exchange Online tab
Install-Module ExchangeOnlineManagement -Scope CurrentUser

# Launch
Import-Module .\LazyWinAdminModule\LazyWinAdminModule.psd1 -Force
Start-LazyWinAdmin

Test plan

# Run full suite (auto-installs Pester 5+ if missing)
pwsh -NoProfile -File .\LazyWinAdminModule\Tests\Run-Tests.ps1
# Expected: 228 tests, 0 failures

Manual verification:

  • Launch GUI, confirm all 11 tabs render
  • Services tab: List All Services → select a row → Start/Stop/Restart → Export CSV
  • Software Inventory: Fetch → filter by name → Export CSV
  • Hardware Inventory: requires local admin; shows model/CPU/RAM/disks
  • Registry: read SOFTWARE\Microsoft\Windows\CurrentVersion from HKLM
  • Cloud Auth tab: Sign in with Microsoft → Identity › Entra ID → Fetch Users

Wiki: Full documentation is available on the fork wiki at https://github.com/dutch2005/LazyWinAdmin_GUI/wiki

🤖 Generated with Claude Code

dutch2005 and others added 4 commits April 10, 2026 17:24
Complete rewrite of LazyWinAdmin as a native PowerShell 7.4+ WPF module.
Replaces the 2012 PowerShell 2.0 WinForms version with a full modern equivalent.

New LazyWinAdminModule includes:
- 11-tab WPF GUI: System, Services, Software, Hardware, Network, Identity,
  Governance & Compliance, Device Compliance, Exchange, Registry, Cloud Auth
- Async architecture: Start-ThreadJob + ConcurrentQueue + DispatcherTimer
- Cloud integration: Entra ID, Intune, Azure Resource Graph, Exchange Online
- Service control: Start/Stop/Restart from the Services tab
- Export to CSV on all major list views
- Admin elevation detection with Restart as Admin
- OData/LDAP injection protection
- 228 Pester v5 tests, 0 failures

See README.md for full feature list and quick start instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Launches the WPF application in a separate pwsh process, waits for the
window to appear, then iterates through all 11 tabs using simulated mouse
clicks and saves a PNG to Media\ for each one.

Uses P/Invoke (FindWindow, GetWindowRect, SetForegroundWindow,
System.Drawing.Bitmap.CopyFromScreen) and mouse_event for tab navigation.

Usage: pwsh -NoProfile -File .\Take-Screenshots.ps1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 PNG screenshots of the modernized 2026 WPF interface — one per tab:
main, System & Network, Services, Software Inventory, Hardware Inventory,
Network, Identity, Device Compliance, Exchange, Governance & Compliance,
Registry, Cloud Auth.

Take-Screenshots.ps1 uses UIAutomation (SelectionItemPattern) for
DPI-independent tab navigation and Get-Process.MainWindowHandle for
reliable WPF HWND discovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dutch2005
Copy link
Copy Markdown
Author

Hi @lazywinadmin 👋

Just wanted to give a quick update on this PR — a lot has been added since the initial submission that I think makes it much easier to review and evaluate.

What's new since the initial PR

Screenshots — the new WPF interface is now fully documented with screenshots of all 11 tabs, so you can see the modernized UI without needing to run the module:

Main view Services tab
main services
Device Compliance Cloud Auth
compliance cloud-auth

Wiki — a full wiki has been written covering everything a maintainer or contributor would need to understand the rewrite:

Test suite — 228 Pester v5 tests, 0 failures. Every private function is covered including the new service control function added in v1.3.0.

Happy to answer any questions or adjust anything to fit your preferred style for the repo. The original LazyWinAdmin/ and Sources/ directories from the 2012 version are untouched in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant