Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/publish-module.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Publish PowerShell Module

on:
workflow_dispatch:

jobs:
Publish-Module:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install manifest dependencies
shell: pwsh
run: |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
# Publish-Module runs Test-ModuleManifest, which validates the RequiredModules
# entry. Microsoft.Graph.Authentication must be present or publishing fails with
# "The specified RequiredModules entry ... is invalid".
Install-Module Microsoft.Graph.Authentication -Scope CurrentUser -Force -AllowClobber

- name: Publish to PowerShell Gallery
shell: pwsh
run: |
Publish-Module -Path ./DeviceOffboardingManager -Repository PSGallery -NuGetApiKey "${{ secrets.NUGET_KEY }}"

- name: Add Gallery Link to Summary
shell: pwsh
run: |
$manifest = Import-PowerShellDataFile ./DeviceOffboardingManager/DeviceOffboardingManager.psd1
$version = $manifest.ModuleVersion
"Successfully published [DeviceOffboardingManager version $version](https://www.powershellgallery.com/packages/DeviceOffboardingManager/$version) to PowerShell Gallery." | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append
"View the package at: https://www.powershellgallery.com/packages/DeviceOffboardingManager/$version" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append
24 changes: 0 additions & 24 deletions .github/workflows/publish-script.yml

This file was deleted.

51 changes: 51 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
## Version 0.3 - Unreleased

### Bug Fixes
- **Fixed 8 Critical Bugs** across device offboarding and playbook execution
- Fixed Autopilot property typo (`lastContactDateTime` -> `lastContactedDateTime`)
- Fixed BitLocker key retrieval array bug: access first element explicitly
- Fixed stale `parsedDevices` not clearing on bulk import cancel
- Fixed status string corruption from counter increment inside PSCustomObject
- Fixed permission scopes: `Device.ReadWrite.All`, added `BitlockerKey.Read.All`
- Fixed export functions to use actual DeviceObject class properties
- Fixed playbook result columns to generate dynamically from actual output schema
- **Full PowerShell Module Migration**: The project now ships as a module with a manifest, exported `Start-DeviceOffboardingManager` command, split private/public source files, XAML resources, bundled playbooks, and a compatibility `DeviceOffboardingManager.ps1` launcher.
- **Module Verification Tests**: Added repository checks for parser health, manifest/import behavior, packaged module import, compatibility launcher validation, XAML control bindings, bundled playbooks, and a Windows-only WPF smoke test.
- **Local Playbook Execution**: Playbooks now load from the module's bundled `Playbooks/` directory instead of downloading from GitHub URLs at runtime
- **Hardened Device Identity Correlation**: Search and offboarding now prefer Graph object IDs, Entra `deviceId`, Intune `azureADDeviceId`, and exact serial matches before any name-only fallback. Ambiguous duplicate matches are skipped with warnings to reduce wrong-device deletion risk.
- **Improved Empty Autopilot DisplayName Handling**: Autopilot device-name matching now avoids server-side displayName filters and supports client-side serial matching for devices with blank Autopilot display names.
- **Safer Audit Trail**: Confirmation preview now shows full Entra, Intune, and Autopilot IDs; CSV exports include Graph IDs; recovery keys and LAPS values are written to the timestamped audit log with a `SENSITIVE` prefix.
- **Authentication Fallback**: Added Device Code login to avoid browser localhost redirect / WAM issues with interactive Microsoft Graph authentication.
- **Fixed Serial Number & Partial Search Not Returning Intune Devices**: Intune `managedDevices` only supports `eq` on `serialNumber` (not `contains`/`startswith`), and combining `contains(deviceName,…)` with `contains(serialNumber,…)` via `or` made the entire query return zero rows. Serial Number search now uses exact `serialNumber eq`, and partial "Contains" search filters on `deviceName`, so Intune devices are correctly returned again (verified against a live tenant).
- **Dashboard Card Loading Feedback**: Clicking a dashboard statistic card now shows an immediate loading indicator (wait cursor + toast) before the device list is fetched, instead of the window appearing to freeze.

### Graph API Performance and Reliability
- **Retry Logic with Backoff**: New `Invoke-GraphRequestWithRetry` wrapper handles 429 throttling (reads Retry-After header), 5xx transient errors (exponential backoff), and network failures
- **Batch Requests**: New `Invoke-GraphBatchRequest` helper auto-chunks up to 20 sub-requests per `$batch` call with sub-request retry logic
- Search queries batch Entra+Intune (device name) and Intune+Autopilot (serial number) lookups
- Per-device offboarding batches Entra+Intune+Autopilot operations into a single `$batch` call
- **Dashboard Statistics via `$count`**: Single `$batch` call with `$count` sub-requests replaces 3 full-collection fetches and client-side counting, with automatic fallback for tenants without `$count` support
- **Bulk Autopilot Deletion**: Uses `deleteDevices` bulk endpoint when 2+ devices are selected, with individual deletion fallback
- **Migrated All Endpoints to Beta**: All v1.0 Graph API references replaced with beta across the main script and all playbooks
- **Added `$select` to All GET Calls**: Every GET endpoint now specifies only the properties used downstream, reducing API payload size

### New Features
- **Saved Authentication Config** (Issue #48): Save and auto-load certificate and client secret configurations to `%LocalAppData%/DeviceOffboardingManager`. Client secret is never persisted for security.
- **Co-Management Awareness**: Displays `ManagementAgent` property on devices and shows an amber warning banner in the confirmation dialog for co-managed devices
- **Platform Filtering on Dashboard** (Issue #40): ComboBox to filter all dashboard statistics by OS platform
- **Grid Filtering and Shift-Click Range Selection** (Issue #33): Filter TextBoxes above the DataGrid for live column filtering, shift-click on checkboxes to toggle device ranges
- **HTML Offboarding Report Generation**: Professional styled HTML reports with per-device service status and summary statistics, accessible via export buttons in summary and dashboard dialogs
- **Defender for Endpoint**: Now shown as a supported service on the homepage (no longer marked as "Soon"). Defender offboarding is optional and disabled by default; admins can enable it from Prerequisites to show the Defender target and request Defender API tokens only when used.
- **Autopilot Group Tag Management** (Issue #21): Set or clear the Autopilot group tag for selected devices from the device management results grid.

### New Playbooks
- **Playbook 6: OS-Specific Devices** -- Filter and list managed devices by operating system
- **Playbook 7: Outdated OS Devices** -- Identify devices running outdated OS versions
- **Playbook 8: End-of-Life OS Devices** -- Detect devices running end-of-life OS versions
- **Playbook 9: BitLocker Key Report** -- Retrieve BitLocker recovery key metadata for Windows devices
- **Playbook 10: FileVault Key Report** -- Check FileVault key availability for macOS devices
- **Playbook 11: Corporate Identifier Stale Report** -- List imported corporate device identifiers with enrollment state and last contact status
- **Shared Playbook Helpers**: Extracted common utility functions (`Get-GraphPagedResults`, `ConvertTo-SafeDateTime`, etc.) into `PlaybookHelpers.ps1` to reduce duplication across playbooks

---

## Version 0.2.2 - 7/26/2025

- **Fixed Autopilot Device Removal by Serial Number**: Enhanced offboarding process to properly retrieve and use serial numbers for Autopilot device removal (Issue #45)
Expand Down
Loading