Skip to content

v0.3 module migration and issue fixes#61

Draft
ugurkocde wants to merge 11 commits into
mainfrom
feature/v0.3
Draft

v0.3 module migration and issue fixes#61
ugurkocde wants to merge 11 commits into
mainfrom
feature/v0.3

Conversation

@ugurkocde

Copy link
Copy Markdown
Owner

Summary

This PR prepares the v0.3 release with a full PowerShell module migration and the current issue-fix pass.

Major changes:

  • Converts the project from a single large script into a module package with DeviceOffboardingManager.psd1, DeviceOffboardingManager.psm1, Public/, Private/, UI/, and bundled Playbooks/.
  • Keeps DeviceOffboardingManager.ps1 as a compatibility launcher.
  • Exports Start-DeviceOffboardingManager as the module entrypoint.
  • Adds module/package validation scripts and a Windows-only WPF smoke test.
  • Hardens device identity correlation for search and offboarding to avoid wrong-device operations.
  • Adds device-code authentication, Autopilot group tag management, local playbooks, Graph ID exports, and safer audit logging.

Issues closed on merge

Closes #3
Closes #9
Closes #11
Closes #13
Closes #21
Closes #33
Closes #35
Closes #37
Closes #40
Closes #41
Closes #47
Closes #49
Closes #50
Closes #52
Closes #54
Closes #55
Closes #56
Closes #58
Closes #59

Related but not auto-closing

These are intentionally referenced without closing keywords because they either need Windows/tenant validation or separate product work:

Relates to #14
Relates to #15
Relates to #17
Relates to #38
Relates to #46
Relates to #53
Relates to #60

Validation

  • pwsh -NoProfile -Command './tests/Verify-Module.ps1 | Format-List'
  • git diff --cached --check
  • Module import by manifest path
  • Module import by name from temporary PSModulePath
  • Compatibility launcher validation
  • XAML FindName(...) binding validation
  • Bundled playbook count validation

Note: this was validated on macOS, so the WPF UI live launch cannot be completed here. The non-Windows guard is verified. Run ./tests/Verify-WindowsUi.ps1 on Windows PowerShell 7 before marking the PR ready.

ugurkocde and others added 11 commits March 13, 2026 19:39
- Fix Autopilot property typo: lastContactDateTime -> lastContactedDateTime
- Fix BitLocker key retrieval array bug: access first element explicitly
- Clear stale parsedDevices on bulk import cancel
- Fix status string corruption from $deviceSuccess++ inside PSCustomObject
- Fix permission scopes: Device.ReadWrite.All, add BitlockerKey.Read.All
- Fix export functions to use actual DeviceObject class properties
- Load playbooks from local Playbooks/ directory instead of remote GitHub URLs
- Generate playbook result columns dynamically from actual output schema

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Invoke-GraphRequestWithRetry wrapper for 429 throttling (reads
  Retry-After header), 5xx transient errors (exponential backoff), and
  network-level failures
- Add Invoke-GraphBatchRequest helper that auto-chunks up to 20
  sub-requests per POST /$batch with sub-request retry logic
- Update Get-GraphPagedResults to use retry wrapper and accept optional
  Headers parameter
- Migrate all v1.0 endpoints to beta with $select across main script
  and Playbooks 1-5 to reduce API payload size
- Rewrite dashboard statistics to use $count batch (1 API call replaces
  3 full-collection fetches + client-side counting), with automatic
  fallback to full-fetch for tenants without $count support
- Batch Entra+Intune search queries for device name lookups and
  Intune+Autopilot queries for serial number lookups
- Hoist Autopilot full-collection fetch out of per-search-term loop
- Batch per-device offboarding operations (Entra+Intune+Autopilot)
  into single $batch call per device
- Add bulk Autopilot deletion via deleteDevices endpoint using serial
  numbers when 2+ devices selected, with individual deletion fallback
  and per-device status parsing from API response
…m filtering, grid filtering, HTML reports

- Add saved authentication config (#48): Save/auto-load cert and secret
  configs to %LocalAppData%/DeviceOffboardingManager. Client secret is
  never persisted for security.
- Add co-management awareness: ManagementAgent property on DeviceObject,
  amber warning banner in confirmation dialog for co-managed devices.
- Add platform filtering on dashboard (#40): ComboBox to filter all
  dashboard statistics by OS platform.
- Add grid filtering and shift-click range selection (#33): Filter
  TextBoxes above DataGrid for live column filtering, shift-click on
  checkboxes to toggle ranges.
- Add HTML offboarding report generation: Export-OffboardingReport
  function with professional styled HTML, per-device service status,
  summary stats. Export buttons in summary and dashboard dialogs.
- Update homepage to show Defender for Endpoint as supported (no longer
  "Soon").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…polation

- Add fallback from EntraDeviceObjectId to intuneDevice.azureADDeviceId for
  LAPS lookup (mirrors BitLocker fallback pattern)
- Fix PowerShell string interpolation in LAPS URI using $() syntax
- Add diagnostic logging for LAPS device ID resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ybooks, confirmation dialog

- Standardize CornerRadius to 6, fix dashboard subtitle contrast
- Fix DataGrid column widths, add tooltips and hover states
- Restructure sidebar: connect/tenant at top, nav center, utils bottom
- Add ConnectionStatusDot indicator (red/green)
- Redesign home page: slim preview banner, Get Started card, quick nav buttons
- Add dashboard page header with refresh button
- Fix hardcoded stale device progress bars with dynamic calculation
- Add device management page header, search placeholder, result count
- Fix dropdown labels (Device Name, Serial Number)
- Add filter toggle, clear search, conditional offboard panel with selection count
- Categorize playbook cards into Device Compliance, Inventory, Health sections
- Make playbook cards responsive (MinWidth/MaxWidth)
- Move confirmation warning to top, add type-to-confirm safeguard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… sidebar, and page-by-page polish

Toast notifications:
- Inline toast overlay replaces ~33 blocking MessageBox popups in main window
- Slide-in/out animation with generation counter to prevent stale callbacks
- Auto-dismiss with configurable duration, manual dismiss via X button or Escape
- Color-coded: green (success), red (error), blue (info)

Keyboard shortcuts:
- Ctrl+K: navigate to Device Offboarding and focus search
- Ctrl+B: toggle sidebar collapse/expand
- F5: refresh dashboard (when on Dashboard page)
- Escape: contextual dismiss (toast > filter row > clear search)
- Enter: search (in search box), connect (auth dialog), confirm (OS picker)
- IsCancel on all modal Close/Cancel buttons for universal Escape-to-close

Collapsible sidebar:
- Toggle button with collapse to 48px rail
- Connection status dot remains visible when collapsed
- Synced at all connection state change points

Search UX:
- Search button shows "Searching..." with wait cursor during operation
- Dynamic placeholder text updates when search mode dropdown changes
- Empty state message shown before first search
- Clear button returns focus to search input
- DataGrid visibility toggled with empty state

Home page:
- Specific subtitle about offboarding workflow
- Ellipse dot bullets replacing ASCII dashes
- Feature list rewritten (offboarding, CSV import, stale reporting, key backup)
- Full Microsoft service names
- Card backgrounds unified to 2 tones
- Get Started card updates dynamically on connection (green button, new text)
- Quick nav tooltips show "(connect first)" when disabled, Ctrl+K hint
- Auto-navigate to Dashboard when already connected on launch

Dashboard page:
- ScrollViewer wrapper for small windows
- "Last refreshed" timestamp in header
- All counts show "--" before data loads (not "0")
- Specific subtitles: "Managed by Intune", "Registered in Autopilot", etc.
- Stale cards: "Not synced in 30/90/180+ days"
- Tooltips on all clickable stat cards
- Refresh button loading state with F5 shortcut
- "EntraID" corrected to "Entra ID"

Device Management page:
- Search/Clear button tooltips with keyboard hints
- Filter row columns aligned to DataGrid widths
- Filter boxes have tooltips
- "OS" column header expanded to "Operating System"
- "View" groups link gets tooltip
- "Offboard device(s)" simplified to "Offboard Devices"
- Empty state TextBlock before first search

Playbooks page:
- Specific subtitle about compliance, inventory, security audits
- "Device Compliance" renamed to "Enrollment Discrepancies"
- Hover effect on playbook cards
- Back/Export buttons get cursor and tooltips
- Results header includes device count
- Results DataGrid column widths proportional

Auth dialog:
- Window title matches header text
- Concise subtitle without "API"
- "Interactive Login (Browser)" instead of "(Admin User)"
- IsDefault on Connect, IsCancel on Cancel
- Cursor and tooltips on Save/Import buttons
- "Save Config" renamed to "Save Locally"
- Auto-selects previously used auth method

Bulk Import dialog:
- "File Template" instead of "CSV Template"
- "Save Template" instead of "Download Template"
- Instructive placeholder text
- IsCancel on Cancel button
- Tooltips on all buttons
- Full file path as tooltip on file path TextBox

Confirmation dialog:
- Warning text covers both delete and disable actions
- Dynamic subtitle with device count
- IsCancel on Cancel, Cursor on Confirm
- Type-to-confirm TextBox turns green on match
- Copy Key button gets tooltip

Offboarding Summary dialog:
- Dynamic timestamp subtitle
- Clean status labels without ASCII art prefixes
- "Defender" instead of "MDE" column label
- IsCancel + Cursor on Close, tooltip on Export Report

All remaining modals:
- IsCancel="True" on every Close/Cancel button (10 total)
- Cursor="Hand" on every interactive button (42 total)
- MenuButtonStyle gets Cursor="Hand"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment