EnhancedIntuneAO.psm1
#Region '.\Public\Check-IntuneCertificates.ps1' -1 function Check-IntuneCertificates { <# .SYNOPSIS Checks for the presence of certificates in the specified certificate store, issued by a specified issuer, within a given timeout period. .DESCRIPTION This function waits for up to a specified timeout for certificates to be created in the specified certificate store, looking specifically for certificates issued by the provided issuer name. It logs the waiting process and the outcome, successfully finding the certificates or timing out. .PARAMETER CertStorePath The path of the certificate store to check for certificates. Default is the local machine's personal certificate store. .PARAMETER IssuerName The name of the issuer to check for in the certificates. Default is "CN=Microsoft Intune MDM Device CA". .PARAMETER Timeout The maximum amount of time, in seconds, to wait for the certificates. Default is 30 seconds. .EXAMPLE Check-IntuneCertificates Checks for certificates issued by Microsoft Intune in the local machine's personal certificate store with the default timeout of 30 seconds. .EXAMPLE Check-IntuneCertificates -CertStorePath 'Cert:\LocalMachine\My\' -IssuerName "CN=Microsoft Intune MDM Device CA" -Timeout 60 Checks for certificates with a custom timeout of 60 seconds in the specified certificate store and issuer. .NOTES Ensure that the 'Write-EnhancedLog' function is defined in your environment for logging. #> [CmdletBinding()] Param( [Parameter(Mandatory = $false, HelpMessage = "Specify the certificate store path to check.")] [ValidateNotNullOrEmpty()] [string]$CertStorePath = 'Cert:\LocalMachine\My\', [Parameter(Mandatory = $false, HelpMessage = "Specify the issuer name to check.")] [ValidateNotNullOrEmpty()] [string]$IssuerName = "CN=Microsoft Intune MDM Device CA", [Parameter(Mandatory = $false, HelpMessage = "Specify the maximum time (in seconds) to wait for the certificate.")] [ValidateRange(1, 300)] [int]$Timeout = 30 ) Begin { Write-EnhancedLog -Message "Starting Check-IntuneCertificates function." -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters Write-EnhancedLog -Message "Waiting for certificates from issuer: $IssuerName in store: $CertStorePath" -Level "INFO" } Process { try { $remainingTime = $Timeout # Loop to wait for the certificate to appear, or until the timeout is reached while ($remainingTime -gt 0) { try { $certificates = Get-ChildItem -Path $CertStorePath | Where-Object { $_.Issuer -match $IssuerName } } catch { Write-EnhancedLog -Message "Error accessing certificates in path: $CertStorePath. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } if ($certificates) { Write-EnhancedLog -Message "Certificate(s) found for issuer: $IssuerName." -Level "INFO" break } Write-EnhancedLog -Message "Waiting... ($remainingTime seconds remaining)" -Level "INFO" Start-Sleep -Seconds 1 $remainingTime-- } # Check if the loop ended due to timeout if ($remainingTime -eq 0) { Write-EnhancedLog -Message "Timed out waiting for certificate from issuer: $IssuerName in store: $CertStorePath" -Level "WARNING" } } catch { Write-EnhancedLog -Message "An error occurred during the certificate check process. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } } End { Write-EnhancedLog -Message "Check-IntuneCertificates function has completed." -Level "Notice" } } #EndRegion '.\Public\Check-IntuneCertificates.ps1' 92 #Region '.\Public\Check-RegistryKeys.ps1' -1 function Check-RegistryKeys { <# .SYNOPSIS Checks for specific registry keys under given GUIDs and outputs their subkeys and values. .DESCRIPTION The Check-RegistryKeys function searches the registry under "HKLM:\SOFTWARE\Microsoft\Enrollments" for specified GUIDs, checks for specific subkeys (DeviceEnroller, DMClient, Poll, Push), and lists all items within these subkeys as a table of key name and value pairs. .PARAMETER EnrollmentGUIDs The GUIDs under which to search for specific registry subkeys. .EXAMPLE Check-RegistryKeys -EnrollmentGUIDs @("GUID1", "GUID2") Searches for and lists details of specific registry subkeys under the specified GUIDs. .NOTES Ensure the 'Write-EnhancedLog' function is defined in your environment for logging. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Provide the Enrollment GUIDs to search for.")] [ValidateNotNullOrEmpty()] [string[]]$EnrollmentGUIDs ) Begin { Write-EnhancedLog -Message "Starting registry key check for specified GUIDs." -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters # Base registry path $BaseKey = "HKLM:\SOFTWARE\Microsoft\Enrollments" Write-EnhancedLog -Message "Checking registry base path: $BaseKey" -Level "INFO" # Initialize an array to store the properties of found subkeys $allProperties = [System.Collections.Generic.List[PSCustomObject]]::new() } Process { foreach ($GUID in $EnrollmentGUIDs) { $GUIDPath = Join-Path -Path $BaseKey -ChildPath $GUID Write-EnhancedLog -Message "Processing GUID: $GUID" -Level "INFO" if (Test-Path -Path $GUIDPath) { Write-EnhancedLog -Message "Found registry path: $GUIDPath" -Level "INFO" try { $SubKeys = Get-ChildItem -Path $GUIDPath -ErrorAction Stop foreach ($SubKey in $SubKeys) { if ($SubKey.Name -match "DeviceEnroller|DMClient|Poll|Push") { $SubKeyProperties = Get-ItemProperty -Path $SubKey.PSPath foreach ($Property in $SubKeyProperties.PSObject.Properties) { # Add each property to the list as a custom object $allProperties.Add([PSCustomObject]@{ SubKeyName = $SubKey.PSChildName PropertyName = $Property.Name PropertyValue = $Property.Value }) } } else { Write-EnhancedLog -Message "No relevant subkeys (DeviceEnroller, DMClient, Poll, Push) found under $GUIDPath." -Level "WARNING" } } } catch { Write-EnhancedLog -Message "Error retrieving subkeys for GUID $GUID. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } else { Write-EnhancedLog -Message "GUID $GUID not found under $BaseKey." -Level "WARNING" } } } End { # Output all collected properties in a table if ($allProperties.Count -gt 0) { Write-EnhancedLog -Message "Displaying properties found in relevant subkeys." -Level "INFO" $allProperties | Format-Table -AutoSize } else { Write-EnhancedLog -Message "No relevant properties found under the specified GUIDs." -Level "WARNING" } Write-EnhancedLog -Message "Completed registry key check for specified GUIDs." -Level "Notice" } } #EndRegion '.\Public\Check-RegistryKeys.ps1' 92 #Region '.\Public\Check-TaskSchedulerEntriesAndTasks.ps1' -1 function Check-TaskSchedulerEntriesAndTasks { <# .SYNOPSIS Checks for scheduled tasks and their folders related to a specific Enrollment GUID. .DESCRIPTION The Check-TaskSchedulerEntriesAndTasks function lists all scheduled tasks under the Enterprise Management path that match the specified Enrollment GUID. It also checks for the existence of corresponding task folders. .PARAMETER EnrollmentGUID The GUID of the enrollment entries related to the tasks to be checked. .EXAMPLE Check-TaskSchedulerEntriesAndTasks -EnrollmentGUID "YourGUIDHere" Lists all scheduled tasks and checks folders under Enterprise Management that match the given GUID. .NOTES Uses Write-EnhancedLog for logging information. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Specify the Enrollment GUID.")] [ValidateNotNullOrEmpty()] [string]$EnrollmentGUID ) Begin { Write-EnhancedLog -Message "Starting Check-TaskSchedulerEntriesAndTasks for GUID: $EnrollmentGUID" -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters # Initialize Task Scheduler connection try { Write-EnhancedLog -Message "Connecting to Task Scheduler service." -Level "INFO" $taskScheduler = New-Object -ComObject Schedule.Service $taskScheduler.Connect() } catch { Write-EnhancedLog -Message "Failed to connect to Task Scheduler service. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } } Process { Write-EnhancedLog -Message "Searching for scheduled tasks matching GUID: $EnrollmentGUID" -Level "INFO" # Search for tasks under the Task Scheduler try { $tasksFound = Get-ScheduledTask | Where-Object { $_.TaskPath -match $EnrollmentGUID } if ($tasksFound.Count -gt 0) { foreach ($task in $tasksFound) { Write-EnhancedLog -Message "Found task: $($task.TaskName)" -Level "INFO" } } else { Write-EnhancedLog -Message "No tasks found for GUID: $EnrollmentGUID" -Level "WARNING" } } catch { Write-EnhancedLog -Message "Error while searching for tasks: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } # Check for the existence of task folders $taskFolders = @( "$env:WINDIR\System32\Tasks\Microsoft\Windows\EnterpriseMgmt\$EnrollmentGUID", "$env:WINDIR\System32\Tasks\Microsoft\Windows\EnterpriseMgmtNoncritical\$EnrollmentGUID" ) foreach ($taskFolder in $taskFolders) { if (Test-Path $taskFolder) { Write-EnhancedLog -Message "Found task folder at path: $taskFolder" -Level "INFO" } else { Write-EnhancedLog -Message "No task folder found at path: $taskFolder" -Level "WARNING" } } } End { Write-EnhancedLog -Message "Task Scheduler entry and folder check for GUID: $EnrollmentGUID completed." -Level "Notice" } } #EndRegion '.\Public\Check-TaskSchedulerEntriesAndTasks.ps1' 85 #Region '.\Public\Enable-MDMAutoEnrollment.ps1' -1 function Enable-MDMAutoEnrollment { <# .SYNOPSIS Enables MDM AutoEnrollment by creating necessary registry entries and invoking the enrollment process. .DESCRIPTION This function checks if the required registry key and property for MDM AutoEnrollment are present. If not, it creates them and invokes the device enrollment process using `deviceenroller.exe`. .NOTES Ensure the 'Write-EnhancedLog' function is defined for logging, and the `Check-IntuneCertificates` function is available for certificate verification after enrollment. #> [CmdletBinding()] Param() Begin { Write-EnhancedLog -Message "Starting MDM AutoEnrollment process." -Level "Notice" } Process { try { $registryPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\MDM" # Check if the registry key exists if (-not (Test-Path $registryPath)) { Write-EnhancedLog -Message "Creating registry key for MDM AutoEnrollment: $registryPath" -Level "INFO" New-Item -Path $registryPath -ErrorAction Stop | Out-Null } else { Write-EnhancedLog -Message "Registry key for MDM AutoEnrollment already exists. Skipping creation." -Level "INFO" } # Check if the AutoEnrollMDM property exists try { $propertyExists = [bool](Get-ItemProperty -Path $registryPath -Name AutoEnrollMDM -ErrorAction Stop) } catch { $propertyExists = $false } # Set the AutoEnrollMDM property if it doesn't exist if (-not $propertyExists) { Write-EnhancedLog -Message "Setting AutoEnrollMDM property in $registryPath." -Level "INFO" New-ItemProperty -Path $registryPath -Name AutoEnrollMDM -Value 1 -ErrorAction Stop | Out-Null } else { Write-EnhancedLog -Message "AutoEnrollMDM property already exists. Skipping." -Level "INFO" } # Invoke the device enrollment process Write-EnhancedLog -Message "Invoking device enrollment process with deviceenroller.exe." -Level "INFO" & "$env:windir\system32\deviceenroller.exe" /c /AutoEnrollMDM Write-EnhancedLog -Message "MDM AutoEnrollment process completed successfully." -Level "Success" } catch { Write-EnhancedLog -Message "An error occurred during the MDM AutoEnrollment process. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "MDM AutoEnrollment function has completed." -Level "Notice" # Optional post-check for certificates after enrollment Write-EnhancedLog -Message "Checking for Intune certificates post enrollment." -Level "INFO" Check-IntuneCertificates } } # Example invocation # Enable-MDMAutoEnrollment #EndRegion '.\Public\Enable-MDMAutoEnrollment.ps1' 73 #Region '.\Public\Get-ManagementGUID.ps1' -1 function Get-ManagementGUID { [CmdletBinding()] param ( [string]$taskRoot = "\Microsoft\Windows\EnterpriseMgmt" ) Begin { Write-EnhancedLog -Message "Starting Get-ManagementGUID function" -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters # Initialize variables and objects try { Write-EnhancedLog -Message "Connecting to the Task Scheduler service." -Level "INFO" $taskScheduler = New-Object -ComObject Schedule.Service $taskScheduler.Connect() # Initialize a list to store collected GUIDs $EnrollmentGUIDs = [System.Collections.Generic.List[object]]::new() # Regular expression to validate GUID format $guidRegex = '^[{(]?[0-9A-Fa-f]{8}[-]?(?:[0-9A-Fa-f]{4}[-]?){3}[0-9A-Fa-f]{12}[)}]?$' } catch { Write-EnhancedLog -Message "Failed to connect to the Task Scheduler service. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } } Process { Write-EnhancedLog -Message "Checking if the task root exists: $taskRoot" -Level "INFO" try { $rootFolder = $taskScheduler.GetFolder($taskRoot) if ($null -eq $rootFolder) { Write-EnhancedLog -Message "Task root '$taskRoot' does not exist." -Level "WARNING" return } Write-EnhancedLog -Message "Task root exists. Retrieving subfolders from the task root: $taskRoot" -Level "INFO" $subfolders = $rootFolder.GetFolders(0) } catch { if ($_.Exception.HResult -eq -2147024894) { # HRESULT for "The system cannot find the file specified" Write-EnhancedLog -Message "The task root '$taskRoot' does not exist or cannot be found." -Level "WARNING" } else { Write-EnhancedLog -Message "Failed to retrieve subfolders from '$taskRoot'. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } return } foreach ($folder in $subfolders) { if ($folder.Name -match $guidRegex) { Write-EnhancedLog -Message "Valid GUID found: $($folder.Name)" -Level "INFO" try { $EnrollmentGUIDs.Add($folder.Name) } catch { Write-EnhancedLog -Message "Failed to add GUID: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } else { Write-EnhancedLog -Message "Skipping non-GUID folder: $($folder.Name)" -Level "INFO" } } } End { if ($EnrollmentGUIDs.Count -gt 0) { Write-EnhancedLog -Message "Successfully collected $($EnrollmentGUIDs.Count) GUID(s)." -Level "INFO" return $EnrollmentGUIDs } else { Write-EnhancedLog -Message "No GUIDs found in the task root '$taskRoot'." -Level "WARNING" } Write-EnhancedLog -Message "Completed Get-ManagementGUID function" -Level "Notice" } } #EndRegion '.\Public\Get-ManagementGUID.ps1' 81 #Region '.\Public\Perform-IntuneCleanup.ps1' -1 function Perform-IntuneCleanup { <# .SYNOPSIS Performs an Intune cleanup by removing MDM certificates, task scheduler entries, and registry keys associated with Intune enrollment GUIDs. .DESCRIPTION This function first checks for Intune-related certificates, removes MDM certificates, and cleans up task scheduler entries, registry keys, and associated GUIDs related to Intune. It also performs checks before and after the cleanup to verify that the cleanup was successful. Finally, it provides a summary report of the cleanup process. .NOTES Assumes that `Check-IntuneCertificates`, `Remove-MDMCertificates`, `Get-ManagementGUID`, `Check-RegistryKeys`, `Check-TaskSchedulerEntriesAndTasks`, `Remove-TaskSchedulerEntriesAndTasks`, and `Remove-RegistryEntries` are defined elsewhere in the script or module. #> [CmdletBinding()] param () Begin { # Initialize counters and summary table $successCount = 0 $warningCount = 0 $errorCount = 0 $summaryTable = [System.Collections.Generic.List[PSCustomObject]]::new() Write-EnhancedLog -Message "Starting Intune cleanup process." -Level "Notice" } Process { try { # Check for Intune-related certificates before removal. Write-EnhancedLog -Message "Checking for Intune certificates before removal." -Level "INFO" Check-IntuneCertificates # Define the parameters for certificate removal in a hashtable and call with splatting. $certParams = @{ CertStorePath = 'Cert:\LocalMachine\My\' IssuerName = "CN=Microsoft Intune MDM Device CA" } Write-EnhancedLog -Message "Removing MDM certificates." -Level "INFO" Remove-MDMCertificates @certParams # Check for Intune-related certificates after removal. Write-EnhancedLog -Message "Re-checking for Intune certificates after removal." -Level "INFO" Check-IntuneCertificates # Obtain the current management GUIDs. Write-EnhancedLog -Message "Retrieving enrollment GUIDs." -Level "INFO" $EnrollmentGUIDs = Get-ManagementGUID if ($EnrollmentGUIDs.Count -eq 0) { Write-EnhancedLog -Message "No enrollment GUIDs found. Exiting cleanup process." -Level "Warning" $warningCount++ return } foreach ($EnrollmentGUID in $EnrollmentGUIDs) { Write-EnhancedLog -Message "Processing cleanup for enrollment GUID: $EnrollmentGUID" -Level "INFO" # Check registry keys before cleanup. Write-EnhancedLog -Message "Checking registry keys before cleanup for GUID: $EnrollmentGUID." -Level "INFO" Check-RegistryKeys -EnrollmentGUIDs @($EnrollmentGUID) # Check task scheduler entries before cleanup. Write-EnhancedLog -Message "Checking task scheduler entries for GUID: $EnrollmentGUID." -Level "INFO" Check-TaskSchedulerEntriesAndTasks -EnrollmentGUID $EnrollmentGUID # Remove task scheduler entries. Write-EnhancedLog -Message "Removing task scheduler entries for GUID: $EnrollmentGUID." -Level "INFO" Remove-TaskSchedulerEntriesAndTasks -EnrollmentGUID $EnrollmentGUID # Verify task scheduler entries after removal. Write-EnhancedLog -Message "Verifying task scheduler entries cleanup for GUID: $EnrollmentGUID." -Level "INFO" Check-TaskSchedulerEntriesAndTasks -EnrollmentGUID $EnrollmentGUID # Remove registry entries associated with the GUID. Write-EnhancedLog -Message "Removing registry entries for GUID: $EnrollmentGUID." -Level "INFO" Remove-RegistryEntries -EnrollmentGUID $EnrollmentGUID # Verify registry cleanup after removal. Write-EnhancedLog -Message "Verifying registry cleanup for GUID: $EnrollmentGUID." -Level "INFO" Check-RegistryKeys -EnrollmentGUIDs @($EnrollmentGUID) # Add success record to the summary table $summaryTable.Add([PSCustomObject]@{ EnrollmentGUID = $EnrollmentGUID Status = "Success" }) $successCount++ } Write-EnhancedLog -Message "Intune cleanup process completed." -Level "Success" -ForegroundColor Green } catch { Write-EnhancedLog -Message "An error occurred during the Intune cleanup process. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ $errorCount++ $summaryTable.Add([PSCustomObject]@{ EnrollmentGUID = $EnrollmentGUID Status = "Failed" }) } } End { # Final Summary Report Write-EnhancedLog -Message "----------------------------------------" -Level "INFO" Write-EnhancedLog -Message "Final Cleanup Summary Report" -Level "NOTICE" Write-EnhancedLog -Message "Total GUIDs processed: $($successCount + $warningCount + $errorCount)" -Level "INFO" Write-EnhancedLog -Message "Successfully processed GUIDs: $successCount" -Level "INFO" Write-EnhancedLog -Message "Warnings: $warningCount" -Level "WARNING" Write-EnhancedLog -Message "Failed GUIDs: $errorCount" -Level "ERROR" Write-EnhancedLog -Message "----------------------------------------" -Level "INFO" # Color-coded summary for the console Write-Host "----------------------------------------" -ForegroundColor White Write-Host "Final Intune Cleanup Summary Report" -ForegroundColor Cyan Write-Host "Total GUIDs processed: $($successCount + $warningCount + $errorCount)" -ForegroundColor White Write-Host "Successfully processed GUIDs: $successCount" -ForegroundColor Green Write-Host "Warnings: $warningCount" -ForegroundColor Yellow Write-Host "Failed GUIDs: $errorCount" -ForegroundColor Red Write-Host "----------------------------------------" -ForegroundColor White # Display the summary table of GUIDs and their statuses Write-Host "Intune Cleanup Summary:" -ForegroundColor Cyan $summaryTable | Format-Table -AutoSize # Optionally log the summary to the enhanced log as well foreach ($row in $summaryTable) { Write-EnhancedLog -Message "EnrollmentGUID: $($row.EnrollmentGUID), Status: $($row.Status)" -Level "INFO" } } } #EndRegion '.\Public\Perform-IntuneCleanup.ps1' 132 #Region '.\Public\Remove-MDMCertificates.ps1' -1 function Remove-MDMCertificates { <# .SYNOPSIS Removes MDM certificates from the specified certificate store based on issuer name. .DESCRIPTION The Remove-MDMCertificates function searches for and removes certificates from the specified certificate store path that are issued by the specified issuer, logging each removal action. .PARAMETER CertStorePath The path of the certificate store from which to remove certificates. .PARAMETER IssuerName The name of the issuer whose certificates should be removed. .EXAMPLE $parameters = @{ CertStorePath = 'Cert:\LocalMachine\My\' IssuerName = "CN=Microsoft Intune MDM Device CA" } Remove-MDMCertificates @parameters Removes all MDM certificates issued by Microsoft Intune from the LocalMachine's My certificate store. .NOTES Uses Write-EnhancedLog for detailed logging. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Provide the certificate store path.")] [ValidateNotNullOrEmpty()] [string]$CertStorePath, [Parameter(Mandatory = $true, HelpMessage = "Provide the issuer name to filter certificates by.")] [ValidateNotNullOrEmpty()] [string]$IssuerName ) Begin { Write-EnhancedLog -Message "Starting Remove-MDMCertificates function" -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters # Validate the certificate store path if (-not (Test-Path $CertStorePath)) { throw "The specified certificate store path does not exist: $CertStorePath" } Write-EnhancedLog -Message "Searching for certificates in store: $CertStorePath with issuer: $IssuerName" -Level "INFO" } Process { try { # Retrieve certificates issued by the specified issuer $mdmCerts = Get-ChildItem -Path $CertStorePath | Where-Object Issuer -eq $IssuerName if ($mdmCerts.Count -eq 0) { Write-EnhancedLog -Message "No certificates found from issuer: $IssuerName in $CertStorePath" -Level "Warning" return } # Loop through and remove each certificate foreach ($cert in $mdmCerts) { Write-EnhancedLog -Message "Removing certificate issued by $IssuerName $($cert.Subject)" -Level "INFO" Remove-Item -Path $cert.PSPath -ErrorAction Stop Write-EnhancedLog -Message "Successfully removed certificate: $($cert.Subject)" -Level "INFO" } } catch { Write-EnhancedLog -Message "An error occurred while removing certificates: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ throw } } End { Write-EnhancedLog -Message "Completed Remove-MDMCertificates function" -Level "Notice" } } #EndRegion '.\Public\Remove-MDMCertificates.ps1' 78 #Region '.\Public\Remove-RegistryEntries.ps1' -1 function Remove-RegistryEntries { <# .SYNOPSIS Removes specified registry entries under the Microsoft Enrollments key that match a given GUID. .DESCRIPTION The Remove-RegistryEntries function searches for and removes registry keys under "HKLM:\SOFTWARE\Microsoft\Enrollments" that match the specified EnrollmentGUID. It logs the process, including successes and warnings, using the Write-EnhancedLog function. .PARAMETER EnrollmentGUID The GUID of the enrollment entries to be removed from the registry. .EXAMPLE Remove-RegistryEntries -EnrollmentGUID "12345678-1234-1234-1234-1234567890ab" Removes all registry entries under Microsoft Enrollments that match the given GUID. .NOTES Uses the Write-EnhancedLog function for logging. Ensure this function is defined in your script or module. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Provide the Enrollment GUID for the registry entries to be removed.")] [ValidateNotNullOrEmpty()] [string]$EnrollmentGUID ) Begin { Write-EnhancedLog -Message "Starting registry entry removal for GUID: $EnrollmentGUID" -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters # Define the registry path to search for enrollment entries $RegistryKeyPath = "HKLM:\SOFTWARE\Microsoft\Enrollments" Write-EnhancedLog -Message "Checking registry path: $RegistryKeyPath" -Level "INFO" } Process { try { if (Test-Path -Path $RegistryKeyPath) { # Get and remove registry entries matching the Enrollment GUID $registryEntries = Get-ChildItem -Path $RegistryKeyPath | Where-Object { $_.Name -match $EnrollmentGUID } if ($registryEntries.Count -gt 0) { foreach ($entry in $registryEntries) { try { Remove-Item -Path $entry.PSPath -Recurse -Force -ErrorAction Stop Write-EnhancedLog -Message "Removed registry entry for GUID: $EnrollmentGUID from path: $($entry.PSPath)" -Level "INFO" } catch { Write-EnhancedLog -Message "Error removing registry entry at $($entry.PSPath). Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } } else { Write-EnhancedLog -Message "No registry entries found matching GUID: $EnrollmentGUID under $RegistryKeyPath" -Level "WARNING" } } else { Write-EnhancedLog -Message "Registry key path $RegistryKeyPath not found." -Level "WARNING" } } catch { Write-EnhancedLog -Message "An error occurred while accessing the registry path $RegistryKeyPath. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Completed registry entry removal for GUID: $EnrollmentGUID" -Level "Notice" } } #EndRegion '.\Public\Remove-RegistryEntries.ps1' 73 #Region '.\Public\Remove-TaskSchedulerEntriesAndTasks.ps1' -1 function Remove-TaskSchedulerEntriesAndTasks { <# .SYNOPSIS Removes scheduled tasks and their folders related to a specific Enrollment GUID. .DESCRIPTION The Remove-TaskSchedulerEntriesAndTasks function finds and removes all scheduled tasks under the Enterprise Management path that match the specified Enrollment GUID. It also removes the corresponding task folders if they exist. .PARAMETER EnrollmentGUID The GUID of the enrollment entries related to the tasks to be removed. .EXAMPLE Remove-TaskSchedulerEntriesAndTasks -EnrollmentGUID "YourGUIDHere" Removes all scheduled tasks and folders under Enterprise Management that match the given GUID. .NOTES Uses Write-EnhancedLog for logging steps and outcomes. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = "Provide the Enrollment GUID for the tasks and folders to be removed.")] [ValidateNotNullOrEmpty()] [string]$EnrollmentGUID ) Begin { Write-EnhancedLog -Message "Starting Remove-TaskSchedulerEntriesAndTasks for GUID: $EnrollmentGUID" -Level "Notice" Log-Params -Params $PSCmdlet.MyInvocation.BoundParameters try { Write-EnhancedLog -Message "Connecting to Task Scheduler service." -Level "INFO" $taskScheduler = New-Object -ComObject Schedule.Service $taskScheduler.Connect() } catch { Write-EnhancedLog -Message "Failed to connect to Task Scheduler service. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ return } # Initialize an array to store unregistered tasks information $unregisteredTasks = [System.Collections.Generic.List[PSCustomObject]]::new() } Process { try { Write-EnhancedLog -Message "Removing scheduled tasks for GUID: $EnrollmentGUID" -Level "INFO" # Search for tasks matching the Enrollment GUID and unregister them $tasks = Get-ScheduledTask | Where-Object { $_.TaskPath -match $EnrollmentGUID } foreach ($task in $tasks) { try { Unregister-ScheduledTask -TaskName $task.TaskName -Confirm:$false Write-EnhancedLog -Message "Unregistered task: $($task.TaskName)" -Level "INFO" # Add unregistered task details to the list $unregisteredTasks.Add([PSCustomObject]@{ TaskName = $task.TaskName TaskPath = $task.TaskPath }) } catch { Write-EnhancedLog -Message "Failed to unregister task: $($task.TaskName). Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } # Paths to task folders for removal $taskFolders = @( "$env:WINDIR\System32\Tasks\Microsoft\Windows\EnterpriseMgmt\$EnrollmentGUID", "$env:WINDIR\System32\Tasks\Microsoft\Windows\EnterpriseMgmtNoncritical\$EnrollmentGUID" ) # Remove the task folders foreach ($folderPath in $taskFolders) { if (Test-Path $folderPath) { try { Remove-Item -Path $folderPath -Force -ErrorAction Stop Write-EnhancedLog -Message "Removed task folder at path: $folderPath" -Level "INFO" } catch { Write-EnhancedLog -Message "Failed to remove task folder at path: $folderPath. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } else { Write-EnhancedLog -Message "Task folder not found at path: $folderPath" -Level "WARNING" } } # Remove parent folder from Task Scheduler try { $rootFolder = $taskScheduler.GetFolder("\") $rootFolder.DeleteFolder("\Microsoft\Windows\EnterpriseMgmt\$EnrollmentGUID", 0) Write-EnhancedLog -Message "Parent task folder for GUID - $EnrollmentGUID removed successfully" -Level "INFO" } catch { Write-EnhancedLog -Message "Failed to remove parent task folder for GUID - $EnrollmentGUID. Error: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } catch { Write-EnhancedLog -Message "Error during task and folder cleanup: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { # Display unregistered tasks if ($unregisteredTasks.Count -gt 0) { Write-EnhancedLog -Message "Unregistered tasks for GUID: $EnrollmentGUID" -Level "INFO" $unregisteredTasks | Format-Table -AutoSize } else { Write-EnhancedLog -Message "No tasks were found or unregistered for GUID: $EnrollmentGUID" -Level "WARNING" } Write-EnhancedLog -Message "Cleanup process for GUID: $EnrollmentGUID completed." -Level "Notice" } } #EndRegion '.\Public\Remove-TaskSchedulerEntriesAndTasks.ps1' 122 |