This script runs automatically when the ODMAD task runs.
This script searches the HKLM\SOFTWARE\Microsoft\Provisioning and the HKLM\SOFTWARE\Microsoft\Provisioning\Diagnostics for child keys that have Autopilot in their names. It will then delete these values and keys from the workstation.
Autopilot Cleanup.txt
Param ( |
) |
$output = New-Object BinaryTree.ADM.Agent.PSHelpers.PSOutput |
### Script Configurable Parameters ### |
# Parent Regisry Keys to search # |
$RegistryKeys = "HKLM:\SOFTWARE\Microsoft\Provisioning" , "HKLM:\SOFTWARE\Microsoft\Provisioning\Diagnostics" |
###################################### |
Write-Output "Evaluating $($RegistryKeys.Count) Registry Hive(s)" |
ForEach ($Key in $RegistryKeys) { |
Write-Output " Processing: $($Key)" |
If (Test-Path -Path $Key) { |
$StoreKey = Get-ChildItem -Path $Key | Where-Object {$_.Name -like '*Autopilot*'} |
Write-Output " Processing $($Storekey.Name.Count) Registry Entries" |
ForEach($S in $StoreKey){ |
Write-Output " $($S)" |
} |
Write-Output " Removing Registry Keys" |
ForEach($S in $Storekey){ |
Write-Output " Removing: $($S)" |
$S | Remove-Item -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue |
$KeyTest = Get-Item -Path Registry::$S -ErrorAction SilentlyContinue |
If([string]::IsNullOrWhitespace($KeyTest)){ |
Write-Output " Delete Suceeded" |
} |
Else{ |
Write-Output " Delete Failed" |
$KeyTest = $Null |
` } |
} |
} |
} |
return ($output) |
To allow enrolling the workstation into the target Intune, it is important to remove the source Intune Enrollment information. Otherwise, the workstation thinks that it is already part of an Intune Enrollment and will not try to enroll in the target.
This script will find the Intune Enrollment ID from the Scheduled Task that Intune uses. The script then searches the following parent registry keys for the EnrollmentID and removes the registry values and Keys:
HKLM:\SOFTWARE\Microsoft\Enrollments
HKLM:\SOFTWARE\Microsoft\Enrollments\Status
HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked
HKLM:\SOFTWARE\Microsoft\PolicyManager\AdmxInstalled
HKLM:\SOFTWARE\Microsoft\PolicyManager\Providers
HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts
HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Logger
HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Sessions
The script will also remove the Intune Enrollment Scheduled Task (this task will automatically get recreated when the machine joins the target tenant) and will remove the existing Intune Certificate from the Computer Certificate store.
Intune Cleanup.txt
Param ( |
) |
$output = New-Object BinaryTree.ADM.Agent.PSHelpers.PSOutput |
### Script Configurable Parameters ### |
# Declare Parent Registry Keys to search for EnrollmentID # |
$RegistryKeys = "HKLM:\SOFTWARE\Microsoft\Enrollments", "HKLM:\SOFTWARE\Microsoft\Enrollments\Status","HKLM:\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked", "HKLM:\SOFTWARE\Microsoft\PolicyManager\AdmxInstalled", "HKLM:\SOFTWARE\Microsoft\PolicyManager\Providers","HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts", "HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Logger", "HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Sessions" |
###################################### |
Write-Output "Getting Intune Enrollment ID:" |
### Find the Intune EnrollmentID from Intune Enrollment Scheduled Task ### |
$EnrollmentID = Get-ScheduledTask | Where-Object {$_.TaskPath -like "*Microsoft*Windows*EnterpriseMgmt*"} | Select-Object -ExpandProperty TaskPath -Unique | Where-Object {$_ -like "*-*-*"} | Split-Path -Leaf |
Write-Output " Intune Enrollment ID: $($EnrollmentID)" |
If([string]::IsNullOrWhitespace($EnrollmentID)){ |
Write-Output " No Intune Enrollment ID Found..Terminating" |
Exit 0 |
} |
### Remove Intune Certificate from Certificate Store ### |
Write-Output "Removing Intune MDM Certificate" |
If((Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Issuer -match "Intune MDM"})){ |
Write-Output " Intune MDM Certificate Found..Collecting Certificate Information" |
$IntuneCert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Issuer -match "Intune MDM"} |
ForEach($Cert in $IntuneCert){ |
Write-Output " Found $($Cert.Subject)..Certificate will be removed" |
$Cert | Remove-Item |
$IntuneCertTest = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match $Cert.Subject} |
If([string]::IsNullOrWhitespace($IntuneCertTest)){ |
Write-Output " Delete Succeeded" |
} |
Else{Write-Output " Delete Failed"} |
$IntuneCertTest = $Null |
} |
} |
Else {Write-Output "Intune MDM Certificate Not Found"} |
### Delete Scheduled Tasks ### |
Write-Output "Finding Enrollment Scheduled Tasks" |
$ScheduledTasks = Get-ScheduledTask | Where-Object {$_.Taskpath -match $EnrollmentID} |
Write-Output " Evaluating $($ScheduledTasks.count) Scheduled Tasks:" |
ForEach($Task in $ScheduledTasks){ |
Write-Output " Found Task: $($Task.Taskname) with path: $($Task.TaskPath)" |
} |
Write-Output "Removing Intune Enrollment Scheduled Tasks" |
ForEach($T in $ScheduledTasks){ |
Write-Output " Removing $($T.Taskname)" |
#Get-ScheduledTask | Where-Object {$_.Taskname -match $T.TaskName} |
Get-ScheduledTask | Where-Object {$_.TaskName -match $T.TaskName} | Unregister-ScheduledTask -Confirm:$false |
$TestScheduledTask = Get-ScheduledTask | Where-Object {$_.Taskname -match $T.TaskName} |
If([string]::IsNullOrWhitespace($TestScheduledTask)){ |
Write-Output " Delete Succeeded" |
} |
Else{Write-Output " Delete Failed"} |
$TestScheduledTask = $Null |
} |
### Search Registry keys for EnrollmentID and Remove Registry Keys |
Write-Output "Removing Enrollment Registry Keys" |
Write-Output " Evaluating $($RegistryKeys.Count) Registry Hive(s)" |
Foreach ($K in $RegistryKeys) { |
Write-Output " $($K)" |
} |
Foreach ($Key in $RegistryKeys) { |
If (Test-Path -Path $Key) { |
Write-Output " Found: $($Key)" |
Get-ChildItem -Path $Key | Where-Object {$_.Name -match $EnrollmentID} | Remove-Item -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue |
} |
If (Test-Path -Path $Key){ |
Write-Output " Deleted Failed" |
} |
Else{Write-Output " Deleted Succeeded"} |
} |
return ($output) |
When the machine enrolls in the target Intune, it will look for an Intune Licensed user in M365 using the UserEmail value found in the workstation registry. By default, this value is set to the Bulk Enrollment user, which does not have the relevant license, and prevents the Intune service from running correctly.
This script creates a separate PowerShell script on the workstation called UpdateCloudJoinInfo.ps1 in the ODMAD agent folder and creates a Scheduled Task to execute UpdateCloudJoinInfo.ps1 when the first target user logs on.
When the UpdateCloudJoinInfo script runs during the first login post-migration, it will update the UserEmail value in the following registry key, setting it to the UPN of the logged-on target user.
HKLM:\System\CurrentControlSet\Control\CloudDomainJoin\JoinInfo
The script will also create a log file in the ODM agent Files folder and then perform cleanup to remove the Scheduled Task and remove the script itself.
SetUserEmailValues.txt
Param ( |
) |
$output = New-Object BinaryTree.ADM.Agent.PSHelpers.PSOutput |
Try{ |
$ODMADService = Get-Service -Name ODMActiveDirectory -ErrorAction SilentlyContinue |
} |
Catch{ |
Write-Output "Error Retrieving Service Status...Terminating with error: $($Error)" |
Exit 1 |
} |
If($ODMADService){ |
Write-Output "ODM AD Agent Service Found...Finding ODM AD Agent Service Path" |
$ODMADServicePath = (Get-ItemProperty -Path HKLM:SYSTEM\CurrentControlSet\Services\ODMActiveDirectory).ImagePath |
$ODMAgentPath = Split-Path $ODMADServicePath |
$ODMAgentPath = $ODMAgentPath.Trim("`"") |
Write-Output "ODM AD Service Path: $($ODMAgentPath)" |
} |
Else{ |
Write-Output "No ODM Agent Service Found...Terminating" |
Exit 1 |
} |
$ScriptName = "UpdateCloudJoinInfo.ps1" |
##### The $Script contains the PS script that gets create in the ODMAD agent folder. |
$Script = @" |
`$TranscriptFile = "`$(`$ODMAgentPath)\Files\PowerShell-`$(Get-Date -f yyyyMMdd-HHMM)-UpdateCloudDomainJoinReg.log" |
Start-Transcript -Path `$TranscriptFile |
Try{ |
`$ODMADService = Get-Service -Name ODMActiveDirectory |
} |
Catch{ |
Write-Output "Error Retrieving Service Status...Terminating with error: `$(`$Error)" |
Exit 1 |
{ |
If(`$ODMADService){ |
Write-Output "ODM AD Agent Service Found...Finding ODM AD Agent Service Path" |
`$ODMADServicePath = (Get-ItemProperty -Path HKLM:SYSTEM\CurrentControlSet\Services\ODMActiveDirectory).ImagePath |
`$ODMAgentPath = Split-Path `$ODMADServicePath |
`$ODMAgentPath = `$ODMAgentPath.Trim("``"") |
Write-Output "ODM AD Service Path: `$(`$ODMAgentPath)" |
} |
Else{ |
Write-Output "No ODM Agent Service Found...Terminating" |
Exit 1 |
} |
# Get Workgroup/AD User |
`$CurrentLoggedOnUser = (Get-CimInstance -Classname Win32_ComputerSystem | Select-Object -expand UserName) |
Write-Output " DEBUG: Current Logged On User: `$(`$CurrentLoggedOnUser)" |
`$LoggedonUserArray = `$CurrentLoggedOnUser.Split("\") |
`$LoggedonUser_Username = `$LoggedonUserArray[1] |
Write-Output " DEBUG: Current Logged On Username: `$(`$LoggedonUser_Username)" |
`$LoggedonUser_Domain = `$LoggedonUserArray[0] |
Write-Output " DEBUG: Current Logged On Domain: `$(`$LoggedonUser_Domain)" |
If (!([String]::IsNullOrWhiteSpace(`$CurrentLoggedOnUser))) |
{ |
`$CurrentUser = Get-Itemproperty "Registry::\HKEY_USERS\S-1-12*\Volatile Environment"|Where-Object {`$_.USERDOMAIN -match `$LoggedonUser_Domain} |
Write-Output " DEBUG: CurrentUser: `$(`$CurrentUser)" |
If (![String]::IsNullOrWhiteSpace(`$CurrentUser)) |
{ |
`$CurrentLoggedOnUser = "`$(`$CurrentUser.USERDOMAIN)\`$(`$CurrentUser.USERNAME)" |
Write-Output " DEBUG: Current Logged On User: `$(`$CurrentLoggedOnUser)" |
`$CurrentLoggedOnUserSID = split-path `$CurrentUser.PSParentPath -leaf |
Write-Output " DEBUG: Current Logged On User SID: `$(`$CurrentLoggedOnUserSID)" |
If(`$CurrentUser.USERDOMAIN -match `$LoggedonUser_Domain) |
{ |
`$UPNKeys = `$(reg query hklm\SOFTWARE\Microsoft\IdentityStore\LogonCache /reg:64).Split([Environment]::NewLine)| where{`$_ -ne ""} |
Write-Output " DEBUG: UPN Keys (Can be Multi-Valued): `$(`$UPNKeys)" |
ForEach (`$item in `$UPNKeys) |
{ |
`$UPN = reg @('query',"`$item\Sid2Name\`$CurrentLoggedOnUserSID",'/v','IdentityName','/reg:64') |
Write-Output " DEBUG: UPN: `$(`$UPN)" |
If (`$LASTEXITCODE -eq 0){`$CurrentLoggedOnUserUPN = (`$UPN[2] -split ' {2,}')[3] ; Break} |
} |
} |
} |
} |
Write-Output " DEBUG: Current Logged On User UPN: `$(`$CurrentLoggedOnUserUPN)" |
`$LoggedonUser = `$CurrentLoggedOnUserUPN |
Write-Output " DEBUG: Logged On User: `$(`$LoggedonUser)" |
## Get Tenant ID from Registry |
`$TenantInfoKey = "HKLM:\System\CurrentControlSet\Control\CloudDomainJoin\TenantInfo" |
If(Test-Path -Path `$TenantInfoKey) { |
`$TenantInfo = Get-ChildItem -Path `$TenantInfoKey |
`$TenantID = `$TenantInfo.Name.split("\")[-1] |
Write-Output " TenantID: `$(`$TenantID)" |
} |
`$JoinInfoPath = "HKLM:\System\CurrentControlSet\Control\CloudDomainJoin\JoinInfo" |
If(Test-Path -Path `$JoinInfoPath) { |
`$JoinInfo = Get-ChildItem -Path `$JoinInfoPath |
`$JoinInfoGUID = `$JoinInfo.Name.Split("\")[-1] |
`$ValuePath = `$JoinInfoPath+"\"+(`$JoinInfo.Name.Split("\")[-1]) |
`$UserEmailValue = (Get-ItemProperty -path `$ValuePath -Name UserEmail) |
Write-Output " Current UserEmail Value: `$(`$UserEmailValue)" |
If(`$UserEmailValue.UserEmail -ne `$LoggedonUser) { |
Write-Output " DEBUG: Will Change Value" |
Set-ItemProperty `$ValuePath -Name UserEmail -Value `$LoggedOnUser} |
} |
### Clean Up Environment |
Write-Output "Cleaning Up Script Environment, Deleteing files and removing Scheduled Task" |
Unregister-ScheduledTask -TaskName "Update Cloud Join Info" -Confirm:`$false |
Remove-Item -path "`$ODMAgentPath\$($ScriptName)" -Force |
Stop-Transcript |
"@ |
############################################################################################################ |
### Create Powershell Script |
$AgentPath = "$ODMAgentPath\" |
$ScriptFullName = $AgentPath+$ScriptName |
If(!(Test-Path $ScriptFullName)) { |
New-item -path $AgentPath -Name $ScriptName -Type "File" -Value $Script |
} |
$TaskName = "Update Cloud Join Info" |
$Argument = "-ExecutionPolicy Bypass -File `"$($ODMAgentPath)\$($ScriptName)`"" |
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument $Argument |
$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries |
$Principal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount |
$Trigger = New-ScheduledTaskTrigger -Atlogon |
$Trigger.Delay = "PT8M" |
$ScheduledTask = New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Settings |
# Register Scheduled Task |
Register-ScheduledTask -TaskName $TaskName -InputObject $ScheduledTask -User "NT AUTHORITY\SYSTEM" -Force |
return ($output) |
© 2024 Quest Software Inc. ALL RIGHTS RESERVED. Feedback Nutzungsbedingungen Datenschutz Cookie Preference Center