Fix unenroll Windows instructions (#47725)
- @noahtalerman: For Windows, I think we want to squeeze turning off MDM and uninstalling fleetd into one script. - Why? Because Fleet automatically turns on Windows MDM, two scripts means Fleet could beat the IT admin and turn MDM back on before they uninstall fleetd. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Windows fleetd uninstall now proactively detects and disables MDM enrollment before removal to help ensure a cleaner device unenrollment. * **Bug Fixes** * Improved uninstall error reporting by surfacing the underlying failure message and exiting with a clear non-zero code. * **Chores** * Updated fleet testing and workstation configurations: removed the Windows uninstall/MDM-related steps from QA and workstation controls, and added new Windows security/setup scripts plus additional cross-platform post-install and extension installation tasks. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Steven Palmesano <3100993+spalmesano0@users.noreply.github.com>
This commit is contained in:
co-authored by
Steven Palmesano
parent
d7800eb5c5
commit
96ca0fd967
@@ -160,12 +160,12 @@ In the Google Admin console:
|
||||
|
||||
1. Determine if your host has MDM features turned on by looking at the **MDM status** on the host's **Host details** page.
|
||||
|
||||
2. If MDM is turned on, for macOS, Windows, iOS/iPadOS, and Android hosts:
|
||||
- For macOS hosts, select **Actions > Turn off MDM** on the host's details page to turn MDM off.
|
||||
- For Windows hosts, download the [turn off MDM script](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/windows/scripts/turn-off-mdm.ps1), add it to the host's fleet on the **Scripts** page in Fleet, and run the script via **Actions > Run script** on the host's details page.
|
||||
- For iOS/iPadOS and Android hosts, select **Actions > Unenroll**.
|
||||
2. If MDM is turned on, turn it off:
|
||||
- Windows: Skip to step 3 (Uninstall Fleet's agent).
|
||||
- macOS: On the **Host details** page, select **Actions > Turn off MDM**.
|
||||
- iOS/iPadOS & Android: On the **Host details** page, select **Actions > Unenroll**.
|
||||
|
||||
3. [Uninstall fleetd](https://fleetdm.com/guides/how-to-uninstall-fleetd) for macOS, Windows, and Linux hosts.
|
||||
3. For macOS, Windows, and Linux hosts, [uninstall Fleet's agent (fleetd)](https://fleetdm.com/guides/how-to-uninstall-fleetd).
|
||||
|
||||
4. Select **Actions > Delete** to delete the host from Fleet.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ To remove fleetd from a Mac:
|
||||
|
||||
To remove fleetd from a Windows device:
|
||||
|
||||
1. Download the [Windows uninstall script](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/windows/scripts/uninstall-fleetd-windows.ps1).
|
||||
1. Download the [Windows uninstall script](https://github.com/fleetdm/fleet/blob/main/docs/solutions/windows/scripts/uninstall-fleetd-windows.ps1). This script turns off MDM and uninstalls fleetd.
|
||||
2. Open **PowerShell** as administrator (right-click and select **Run as administrator**).
|
||||
3. Navigate to where you saved the script: `cd C:\path\to\your\script`
|
||||
4. Run the script: `.\uninstall-fleetd-windows.ps1`
|
||||
@@ -41,7 +41,7 @@ To remove fleetd from a Linux device:
|
||||
|
||||
To remove fleetd from a device through Fleet:
|
||||
|
||||
1. Add the uninstall script for [macOS](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/macos/scripts/uninstall-fleetd-macos.sh), [Windows](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/windows/scripts/uninstall-fleetd-windows.ps1), or [Linux](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/linux/scripts/uninstall-fleetd-linux.sh) to Fleet as a script.
|
||||
1. Add the uninstall script for [macOS](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/macos/scripts/uninstall-fleetd-macos.sh), [Windows](https://github.com/fleetdm/fleet/blob/main/docs/solutions/windows/scripts/uninstall-fleetd-windows.ps1), or [Linux](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/linux/scripts/uninstall-fleetd-linux.sh) to Fleet as a script.
|
||||
2. Go to the device's **Host details** page.
|
||||
3. Select **Actions > Run script** and choose the uninstall script.
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ The Autopilot service may need a few minutes to sync after the device record cle
|
||||
|
||||
## Turn off Windows MDM
|
||||
|
||||
1. Turn off MDM for each host by running [this script](https://github.com/fleetdm/fleet/blob/main/it-and-security/lib/windows/scripts/turn-off-mdm.ps1) from Fleet on all your Windows hosts.
|
||||
1. Turn off MDM for each host by running [this script](https://github.com/fleetdm/fleet/blob/main/docs/solutions/windows/scripts/uninstall-fleetd-windows.ps1) from Fleet on all your Windows hosts. Note that this script will also remove fleetd from the hosts.
|
||||
|
||||
2. Head to **Settings > Integrations > MDM**.
|
||||
|
||||
|
||||
+84
-13
@@ -1,4 +1,22 @@
|
||||
# Please don't delete. This script is referenced in the guide here: https://fleetdm.com/guides/how-to-uninstall-fleetd
|
||||
# Please don't delete. This script is referenced in the guides here:
|
||||
# - https://fleetdm.com/guides/windows-mdm-setup#turn-off-windows-mdm
|
||||
# - https://fleetdm.com/guides/how-to-uninstall-fleetd
|
||||
|
||||
Add-Type -TypeDefinition @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class MdmRegistration
|
||||
{
|
||||
[DllImport("mdmregistration.dll", SetLastError = true)]
|
||||
public static extern int UnregisterDeviceWithManagement(IntPtr pDeviceID);
|
||||
|
||||
public static int UnregisterDevice()
|
||||
{
|
||||
return UnregisterDeviceWithManagement(IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
"@ -Language CSharp
|
||||
|
||||
function Test-Administrator
|
||||
{
|
||||
@@ -66,7 +84,7 @@ function Force-Remove-Orbit {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Write success log
|
||||
"Fleetd successfully removed at $(Get-Date)" | Out-File -Append -FilePath "$env:TEMP\fleet_remove_log.txt"
|
||||
}
|
||||
@@ -89,18 +107,16 @@ function Main {
|
||||
Exit -1
|
||||
}
|
||||
|
||||
Write-Host "About to uninstall fleetd..."
|
||||
|
||||
if ($args[0] -eq "remove") {
|
||||
# "remove" is received as argument to the script when called as the
|
||||
# sub-process that will actually remove the fleet agent.
|
||||
|
||||
# Log the start of removal process
|
||||
"Starting removal process at $(Get-Date)" | Out-File -Append -FilePath "$env:TEMP\fleet_remove_log.txt"
|
||||
|
||||
|
||||
# sleep to give time to fleetd to send the script results to Fleet
|
||||
Start-Sleep -Seconds 20
|
||||
|
||||
|
||||
if (Force-Remove-Orbit) {
|
||||
Write-Host "fleetd was uninstalled."
|
||||
Exit 0
|
||||
@@ -109,26 +125,81 @@ function Main {
|
||||
Exit -1
|
||||
}
|
||||
} else {
|
||||
# Turn off MDM first so Fleet cannot re-enable it before fleetd is removed.
|
||||
|
||||
# Check 1: Fleet-specific enrollment (ProviderID + EnrollmentState)
|
||||
$enrollmentKey = Get-Item -Path HKLM:\SOFTWARE\Microsoft\Enrollments\* -ErrorAction SilentlyContinue | Get-ItemProperty | Where-Object {$_.ProviderID -eq 'Fleet'} | Where-Object {$_.EnrollmentState -match '1|3|6|13'}
|
||||
$mdmEnrolled = $null -ne $enrollmentKey
|
||||
|
||||
# Check 2: fallback via DiscoveryServiceFullURL
|
||||
$enrollmentsPath = "HKLM:\SOFTWARE\Microsoft\Enrollments"
|
||||
if (-not $mdmEnrolled) {
|
||||
if (Test-Path $enrollmentsPath) {
|
||||
$enrollmentKeys = Get-ChildItem -Path $enrollmentsPath -ErrorAction SilentlyContinue
|
||||
foreach ($key in $enrollmentKeys) {
|
||||
if ($null -ne (Get-ItemProperty -Path $key.PSPath -Name "DiscoveryServiceFullURL" -ErrorAction SilentlyContinue)) {
|
||||
$mdmEnrolled = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mdmEnrolled) {
|
||||
$result = [MdmRegistration]::UnregisterDevice()
|
||||
|
||||
if ($result -ne 0) {
|
||||
throw "UnregisterDeviceWithManagement failed with error code: $result"
|
||||
}
|
||||
|
||||
Write-Host "Device unregistration called successfully."
|
||||
|
||||
$clearedCount = 0
|
||||
|
||||
if (Test-Path $enrollmentsPath) {
|
||||
$enrollmentKeys = Get-ChildItem -Path $enrollmentsPath -ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($key in $enrollmentKeys) {
|
||||
if ($null -ne (Get-ItemProperty -Path $key.PSPath -Name "DiscoveryServiceFullURL" -ErrorAction SilentlyContinue)) {
|
||||
try {
|
||||
Remove-ItemProperty -Path $key.PSPath -Name "DiscoveryServiceFullURL" -ErrorAction Stop
|
||||
$clearedCount++
|
||||
Write-Host "Cleared DiscoveryServiceFullURL from enrollment key: $($key.PSChildName)"
|
||||
} catch {
|
||||
Write-Warning "Failed to clear DiscoveryServiceFullURL from $($key.PSChildName): $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($clearedCount -gt 0) {
|
||||
Write-Host "Cleared DiscoveryServiceFullURL from $clearedCount enrollment key(s)."
|
||||
} else {
|
||||
Write-Host "Turning off MDM completed. The UnregisterDeviceWithManagement API automatically cleared the registry values."
|
||||
}
|
||||
} else {
|
||||
Write-Host "MDM is not turned on. Skipping MDM unregistration."
|
||||
}
|
||||
|
||||
# when this script is executed from fleetd, it does not immediately
|
||||
# remove the agent. Instead, it starts a new detached process that
|
||||
# will do the actual removal.
|
||||
|
||||
|
||||
Write-Host "Removing fleetd, system will be unenrolled in 20 seconds..."
|
||||
Write-Host "Executing detached child process"
|
||||
|
||||
|
||||
$execName = $MyInvocation.ScriptName
|
||||
$proc = Start-Process -PassThru -FilePath "powershell" -WindowStyle Hidden -ArgumentList "-MTA", "-ExecutionPolicy", "Bypass", "-File", "`"$execName`"", "remove"
|
||||
|
||||
|
||||
# Log the process ID
|
||||
"Started removal process with ID: $($proc.Id) at $(Get-Date)" | Out-File -Append -FilePath "$env:TEMP\fleet_remove_log.txt"
|
||||
|
||||
|
||||
Start-Sleep -Seconds 5 # give time to process to start running
|
||||
Write-Host "Removal process started: $($proc.Id)."
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Error: Entry point"
|
||||
Write-Host "$(Resolve-Error-Detailed)"
|
||||
Exit -1
|
||||
Write-Error "Error running fleetd unenrollment script: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ controls:
|
||||
# macOS scripts
|
||||
- path: ../lib/macos/scripts/uninstall-fleetd-macos.sh
|
||||
# Windows scripts
|
||||
- path: ../lib/windows/scripts/uninstall-fleetd-windows.ps1
|
||||
# Linux scripts
|
||||
- path: ../lib/linux/scripts/uninstall-fleetd-linux.sh
|
||||
- path: ../lib/linux/scripts/install-fleet-desktop-required-extension.sh
|
||||
|
||||
@@ -148,8 +148,6 @@ controls:
|
||||
grace_period_days: 2
|
||||
scripts:
|
||||
- path: ../lib/macos/scripts/uninstall-fleetd-macos.sh
|
||||
- path: ../lib/windows/scripts/uninstall-fleetd-windows.ps1
|
||||
- path: ../lib/windows/scripts/turn-off-mdm.ps1
|
||||
- path: ../lib/windows/scripts/enable-ms-defender.ps1
|
||||
- path: ../lib/windows/scripts/create-admin-user.ps1
|
||||
- path: ../lib/linux/scripts/uninstall-fleetd-linux.sh
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# Please don't delete. This script is referenced in the guide here: https://fleetdm.com/guides/windows-mdm-setup#turn-off-windows-mdm
|
||||
|
||||
Add-Type -TypeDefinition @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class MdmRegistration
|
||||
{
|
||||
[DllImport("mdmregistration.dll", SetLastError = true)]
|
||||
public static extern int UnregisterDeviceWithManagement(IntPtr pDeviceID);
|
||||
|
||||
public static int UnregisterDevice()
|
||||
{
|
||||
return UnregisterDeviceWithManagement(IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
"@ -Language CSharp
|
||||
|
||||
try {
|
||||
# Step 1: Check for DiscoveryServiceFullURL values before unregistering
|
||||
# This helps us provide clearer output about what happened
|
||||
$enrollmentsPath = "HKLM:\SOFTWARE\Microsoft\Enrollments"
|
||||
$foundBeforeUnregister = $false
|
||||
|
||||
if (Test-Path $enrollmentsPath) {
|
||||
$enrollmentKeys = Get-ChildItem -Path $enrollmentsPath -ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($key in $enrollmentKeys) {
|
||||
$upnPath = Join-Path $key.PSPath "UPN"
|
||||
$discoveryUrlPath = Join-Path $key.PSPath "DiscoveryServiceFullURL"
|
||||
|
||||
if (Test-Path $upnPath) {
|
||||
if (Test-Path $discoveryUrlPath) {
|
||||
$foundBeforeUnregister = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Step 2: Unregister the device from MDM using the Windows API
|
||||
$result = [MdmRegistration]::UnregisterDevice()
|
||||
|
||||
if ($result -ne 0) {
|
||||
throw "UnregisterDeviceWithManagement failed with error code: $result"
|
||||
}
|
||||
|
||||
Write-Host "Device unregistration called successfully."
|
||||
|
||||
# Step 3: Clear any remaining DiscoveryServiceFullURL registry values to ensure Fleet detects
|
||||
# the device as unenrolled on the next refetch. The UnregisterDeviceWithManagement API
|
||||
# may have already cleared these values, but we check and clear any remaining ones to be safe.
|
||||
$clearedCount = 0
|
||||
|
||||
if (Test-Path $enrollmentsPath) {
|
||||
$enrollmentKeys = Get-ChildItem -Path $enrollmentsPath -ErrorAction SilentlyContinue
|
||||
|
||||
foreach ($key in $enrollmentKeys) {
|
||||
# Only clear DiscoveryServiceFullURL from enrollment keys that have a UPN
|
||||
# (these are the ones Fleet's query checks). This matches Fleet's query logic
|
||||
# which filters by entries with UPN values.
|
||||
$upnPath = Join-Path $key.PSPath "UPN"
|
||||
$discoveryUrlPath = Join-Path $key.PSPath "DiscoveryServiceFullURL"
|
||||
|
||||
if (Test-Path $upnPath) {
|
||||
if (Test-Path $discoveryUrlPath) {
|
||||
try {
|
||||
Remove-ItemProperty -Path $key.PSPath -Name "DiscoveryServiceFullURL" -ErrorAction Stop
|
||||
$clearedCount++
|
||||
Write-Host "Cleared DiscoveryServiceFullURL from enrollment key: $($key.PSChildName)"
|
||||
} catch {
|
||||
Write-Warning "Failed to clear DiscoveryServiceFullURL from $($key.PSChildName): $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Provide clearer output based on what we found
|
||||
if ($clearedCount -gt 0) {
|
||||
Write-Host "Cleared DiscoveryServiceFullURL from $clearedCount enrollment key(s). Fleet will detect the device as unenrolled on the next refetch."
|
||||
} elseif ($foundBeforeUnregister) {
|
||||
Write-Host "MDM unregistration completed. The UnregisterDeviceWithManagement API automatically cleared the registry values."
|
||||
Write-Host "Fleet will detect the device as unenrolled on the next refetch."
|
||||
} else {
|
||||
Write-Host "MDM unregistration completed. No DiscoveryServiceFullURL registry values were found (device was not enrolled or values were already cleared)."
|
||||
}
|
||||
} catch {
|
||||
Write-Error "Error calling UnregisterDeviceWithManagement: $_"
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user