In today’s environments one of the most important point is to keep them clean and tidy. Otherwise deployment statistics and security related reports are not correct. Therefore it’s important to continuously clean up your environment.
In this blog I will cover solution on how to automatically cleanup when you are using Autopilot in combination with Azure AD Hybrid Join (Intune Connector for Active Directory Extender). The cleanup is done for the following systems:
- Active Directory: In case you build your device name by using for example the serial number, done by a custom script after the enrollment by Intune. Then you need a mechanism to delete the old object if the device was already enrolled. Otherwise the device cannot be renamed if a computer object already exists for the same name.
- Intune: On each enrollment Intune creates a new object. Therefore, we should check if there are other devices with the same serial number and remove them.
- ConfigMgr: If you are using Co-Management also ConfigMgr could have stale devices which can be removed. Part of next blog.
Important: All the above depends on unique device serial numbers. If your hardware vendor doesn’t provide them correctly, then you need another mechanism.
Important 2: In normal case I try to disable objects only, but this is in the above cases not possible. If the AD computer account for example is only disabled, then I can still not rename the reenrolled device. So, the scripts are deleting, test them well before enabling them.
Example 1 – Add AD computer object to AD group
Can be found in the initial blog about the Extender.
Example 2 – Remove old instances of device in Intune
If you would like to remove automatically old device entries in Intune during an Autopilot Enrollment. You can easily archive this by installing the Intune Connector for Active Directory Extender as explained in the Installation and Configuration section. After that we can start customizing the ODJ-Extender.ps1 script.
Nearly at the bottom you will find the Empty Main script section. At this position the script has already set the variable $DeviceName and $DeviceId which corresponds to the Intune device id.
#region Main Script
########################################################
#endregion
First of all, we need to initialize some variables which we can then use in the script. Important is a service account with Intune permissions to delete devices. The password can be saved as SecureString. You can get the string by executing the following command, which should be executed under the same account as the service is running (System). Therefore, you have to use “psexec -i -s powershell.exe” to generate it:
$sec = Read-Host -AsSecureString | ConvertFrom-SecureString
The variables in the script should then look like in this example:
#region Remove old Computer Account from AD based on Computername Pattern
$upn = "intune.svc@kurcontoso.ch"
$passWD = "01000000d08c9ddf00000000020000000…aad871d4baa91387bdb139503eec1c961c47d1c"
$maxDevicesToDelete = 3 # If more devices are returned, the script will not delete them.
$MaxRetries = 25
$RetryDelay = 5 # Seconds
Then we must load the Intune PowerShell Module and Connect to it:
try {
#import the Intune Powershell module
Write-Log "import Microsoft.Graph.Intune PSModule"
Import-Module Microsoft.Graph.Intune -Force -ErrorAction Stop | Out-Null
} catch {
Write-Log "Coul not load Microsoft.Graph.Intune module. Trying to install and then import it."
#Install Intune PowerShell module and then import it
Install-Module Microsoft.Graph.Intune -Force
Import-Module Microsoft.Graph.Intune -Force -ErrorAction Stop | Out-Null
if((Get-Module -Name Microsoft.Graph.Intune) -eq $null){
Write-Log "Could not import Microsoft.Graph.Intnue module. Data collection will be aborted." -Type Error
throw "Could not import Microsoft.Graph.Intnue module."
}
}
try {
#create the connection credentials
Write-Log "Converting Password to securestring"
$secPwd = ConvertTo-SecureString $passWD
$credentials = New-Object System.Management.Automation.PSCredential($upn,$secPwd)
Write-Log "Connecting to intune"
#connect to Intune without Outputing to the console.
Connect-MSGraph -PSCredential $credentials
} catch {
Write-Log "Could not connet to Intune." -Type Error -Exception $_.Exception
throw "Could not connect to Intune"
}
Next Task is to get the serial number of the device with the $DeviceId. This can be accomplished by the following lines of code. Important is, that it sometimes takes a few seconds until the device information is available, because of that I added a retry mechanism:
try{
Write-Log "Getting serialnumber for device id '$DeviceId'"
$i = 0
while(($intuneDevice.serialNumber.Length -lt 1) -and ($i -lt $MaxRetries)){
$i++
Write-Log "Start searching Intune by DeviceId (Try: '$i')"
Start-Sleep -Seconds $RetryDelay
$intuneDevice = Get-IntuneManagedDevice -managedDeviceId $DeviceId
$DeviceSerial = $intuneDevice.serialNumber
}
} catch {
if($_.TargetObject.Response.HttpStatusCode -eq 404){
Write-Log "Device not found in Intune continuing with the script"
}else{
Write-Log "Could not get new device name" -Type Error -Exception $_.Exception
}
}
Then we can already start searching for other devices with the same serial number and remove the one which are not our actual device with id equals $DeviceId:
if($null -ne $DeviceSerial)
{
try{
Write-Log "Getting all devices with same serialnumber '$DeviceSerial' like device id '$DeviceId'"
$intuneOldDevices = Get-IntuneManagedDevice -Filter "serialNumber eq '$DeviceSerial'"
if($intuneOldDevices.Count -lt ($maxDevicesToDelete + 1)){ # Add one to the Max because one device will be excluded
foreach($intuneOldDevice in $intuneOldDevices){
if($intuneOldDevice.id -eq $DeviceId){
Write-Log "Identical device id '$DeviceId', do nothing with this object."
} else {
Write-Log "Found device id '$($intuneOldDevice.id)', remove object."
Remove-IntuneManagedDevice -managedDeviceId $intuneOldDevice.id
}
}
}
} catch{
if($_.TargetObject.Response.HttpStatusCode -eq 404){
Write-Log "Device not found in Intune continuing with the script"
}else{
Write-Log "Could not get new device name" -Type Error -Exception $_.Exception
}
}
}else{
Write-Log "Target devicename not set. Skipping device removal."
}
Now we have already all code snippets together. To simplify it for you I have uploaded the complete script to Github.
Example 3 – Remove stale ad computer objects
This example is only working, if you rename your devices after enrollment by using some fix variables like serial number. The first parts we require are identical to example 2. We need to define some variables, load the Intune PowerShell Module and retrieve the serial number from Intune. Then we have to build the proposed future hostname. We can do this at this point because the renaming will happen at a later stage with the exact same algorithm:
#Building Devicename to search for it in AD
Write-Log "Building Target Devicename"
$TargetComputername = "KUR-$DeviceSerial"
Write-Log "Target ComputerName: '$TargetComputername'"
if ($TargetComputername.Length -ge 15) {
Write-Log "Target ComputerName is longer ($($TargetComputername.Length)) than the allowed length of 15. It will be shorted."
$TargetComputername = $TargetComputername.substring(0, 15)
Write-Log "New Target ComputerName: '$TargetComputername' "
}
Now we can check if there is already such a computer account available in Active Directory. If yes the renaming process would fail and therefore we should immediately delete the computer account:
if(($intuneDevice) -and ($TargetComputername.Length -gt 4))
{
Write-Log "Delete device from AD with devicename '$TargetComputername'"
try{
$devicesToDelete = @(Get-ADComputer -Identity $TargetComputername)
if($devicesToDelete.Count -le $maxDevicesToDelete){
Write-Log "Found '$($devicesToDelete.Count)' devices. This is below the configured value of '$maxDevicesToDelete'. Therefore deleting those devices."
foreach($deviceToDelete in $devicesToDelete){
Write-Log "Removing '$($deviceToDelete.DistinguishedName)'"
try{
Remove-ADObject -Identity $deviceToDelete -Recursive -Confirm:$FALSE
}catch{
Write-Log "Could not remove device" -Type Error -Exception $_.Exception
}
}
}else{
Write-Log "Found '$($devicesToDelete.Count)' devices. This is above the configured value of '$maxDevicesToDelete'. Therefore skipping those devices."
}
}catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
Write-Log "AD object for '$TargetComputername' not found, skipping device removal"
}catch{
Write-Log "Error on deleting device." -Type Error -Exception $_.Exception
}
}else{
Write-Log "Target devicename not set. Skipping device removal."
}
The complete script to automatically remove computer accounts can also be found on Github. If you combine it with the one from example 2 just remove the duplicated parts.
Summary
The above scripts help you to have a clean environment which also improves your deployment statistics. If you have any improvements, just commit them on Github.
- Microsoft Sentinel ASIM Parser demystified - March 31, 2024
- Enhancing Network Security Insights with IDS/IPS of Ubiquiti Dream Machine Pro and Microsoft Sentinel - March 10, 2024
- Ubiquiti Dream Machine Pro Logs to Microsoft Sentinel - February 6, 2024
7 Comments
Rizwan Ayub · October 8, 2019 at 15:46
Hi Thomas
After renaming the devices,
Associated Intune Device Name = Changes to Correct
Active Directory = Changes to Correct Name
Hybrid Azure AD joined = Changes to Correct
Azure AD joined = Doesn’t Change – Stays the Same even after 24hours
COuld you please help with the resolve
Thomas Kurth · October 9, 2019 at 14:08
Hello Rizwan
Have you renamed the device via SCCM? or how do you do this?
Are you using Windows 1903? Then it should work:
https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/12980892-machine-rename-azure-ad
Rizwan · October 16, 2019 at 16:56
I have noticed that devi e idnis different in intune abd in azure. Some thing i am doing it wrong
I am using the powowershell from intune to rename the device as sccm takes too long to work. Could tht be the cause. If it is please inform
Best practices for base installation
Rizwan · October 16, 2019 at 17:01
1903 inuse
Using the powershell from intune
Sccm baseline configuration not running straight away. As device get build with incorrect random name
I have added the asset Information on the Device and instead of serial number i am using the asset id
During the script it changes the device name.
But notice that id is different on intune and azure ad
Thomas Kurth · October 17, 2019 at 11:44
OK, that sounds like a strange issue if you have different device id’s in Azure AD and Intune. I suggest to open an MS Case for this.
If you rename a device manually over the UI is it then updating in all systems. If it renames in Active Directory on-prem. Is it then not synced to Azure AD?
Rizwan · October 17, 2019 at 09:12
Hello Thomas
Rename is done through script in Intune during the device preparation process. Using SMbios to pick asset info.
If used SCCM to deploy baseline as suggested. The rename wont happen till late. Unless that is the only way this should be implemented.
Please advise
Dowst.Dev | PowerShell Weekly – June 28, 2019 · June 28, 2019 at 13:37
[…] Automatic environment cleanup with Intune Connector for AD Extender Thomas Kurth provides great examples on how to keep your environment clean, using automatic cleanup of Intune Devices and ActiveDirectory Computer Accounts with PowerShell. […]