BitLocker enable + inventory rewrite with recovery key automation#64
BitLocker enable + inventory rewrite with recovery key automation#64Gumbees wants to merge 15 commits into
Conversation
Added comprehensive improvements to ensure successful automated upgrades when running under SYSTEM user via RMM platforms. Improvements: - Pre-flight checks: disk space validation (20GB minimum), pending reboot detection, and temp file cleanup - Enhanced setup.exe arguments for full automation: - /DynamicUpdate Disable (prevents mid-upgrade download hangs) - /Compat IgnoreWarning (bypasses compatibility warnings) - /ShowOOBE None (skips post-upgrade OOBE screens) - /quiet (minimizes UI interactions) - Process confirmation: waits 10 seconds after launch to verify setup.exe is running successfully before script exits - Better error handling with specific exit codes and progress reporting - Hidden window mode for cleaner background execution These changes address common failure points in automated Windows upgrades, particularly when executed remotely without user interaction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Focused the diagnostics script to only analyze the most relevant log file for in-progress Windows upgrades: C:\$Windows.~BT\Sources\Panther\setuperr.log Changes: - Removed C:\Windows\Panther\ log locations (post-upgrade logs) - Removed setupact.log checks (less relevant for error diagnosis) - Now only checks C:\$Windows.~BT\Sources\Panther\setuperr.log - Updated messages to reflect single log file focus - Clarified that this log appears during the upgrade process This simplification reduces noise and focuses AI analysis on the primary error log created during active Windows upgrade attempts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the diagnostics script to collect and analyze XML compatibility scan results along with the setup error log. New files collected from C:\$Windows.~BT\Sources\Panther\: - ScanResult.xml (compatibility scan summary) - CompatData_*.xml (detailed hardware/software compatibility data) Benefits: - AI can now identify specific hardware/software blocking the upgrade - More accurate diagnosis of compatibility issues - Better recommended actions based on specific blockers - Comprehensive analysis combining error logs and compatibility data Updated AI prompt to analyze XML compatibility elements and provide specific remediation steps for identified compatibility blockers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Added functionality to detect and enable Secure Boot on Dell systems booted in UEFI mode (required for Windows 11 upgrades). New Features: - New variable $enableSecureBoot (default: 0, opt-in) - Test-UefiBootMode function detects UEFI vs Legacy BIOS boot: - Checks firmware_type environment variable - Detects EFI system partition (GPT type) - Checks SecureBoot registry keys - Set-SecureBoot function enables Secure Boot only on UEFI systems: - Verifies UEFI boot mode before attempting configuration - Sets SecureBoot=Enabled via CCTK - Ensures BootMode=Uefi is set - Warns user that reboot is required Safety Features: - Automatically skips Secure Boot on Legacy BIOS systems - Multiple detection methods ensure accurate boot mode identification - Default disabled (opt-in) to prevent accidental enablement Usage in RMM: Set $enableSecureBoot = 1 to enable Secure Boot on UEFI systems 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Created diagnostic script to identify duplicate ProfileImagePath entries in Windows ProfileList registry which can cause profile corruption and login failures. Features: - Scans HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList - Identifies all user profile SIDs - Detects duplicate ProfileImagePath values (multiple SIDs → same path) - Reports detailed information for each duplicate: - Profile path - All associated SIDs - Registry key paths - Profile state (Normal, Mandatory, Backup, etc.) - Load history - Provides remediation recommendations Common Issues Detected: - Failed domain migrations creating duplicate profiles - Profile corruption during Windows upgrades - .bak profile conflicts - SID mismatches after account changes Output Format: - Lists each duplicate path with all associated SIDs - Shows registry paths for manual remediation - Exit code 0 if no duplicates (healthy system) Usage: Run interactively or via RMM to scan for profile issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the duplicate profile detection script with optional automatic remediation capability to delete the oldest duplicate profile entry. New Feature: - $deleteOldest parameter (default: 0, opt-in) - When enabled, automatically deletes the oldest duplicate for each path - Determines "oldest" by LocalProfileLoadTime timestamp - Profiles never loaded are considered oldest Safety Features: - Creates .reg backup file before deletion in %TEMP% - Backup filename includes SID and timestamp - Only deletes if backup succeeds - Skips deletion if backup fails (safety first) - Provides detailed logging of actions taken How It Works: 1. Detects duplicate ProfileImagePath entries 2. For each duplicate set, identifies oldest by load timestamp 3. Exports registry key to backup file 4. Deletes oldest registry entry 5. Reports deletion summary Output Changes: - Shows load timestamps for each profile - Indicates which entry will be deleted (when enabled) - Displays backup file locations - Provides post-deletion verification steps Usage: - Detection only (default): Run without parameters - Auto-delete oldest: Set $deleteOldest = 1 in RMM Exit Behavior: - Reports number of deleted entries - Lists backup file locations for rollback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Created script to remove Microsoft Print to PDF Windows optional feature which is a confirmed blocker for Windows 11 upgrades. Problem: - Microsoft Print to PDF drivers cause Windows 11 upgrade failures - Compatibility scan detects Print to PDF as incompatible - Feature must be fully disabled before upgrade attempts Features: - Detects current state of Print to PDF feature - Disables feature using Disable-WindowsOptionalFeature - Does NOT force immediate reboot (allows scheduling) - Validates feature state before and after operation - Handles DisablePending state (pending reboot) Critical Workflow: 1. Run this script to disable Print to PDF 2. **REBOOT system** (REQUIRED - drivers stay loaded until reboot) 3. Verify feature disabled (optional - run script again) 4. Run Windows 11 upgrade Why Reboot is Required: - Print to PDF drivers remain loaded in memory until reboot - Windows Setup compatibility scan checks running drivers - Feature state is "DisablePending" until reboot completes - Upgrade will fail if drivers are still detected in memory - Reboot fully removes drivers from system Safety Features: - Checks for admin elevation - Uses -NoRestart flag (allows controlled reboot timing) - Validates feature state after operation - Provides clear reboot instructions - Detects already-disabled state Output States: - Enabled → DisablePending (needs reboot) - DisablePending → Reminds user to reboot - Disabled → Confirms ready for upgrade (if rebooted) Usage in RMM: Run as automated task, then schedule reboot, then run upgrade 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Completely rewrote msft-win-bitlocker-inventory.ps1 to be significantly more user-friendly and add automatic recovery key generation functionality. Key improvements: - Auto-creates recovery passwords when BitLocker is enabled but no key exists - User-friendly output with clear status indicators (✓, ✗, →, ℹ) - Per-volume detailed status reporting (encryption %, volume status, key status) - Comprehensive summary report showing totals and actions taken - Better error handling with try/catch blocks throughout - Proper function documentation with .SYNOPSIS blocks - Cleaner code organization and removed unused commented code - Admin privilege check at script start - Tracks all actions: volumes scanned, encrypted, keys created, keys backed up - Safe to run multiple times (idempotent operation) Functions added/improved: - Test-DomainJoined: Better domain join detection with error handling - Get-VolumeEncryptionStatus: Returns detailed encryption status object - Get-RecoveryKeyStatus: Checks for existing recovery keys with count - New-RecoveryKey: Creates recovery password with success verification - Backup-RecoveryKeyToAD: Backs up keys to AD with per-key error handling - Set-BitLockerADBackupPolicy: Cleaner registry configuration with counters Output improvements: - Section headers with visual separators - Clear volume-by-volume breakdown - Summary report with statistics - RMM-ready output variables documented The script now provides enterprise-grade BitLocker management with clear visibility into what actions were taken on each volume. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced BitLocker inventory script to collect and format all recovery passwords for storage in RMM platforms. Changes: - Collects all recovery passwords (existing and newly created) in hashtable - Formats passwords as pipe-delimited string: "C: 123456-789012... | D: 234567-890123..." - Handles multiple passwords per volume with numbered keys - Outputs formatted passwords to transcript for RMM capture - Comprehensive RMM integration documentation with examples for: - NinjaRMM (with -Secure flag for sensitive data) - ConnectWise Automate (registry properties) - Datto RMM (result output format) - Security warnings about sensitive data storage - Character limit guidance (10K-50K typical RMM limits) Output variable added: - $recoveryPasswordsFormatted: All recovery passwords in RMM-ready format This enables MSPs to automatically backup recovery passwords to their RMM platform alongside Active Directory backup, providing redundant recovery options when systems need BitLocker unlock. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced BitLocker script to create and backup BOTH recovery passwords (48-digit) AND recovery keys (.BEK files) to Active Directory, while storing only passwords in RMM for quick access. Key changes: - Renamed Get-RecoveryKeyStatus → Get-RecoveryProtectorStatus - Now checks for BOTH RecoveryPassword and ExternalKey protectors - Returns separate status objects for passwords and keys - Split New-RecoveryKey into two functions: - New-RecoveryPassword: Creates 48-digit numerical passwords - New-RecoveryKey: Creates .BEK file protectors - Renamed Backup-RecoveryKeyToAD → Backup-RecoveryProtectorsToAD - Backs up BOTH passwords and keys to Active Directory - Handles each protector type separately with error handling - Updated main logic to: - Check for both passwords and keys - Create both if missing - Display separate status lines for each type - Store passwords in RMM, both types in AD Storage architecture: - Active Directory: Both passwords AND keys (complete backup) - RMM Custom Fields: Passwords only (quick access for unlock) - Transcript Log: Full details including all passwords Output improvements: - Separate status lines: "Recovery Password: EXISTS" and "Recovery Key: EXISTS" - Updated summary to show "recovery protectors" instead of "keys" - Comprehensive documentation on what's stored where and why This provides triple redundancy with proper separation: - AD has complete recovery capability (passwords + keys) - RMM has quick-access passwords for common unlock scenarios - Transcript logs have full audit trail 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Created new script to enable BitLocker encryption with TPM-based automatic unlock and comprehensive recovery protector management. Key features: - Validates TPM presence and readiness before attempting encryption - Exits gracefully if no TPM or TPM not ready (required for automatic unlock) - Enables BitLocker using TPM protector for transparent boot experience - Uses XtsAes256 encryption method (strongest available) - Automatically creates BOTH recovery passwords and recovery keys - Backs up both protector types to Active Directory (domain-joined) - Stores passwords in RMM custom fields for quick access - Configures registry for automatic AD backup on domain-joined systems TPM requirements: - TPM 1.2 or 2.0 must be present - TPM must be enabled, activated, and owned - Script validates all conditions before proceeding Storage architecture (same as inventory script): - Active Directory: Both passwords AND keys (complete backup) - RMM Custom Fields: Passwords only (quick access for unlock) - Transcript Log: Full details including all passwords Volume processing: - Scans all fixed volumes with drive letters - Skips volumes already encrypted (idempotent) - Reports separately: already encrypted vs newly encrypted - Encryption happens in background after script completes Functions include: - Test-TPMPresent: Validates TPM readiness with detailed status - Enable-BitLockerWithTPM: Enables encryption with TPM protector - New-RecoveryPassword/New-RecoveryKey: Creates both protector types - Backup-RecoveryProtectorsToAD: Backs up to AD with per-protector error handling Output variables for RMM: - VolumesEncrypted: Number of newly encrypted volumes - RecoveryProtectorsCreated: Total protectors created - RecoveryProtectorsBackedUp: Total protectors backed up to AD - recoveryPasswordsFormatted: All passwords for RMM storage Safe to run multiple times - skips already encrypted volumes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Modified script to properly handle OS and data volumes with different encryption strategies: OS Volume (Step 1): - Uses TPM protector for automatic unlock - Must complete first before data volumes Data Volumes (Step 2): - Uses password protector with random GUID - Enables BitLocker auto-unlock feature - Automatically unlocks when OS volume is unlocked Recovery Protectors (All Volumes): - Creates recovery password (48-digit) for user unlock - Creates recovery key (.BEK file) for advanced recovery - Backs up both to Active Directory (domain-joined systems) - Stores passwords in RMM custom field Technical Details: - TPM can only protect OS volumes per BitLocker limitation - Data volumes require password protector + auto-unlock - Auto-unlock depends on OS volume being encrypted first - Random GUID password ensures strong protection - All recovery data collected and stored consistently Error Fixed: "BitLocker cannot use the Trusted Platform Module (TPM) to protect a data drive. TPM protection can only be used with the operating system drive." 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed error 0x80310031 ("This key protector cannot be added. Only one
key protector of this type is allowed for this drive") that occurred
when running script on drives that already have protectors but aren't
fully encrypted yet.
Changes:
- Enhanced Get-VolumeEncryptionStatus to detect existing TPM and password protectors
- Updated Enable-BitLockerWithTPM to check for existing TPM protector before adding
- Updated Enable-BitLockerWithAutoUnlock to check for existing password protector
- Added detection for volumes with encryption IN PROGRESS (has protectors but not fully enabled)
- Script now properly handles re-running on partially encrypted systems
- Added Resume-BitLocker calls to continue encryption if paused
Error Handling:
- Detects and gracefully handles existing TPM protectors on OS volumes
- Detects and gracefully handles existing password protectors on data volumes
- Continues encryption process if already started but not complete
- Enables auto-unlock on data volumes even if already configured
Fixed Drives Only:
- Script processes only DriveType 'Fixed' (internal drives)
- Does NOT process removable drives (USB, external drives)
- Does NOT use BitLocker To Go
- Focuses on TPM-based encryption for fixed internal drives only
This makes the script idempotent and safe to re-run during active encryption.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issues with partial enablement scenarios and RMM logging: Recovery Protector Management: - Check for existing recovery passwords before creating new ones - Check for existing recovery keys before creating new ones - Only create recovery protectors if they're missing - Report count of existing protectors when found - Prevents duplicate recovery protectors on repeated runs - Truly idempotent for partial enablement scenarios RMM Path Logic Fix: - Fixed backwards logic for $RMMScriptPath check - Changed: if ($null -eq $RMMScriptPath) to if ($null -ne $RMMScriptPath) - Prevents log path from becoming "\logs\..." without drive letter - Ensures proper C:\Windows\logs\ fallback when RMM path not available Before this fix: - Script created new recovery passwords/keys every time it ran - Multiple recovery protectors accumulated on each run - Log path could be malformed in RMM execution After this fix: - Script checks for existing recovery protectors first - Only creates protectors if missing - Reports existing protectors with count - Proper log path in all execution modes - Safe to run multiple times during partial enablement Example output: "ℹ Recovery password already exists (2 found)" "ℹ Recovery key already exists (1 found)" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.
Once credits are available, push a new commit or reopen this pull request to trigger a review.
|
Superseded by DTC-Inc/ninja-one-automation#9, which ports this BitLocker recovery-key automation into the Note: the existing BitLocker scripts here stay in place for now (the #105 refactor still applies); they'll be retired once the new security/ set is validated in production. |
Summary
Major rewrite and hardening of BitLocker tooling. Adds a full enablement script with TPM and recovery protector support, generates both recovery passwords and
.BEKrecovery key files, stores them back to the RMM, and makes the enablement workflow idempotent for in-progress encryption and data-volume auto-unlock scenarios. The inventory script is rewritten alongside for parity.Files touched (BitLocker-specific):
msft-windows/msft-win-bitlocker-inventory.ps1... rewrite with auto recovery key creationmsft-windows/msft-windows-enable-bitlocker.ps1... new full enablement script (TPM + recovery protectors, idempotent, handles in-progress + data volumes)Overlap with PR #62
This branch also carries the 7 Win11 upgrade automation commits from
problem/win11-upgrade-automation(PR #62) ... they share lineage. If PR #62 merges first, the duplicate commits will dedupe naturally on the next rebase here. Reviewer can also fold by merging PR #62 first and rebasing this branch.Test plan
msft-windows-enable-bitlocker.ps1on a test endpoint with TPM and confirm BitLocker is enabled with both a recovery password and a.BEKfile..BEKare stored in the configured RMM custom fields.msft-win-bitlocker-inventory.ps1and confirm inventory output matches enablement state.-Secureflag.Lineage
Renamed from
feature/bitlocker-inventory-improvementstoenhancement/bitlocker-inventory-improvementsper CLAUDE.md change taxonomy. Was 16 commits behindmain; rebased onto currentmainbefore opening this PR. Part of the stale-branch reconciliation sweep.