You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设备未出现在MEM门户/工作负载迁移不全,如何脚本删除Azure AD设备?

问题背景

设备未显示在MEM门户中,或仅完成部分工作负载迁移,需解决该问题。

已执行操作

已尝试以下PowerShell操作:

  • 创建了PowerShell脚本:DeleteEnrollment.PS1
## Create Log

Function Write-Log 
{
    Param 
    (
    [string]$Message
    )

    $Logfilepath = "C:\ProgramData\Microsoft\CoMgmtFixLog"
    $Logfile = "C:\ProgramData\Microsoft\CoMgmtFixLog\CoMgmtFixLog.log"

    If (!(Test-Path $Logfilepath))
    {
        New-Item -ItemType Directory -Path $Logfilepath -Force | Out-Null
    }

    If (!(Test-Path $Logfile))
    {
        New-Item -ItemType File -Path $Logfile -Force | Out-Null
    }

    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $mgs = "$Stamp $Message"
    Add-Content $Logfile -Value $mgs
}

## Create TimeStamp in Registry
Function Create-Timestamp
{
    param
    (
        [String]$RegKeypath,
        [String]$RegKeyName,
        [String]$RegKeyValue
    )
    $ComgmtFixHive = 'HKLM:\SOFTWARE\Policies\Microsoft\CoMgmtFix'
    $Step = "$ComgmtFixHive\$RegKeypath"

    If (!(Test-Path $ComgmtFixHive))
    {
        New-Item -Path $ComgmtFixHive -Force | Out-Null
    }
    
    If(!(Test-Path $Step))
    {
        New-Item -Path $Step -Force | Out-Null
    }
    If($Step -and $RegKeyName -and $RegKeyValue)
    {
        New-ItemProperty -Path $Step -Name $RegKeyName -Value $RegKeyValue -PropertyType 'String' -force -ea SilentlyContinue | Out-Null
    }
    New-ItemProperty -Path $Step -Name 'ExecutionTimeStap' -Value (Get-Date).toString("yyyy/MM/dd HH:mm:ss") -PropertyType 'String' -force -ea SilentlyContinue | Out-Null
    
}

## Script Block ##
$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
Write-Log "=========== Begining of Log - $Stamp =========="

## Retrieving Enrollment GUID
(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\*' | select Pschildname).pschildname | Out-File -FilePath 'C:\ProgramData\Microsoft\CoMgmtFixLog\EnrollmentGUID.txt'
$DeviceEnrollmentID = Get-Content 'C:\ProgramData\Microsoft\CoMgmtFixLog\EnrollmentGUID.txt'
Write-Log "Collected Enrollment GUID : $DeviceEnrollmentID"
Create-Timestamp -RegKeypath 'GetEnrollmentID' -RegKeyName 'EnrollmentID' -RegKeyValue $DeviceEnrollmentID

If (Test-Path "HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked\$DeviceEnrollmentID")
{
    Remove-Item -Path HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked\$DeviceEnrollmentID -Recurse -Force
    Write-Log "Delected : \`"HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked\$DeviceEnrollmentID\`" registry."
}
If (Test-Path "HKLM:\SOFTWARE\Microsoft\Enrollments\$DeviceEnrollmentID")
{
    Remove-Item -Path HKLM:\SOFTWARE\Microsoft\Enrollments\$DeviceEnrollmentID -Recurse -Force
    Write-Log "Delected : \`"HKLM:\SOFTWARE\Microsoft\Enrollments\$DeviceEnrollmentID\`" registry."
}

## Retrieve Scheduled tasks
Write-Log "Checking and deleting Enrollment Scheduled tasks."
Create-Timestamp -RegKeypath 'ScheduledTaskDeletion'
$AllSchdTasks = Get-ScheduledTask | where TaskPath -eq "\Microsoft\Windows\Enterprisemgmt\$DeviceEnrollmentID\"

ForEach ($AllSchdTask in $AllSchdTasks)
{
    $taskname = $AllSchdTask.TaskName
    Unregister-ScheduledTask -TaskPath $AllSchdTask.TaskPath -TaskName $taskname -Confirm:$false
    Write-Log "Deleting : $taskname"
}

Start-Process "$PSScriptRoot\PsExec.exe" -ArgumentList "-is powershell.exe -command Remove-Item 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\Microsoft\Windows\EnterpriseMgmt\$DeviceEnrollmentID' -Recurse -Force" -WindowStyle Hidden


## Removing MDM Certificate
Write-Log "Finding and deleting MDM certificate"
Create-Timestamp -RegKeypath 'MDMCertificateDeletion'
gci cert:\LocalMachine\My -Recurse | Where {$_.Issuer -match 'Microsoft Intune MDM Device CA'} | Remove-Item -Force
$MDMcert = Get-ChildItem cert:\LocalMachine\My -Recurse | Where {$_.Issuer -match 'Microsoft Intune MDM Device CA'}
If($MDMcert)
{
    Write-Log "MDM Certificate NOT Deleted"
}
Else
{
    Write-Log "MDM Certificate Deleted"
}

## Retrieving existing users
Write-Log "Retrieving Existing user name and deleting Microsoft AAD broker plugin files."
Create-Timestamp -RegKeypath 'DeleteUserFiles'
$UserFolders = Get-ChildItem "C:\Users"
ForEach ($UserFolder in $UserFolders)
{
    if ($UserFolder.Name -ne 'adiadmin')
    {
        if ($UserFolder.Name -ne 'Public')
        {
            if ($UserFolder.Name -ne 'Default')
            {
                $username = $UserFolder.Name
                Write-Log "Deleting Microsoft.AAD.BrokerPlugin files from $username"
                $msaadName = (Get-ChildItem "C:\Users\$username\AppData\Local\Packages" -Recurse -Force -Include Microsoft.AAD.BrokerPlugin* -ea SilentlyContinue).Name
                Remove-Item -Path "C:\Users\$username\AppData\Local\Packages\$msaadName\Settings\*" -Force -Recurse -ea SilentlyContinue 
                Remove-Item -Path "C:\Users\$username\AppData\Local\Packages\$msaadName\AC\TokenBroker\Accounts\*" -Force -Recurse -ea SilentlyContinue
            }
        }
    }
}

## Running dsregcmd /leave
Write-Log "Running dsregcmd /leave command"
Create-Timestamp -RegKeypath 'DsRegcmdLeave'
Start-Process -FilePath "dsregcmd.exe" -ArgumentList "/leave" -Verb RunAs
#.\dsregcmd.exe /leave

## Printing Reboot required regkey
Write-Log "Please restart you computer to proceed with next step."
Create-Timestamp -RegKeypath 'Reboot' -RegKeyName 'IsRebootRequired' -RegKeyValue 'Yes'

#Remove-Item -Path C:\temp\PsExec.exe -Force

Write-Log "=========== End of Log - $Stamp =========="
  • 创建了包含问题设备列表的Server.txt文件
  • 执行CoMgmtFix.Ps1脚本完成相关清理操作
当前疑问

上述步骤中需手动删除Azure AD中的设备条目,是否有办法通过脚本自动完成该操作?


解决方案

可以通过PowerShell自动删除Azure AD中的设备条目,具体实现如下:

1. 准备依赖模块

推荐使用Microsoft Graph PowerShell模块(Azure AD模块已弃用),先完成模块安装与权限连接:

# 安装Microsoft Graph设备管理模块
Install-Module Microsoft.Graph.Identity.DirectoryManagement -Force -AllowClobber

# 连接到Microsoft Graph,需设备读写权限
Connect-MgGraph -Scopes "Device.ReadWrite.All"

2. 脚本自动删除逻辑

可以根据你的现有流程选择两种匹配方式:

方式一:按设备名称批量删除(适配Server.txt列表)

# 读取Server.txt中的设备名称列表
$deviceList = Get-Content "Server.txt"

foreach ($deviceName in $deviceList) {
    # 根据设备名称查找Azure AD中的设备
    $targetDevice = Get-MgDevice -Filter "DisplayName eq '$deviceName'"
    if ($targetDevice) {
        # 删除匹配到的设备
        Remove-MgDevice -DeviceId $targetDevice.Id
        Write-Host "已删除Azure AD设备:$deviceName"
    } else {
        Write-Host "Azure AD中未找到设备:$deviceName"
    }
}

方式二:按设备ID删除(适配本地脚本获取的Enrollment GUID)

可以将这段逻辑整合到你的DeleteEnrollment.PS1脚本中,在本地清理完成后同步删除Azure AD条目:

# 假设$DeviceEnrollmentID是从本地注册表获取的设备ID
$targetDevice = Get-MgDevice -Filter "DeviceId eq '$DeviceEnrollmentID'"
if ($targetDevice) {
    Remove-MgDevice -DeviceId $targetDevice.Id
    Write-Log "已删除Azure AD中对应设备:$DeviceEnrollmentID"
} else {
    Write-Log "Azure AD中未找到匹配ID的设备:$DeviceEnrollmentID"
}

3. 注意事项

  • 执行脚本的账号需拥有设备管理员或全局管理员权限
  • 删除前建议先通过Get-MgDevice确认设备存在,避免误删
  • 若必须使用旧版Azure AD模块,对应命令为Get-AzureADDevice和Remove-AzureADDevice,但不推荐长期使用

内容的提问来源于stack exchange,提问作者ScriptiX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:10:49