Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deletes device records in AD / AAD / Intune / Autopilot / ConfigMgr for Autopilot Test Deployments
[CmdletBinding(DefaultParameterSetName='All')]
Param
(
[Parameter(ParameterSetName='All',Mandatory=$true,ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
[Parameter(ParameterSetName='Individual',Mandatory=$true,ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
$ComputerName,
[Parameter(ParameterSetName='All')]
[switch]$All = $True,
[Parameter(ParameterSetName='Individual')]
[switch]$AD,
[Parameter(ParameterSetName='Individual')]
[switch]$AAD,
[Parameter(ParameterSetName='Individual')]
[switch]$Intune,
[Parameter(ParameterSetName='Individual')]
[switch]$Autopilot,
[Parameter(ParameterSetName='Individual')]
[switch]$ConfigMgr
)
Set-Location $env:SystemDrive
# Load required modules
If ($PSBoundParameters.ContainsKey("AAD") -or $PSBoundParameters.ContainsKey("Intune") -or $PSBoundParameters.ContainsKey("Autopilot") -or $PSBoundParameters.ContainsKey("ConfigMgr") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-host "Importing modules..." -NoNewline
If ($PSBoundParameters.ContainsKey("AAD") -or $PSBoundParameters.ContainsKey("Intune") -or $PSBoundParameters.ContainsKey("Autopilot") -or $PSBoundParameters.ContainsKey("All"))
{
Import-Module Microsoft.Graph.Intune -ErrorAction Stop
}
If ($PSBoundParameters.ContainsKey("AAD") -or $PSBoundParameters.ContainsKey("All"))
{
Import-Module AzureAD -ErrorAction Stop
}
If ($PSBoundParameters.ContainsKey("ConfigMgr") -or $PSBoundParameters.ContainsKey("All"))
{
Import-Module $env:SMS_ADMIN_UI_PATH.Replace('i386','ConfigurationManager.psd1') -ErrorAction Stop
}
Write-host "Success" -ForegroundColor Green
}
Catch
{
Write-host "$($_.Exception.Message)" -ForegroundColor Red
Return
}
}
# Authenticate with Azure
If ($PSBoundParameters.ContainsKey("AAD") -or $PSBoundParameters.ContainsKey("Intune") -or $PSBoundParameters.ContainsKey("Autopilot") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-Host "Authenticating with MS Graph and Azure AD..." -NoNewline
$intuneId = Connect-MSGraph -ErrorAction Stop
$aadId = Connect-AzureAD -AccountId $intuneId.UPN -ErrorAction Stop
Write-host "Success" -ForegroundColor Green
}
Catch
{
Write-host "Error!" -ForegroundColor Red
Write-host "$($_.Exception.Message)" -ForegroundColor Red
Return
}
}
Write-host "$($ComputerName.ToUpper())" -ForegroundColor Yellow
Write-Host "===============" -ForegroundColor Yellow
# Delete from AD
If ($PSBoundParameters.ContainsKey("AD") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-host "Retrieving " -NoNewline
Write-host "Active Directory " -ForegroundColor Yellow -NoNewline
Write-host "computer account..." -NoNewline
$Searcher = [ADSISearcher]::new()
$Searcher.Filter = "(sAMAccountName=$ComputerName`$)"
[void]$Searcher.PropertiesToLoad.Add("distinguishedName")
$ComputerAccount = $Searcher.FindOne()
If ($ComputerAccount)
{
Write-host "Success" -ForegroundColor Green
Write-Host " Deleting computer account..." -NoNewline
$DirectoryEntry = $ComputerAccount.GetDirectoryEntry()
$Result = $DirectoryEntry.DeleteTree()
Write-Host "Success" -ForegroundColor Green
}
Else
{
Write-host "Not found!" -ForegroundColor Red
}
}
Catch
{
Write-host "Error!" -ForegroundColor Red
$_
}
}
# Delete from Azure AD
If ($PSBoundParameters.ContainsKey("AAD") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-host "Retrieving " -NoNewline
Write-host "Azure AD " -ForegroundColor Yellow -NoNewline
Write-host "device record/s..." -NoNewline
[array]$AzureADDevices = Get-AzureADDevice -SearchString $ComputerName -All:$true -ErrorAction Stop
If ($AzureADDevices.Count -ge 1)
{
Write-Host "Success" -ForegroundColor Green
Foreach ($AzureADDevice in $AzureADDevices)
{
Write-host " Deleting DisplayName: $($AzureADDevice.DisplayName) | ObjectId: $($AzureADDevice.ObjectId) | DeviceId: $($AzureADDevice.DeviceId) ..." -NoNewline
Remove-AzureADDevice -ObjectId $AzureADDevice.ObjectId -ErrorAction Stop
Write-host "Success" -ForegroundColor Green
}
}
Else
{
Write-host "Not found!" -ForegroundColor Red
}
}
Catch
{
Write-host "Error!" -ForegroundColor Red
$_
}
}
# Delete from Intune
If ($PSBoundParameters.ContainsKey("Intune") -or $PSBoundParameters.ContainsKey("Autopilot") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-host "Retrieving " -NoNewline
Write-host "Intune " -ForegroundColor Yellow -NoNewline
Write-host "managed device record/s..." -NoNewline
[array]$IntuneDevices = Get-IntuneManagedDevice -Filter "deviceName eq '$ComputerName'" -ErrorAction Stop
If ($IntuneDevices.Count -ge 1)
{
Write-Host "Success" -ForegroundColor Green
If ($PSBoundParameters.ContainsKey("Intune") -or $PSBoundParameters.ContainsKey("All"))
{
foreach ($IntuneDevice in $IntuneDevices)
{
Write-host " Deleting DeviceName: $($IntuneDevice.deviceName) | Id: $($IntuneDevice.Id) | AzureADDeviceId: $($IntuneDevice.azureADDeviceId) | SerialNumber: $($IntuneDevice.serialNumber) ..." -NoNewline
Remove-IntuneManagedDevice -managedDeviceId $IntuneDevice.Id -Verbose -ErrorAction Stop
Write-host "Success" -ForegroundColor Green
}
}
}
Else
{
Write-host "Not found!" -ForegroundColor Red
}
}
Catch
{
Write-host "Error!" -ForegroundColor Red
$_
}
}
# Delete Autopilot device
If ($PSBoundParameters.ContainsKey("Autopilot") -or $PSBoundParameters.ContainsKey("All"))
{
If ($IntuneDevices.Count -ge 1)
{
Try
{
Write-host "Retrieving " -NoNewline
Write-host "Autopilot " -ForegroundColor Yellow -NoNewline
Write-host "device registration..." -NoNewline
$AutopilotDevices = New-Object System.Collections.ArrayList
foreach ($IntuneDevice in $IntuneDevices)
{
$URI = "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities?`$filter=contains(serialNumber,'$($IntuneDevice.serialNumber)')"
$AutopilotDevice = Invoke-MSGraphRequest -Url $uri -HttpMethod GET -ErrorAction Stop
[void]$AutopilotDevices.Add($AutopilotDevice)
}
Write-Host "Success" -ForegroundColor Green
foreach ($device in $AutopilotDevices)
{
Write-host " Deleting SerialNumber: $($Device.value.serialNumber) | Model: $($Device.value.model) | Id: $($Device.value.id) | GroupTag: $($Device.value.groupTag) | ManagedDeviceId: $($device.value.managedDeviceId) ..." -NoNewline
$URI = "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($device.value.Id)"
$AutopilotDevice = Invoke-MSGraphRequest -Url $uri -HttpMethod DELETE -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
}
}
Catch
{
Write-host "Error!" -ForegroundColor Red
$_
}
}
}
# Delete from ConfigMgr
If ($PSBoundParameters.ContainsKey("ConfigMgr") -or $PSBoundParameters.ContainsKey("All"))
{
Try
{
Write-host "Retrieving " -NoNewline
Write-host "ConfigMgr " -ForegroundColor Yellow -NoNewline
Write-host "device record/s..." -NoNewline
$SiteCode = (Get-PSDrive -PSProvider CMSITE -ErrorAction Stop).Name
Set-Location ("$SiteCode" + ":") -ErrorAction Stop
[array]$ConfigMgrDevices = Get-CMDevice -Name $ComputerName -Fast -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
foreach ($ConfigMgrDevice in $ConfigMgrDevices)
{
Write-host " Deleting Name: $($ConfigMgrDevice.Name) | ResourceID: $($ConfigMgrDevice.ResourceID) | SMSID: $($ConfigMgrDevice.SMSID) | UserDomainName: $($ConfigMgrDevice.UserDomainName) ..." -NoNewline
Remove-CMDevice -InputObject $ConfigMgrDevice -Force -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
}
}
Catch
{
Write-host "Error!" -ForegroundColor Red
$_
}
}
Set-Location $env:SystemDrive
@NFCES
Copy link

NFCES commented May 27, 2020

The specified module 'AzureAD' was not loaded because no valid module file was found in any module directory. Please advise.

@kvnsmn
Copy link

kvnsmn commented Jul 23, 2020

The specified module 'AzureAD' was not loaded because no valid module file was found in any module directory. Please advise.

It happened to me too with "-All". I think it is the ConfigMgr option. When I just use "-AAD -Intune -Autopilot" it works fine.

@oingobo
Copy link

oingobo commented Feb 25, 2021

Very cool. To make it work for my environment, I changed the order of the deletion process and added a 2 minute Sleep after Autopilot delete to give the service enough time. Autopilot should never be deleted before Azure.

@speedracer3901
Copy link

speedracer3901 commented Feb 28, 2021

If I enter a computer name 'Brown' it will delete Brown Brown1 Brown2. Is there a code change I can make so it only deletes exact matches?

@tilla1975
Copy link

tilla1975 commented Jun 6, 2021

I run this script with -Autopilot -AAD -Intune, using a CSV as per the below.

I get a success for all removals, but when I check AutoPilot, all of the devices are still listed?

$computer_list = Import-Csv "c:\Scripts\TestComputerName.csv"
foreach ($computer in $computer_list)
{
.\Delete-AutopilotedDeviceRecords.ps1 -ComputerName $($computer.ComputerName) -Autopilot -AAD -Intune
}

@randomsunrize
Copy link

randomsunrize commented Sep 25, 2021

If I enter a computer name 'Brown' it will delete Brown Brown1 Brown2. Is there a code change I can make so it only deletes exact matches?

That happened to me too! Luckily it was only pilot devices.
.\Delete-AutopilotedDeviceRecords.ps1 -ComputerName LAB -Intune -AAD

@dridley23
Copy link

dridley23 commented Dec 23, 2021

Thanks Trevor - Love your work on this.
To be unique, I changed the search to "Get-AzureADDevice -All:$True -ErrorAction Stop | Where { $_.DisplayName -eq $($ComputerName) } }"
as it didn't like the -Filter switch inside ps1 (given literal string i believe).

@RaghuKeenLearner
Copy link

RaghuKeenLearner commented May 12, 2022

The specified module 'AzureAD' was not loaded because no valid module file was found in any module directory. Please advise.

You need to install the module first. Inject these at the begining of your script.

Install-Module Microsoft.Graph.Intune -ErrorAction Stop -Force -Confirm:$false -Verbose
Install-Module AzureAD -ErrorAction Stop -Force -Confirm:$false -Verbose

@Desiqnx3
Copy link

Desiqnx3 commented Jun 14, 2022

Hi all!
I have the problem, that one autopilot rollout failed. And now there are two devices with the exact name. One is Hybrid Joined and one Azure AD joined(in activ since 2021), both autopilot devices. Is there an way, how can i remove only that "Azure AD joined" device? I have the fear that I delete both with the command. (even if I use e.g. only azure ad, because there they are both seen under the same name) Object IDs etc. are different.

@RaghuKeenLearner
Copy link

RaghuKeenLearner commented Jun 17, 2022

@rmuhammad4
Copy link

rmuhammad4 commented Jul 28, 2022

This worked for me. But the device was still in MSfB, I had to delete it from there then re-import csv.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment