reset-EntraConnectObject.ps1
############################################################################################# # DISCLAIMER: # # # # THE SAMPLE SCRIPTS ARE NOT SUPPORTED UNDER ANY MICROSOFT STANDARD SUPPORT # # PROGRAM OR SERVICE. THE SAMPLE SCRIPTS ARE PROVIDED AS IS WITHOUT WARRANTY # # OF ANY KIND. MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING, WITHOUT # # LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR A PARTICULAR # # PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLE SCRIPTS # # AND DOCUMENTATION REMAINS WITH YOU. IN NO EVENT SHALL MICROSOFT, ITS AUTHORS, OR # # ANYONE ELSE INVOLVED IN THE CREATION, PRODUCTION, OR DELIVERY OF THE SCRIPTS BE LIABLE # # FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS # # PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) # # ARISING OUT OF THE USE OF OR INABILITY TO USE THE SAMPLE SCRIPTS OR DOCUMENTATION, # # EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES # ############################################################################################# <#PSScriptInfo .VERSION 2.2.1 .GUID f9cfe327-869f-410e-90e3-7286c94c31fd .AUTHOR timmcmic@microsoft.com .COMPANYNAME Microsoft CSS .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION This script will allow an administrator to purge objects from the connetor space and perform full object sync. #> Param ( #Define paramters to locate object in Active Directory [Parameter(Mandatory = $false)] [string]$ADObjectGUID="", [Parameter(Mandatory = $false)] [string]$ADObjectMAIL="", [Parameter(Mandatory = $false)] [string]$ADObjectDN="", [Parameter(Mandatory = $false)] [string]$ADConnectorName="", #Define parameteres to locate object in Entra Connector space. [Parameter(Mandatory = $false)] [string]$EntraDN="", [Parameter(Mandatory = $false)] [boolean]$CalculateEntraDN=$true, #Define parameters for Active Directory Connections. [Parameter(Mandatory = $false)] [string]$globalCatalogServer="", [Parameter(Mandatory = $false)] [psCredential]$activeDirectoryCredential=$NULL, #Define general parameters for the script. [Parameter(Mandatory = $true)] [string]$logFolderPath=$NULL, [Parameter(Mandatory = $false)] [boolean]$skipSingleItemSync=$false ) #Define the script parameters. [string]$entraConnectInstallPath = "" [boolean]$useActiveDirectoryLookup = $FALSE [string]$sourceAnchorAttribute = "" [string]$ADConnectorPowershell = "Microsoft Azure AD Sync\Extensions\AADConnector.psm1" [string]$ADSyncDiagnosticsPowershell = "Microsoft Azure AD Sync\Bin\ADSyncDiagnostics\ADSyncDiagnostics.psm1" [string]$ADConnectorPowershellFullpath = "" [string]$ADSyncDiagnosticsPowershellFullPath = "" $adObject = $NULL $adConnectorType = "AD" $entraConnectorType = "Extensible2" [string]$entraConnectorName = "" $adObjectXML = "adObject" $adCSObjectXML = "adCSObject" $entraCSObjectXML = "entraCSObject" $singleItemData = $NULL $singleItemXML = "singleItemXML" $logFileName = (Get-Date -Format FileDateTime) $adCSObject = $NULL $entraCSObject = $NULL Function new-LogFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] [string]$logFileName, [Parameter(Mandatory = $true)] [string]$logFolderPath ) [string]$logFileSuffix=".log" [string]$fileName=$logFileName+$logFileSuffix # Get our log file path $logFolderPath = $logFolderPath+"\"+$logFileName+"\" #Since $logFile is defined in the calling function - this sets the log file name for the entire script $global:LogFile = Join-path $logFolderPath $fileName #Test the path to see if this exists if not create. [boolean]$pathExists = Test-Path -Path $logFolderPath if ($pathExists -eq $false) { try { #Path did not exist - Creating New-Item -Path $logFolderPath -Type Directory } catch { throw $_ } } } Function Out-LogFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $String, [Parameter(Mandatory = $false)] [boolean]$isError=$FALSE ) # Get the current date [string]$date = Get-Date -Format G # Build output string #In this case since I abuse the function to write data to screen and record it in log file #If the input is not a string type do not time it just throw it to the log. if ($string.gettype().name -eq "String") { [string]$logstring = ( "[" + $date + "] - " + $string) } else { $logString = $String } # Write everything to our log file and the screen $logstring | Out-File -FilePath $global:LogFile -Append #Write to the screen the information passed to the log. if ($string.gettype().name -eq "String") { Write-Host $logString } else { write-host $logString | select-object -expandProperty * } #If the output to the log is terminating exception - throw the same string. if ($isError -eq $TRUE) { #Ok - so here's the deal. #By default error action is continue. IN all my function calls I use STOP for the most part. #In this case if we hit this error code - one of two things happen. #If the call is from another function that is not in a do while - the error is logged and we continue with exiting. #If the call is from a function in a do while - write-error rethrows the exception. The exception is caught by the caller where a retry occurs. #This is how we end up logging an error then looping back around. write-error $logString #Now if we're not in a do while we end up here -> go ahead and create the status file this was not a retryable operation and is a hard failure. exit } } Function write-FunctionParameters { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $keyArray, [Parameter(Mandatory = $true)] $parameterArray, [Parameter(Mandatory = $true)] $variableArray ) #Define script paramters Out-LogFile -string "********************************************************************************" $parameteroutput = @() foreach ($paramName in $keyArray) { $bound = $parameterArray.ContainsKey($paramName) $parameterObject = New-Object PSObject -Property @{ ParameterName = $paramName ParameterValue = if ($bound) { $parameterArray[$paramName] } else { ($variableArray | where {$_.name -eq $paramName } ).value } Bound = $bound } $parameterOutput+=$parameterObject } out-logfile -string $parameterOutput Out-LogFile -string "********************************************************************************" } function validate-ActiveDirectoryServerInfo { Param ( [Parameter(Mandatory = $true)] $globalCatalogServer, [Parameter(Mandatory = $true)] [AllowNull()] $activeDirectoryCredential ) out-logfile -string "Entering validate-ActiveDirectoryServerInfo" out-logfile -string "Validating global catalog server..." if ($globalCatalogServer -eq "") { out-logfile -string "A global catlog server must be specified in order to continue." -isError:$true } out-logfile -string "Validaing credentials passed." if ($activeDirectoryCredential -eq $NULL) { out-logfile -string "A validate Active Directory credential with rights to read objects must be provided." -isError:$TRUE } else { out-logfile -string "Active Directory credential provided." } out-logfile -string "Exiting validate-ActiveDirectoryServerInfo" } function validate-ActiveDirectoryTools { out-logfile -string "Entering validate-ActiveDirectoryTools" $functionCommands = get-command -module "ActiveDirectory" if ($functionCommands.count -eq 0) { out-logfile -string "Remote server administration tools for Active Directory required to proceed." -isError:$TRUE } else { out-logfile -string "Remote server administration tools for Active Directory present." } out-logfile -string "Exiting validate-ActiveDirectoryTools" } function validate-EntraConnectServer { out-logfile -string "Entering validate-EntraConnectServer" out-logfile -string "Microsoft Azure AD Connect synchronization services for legacy versions..." $functionApplicationDisplayName = "Microsoft Azure AD Connect synchronization services" $functionInstalledPrograms = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* $functionEntraConnect = $functionInstalledPrograms | where {$_.displayName -eq $functionApplicationDisplayName} if ($functionEntraConnect.displayName -ne $functionApplicationDisplayName) { out-logfile -string "Legacy version is not present." $functionApplicationDisplayName = "Microsoft Entra Connect synchronization services" $functionInstalledPrograms = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* $functionEntraConnect = $functionInstalledPrograms | where {$_.displayName -eq $functionApplicationDisplayName} } else { out-logfile -string "Legacy version present did not test for Entra name." } if ($functionEntraConnect.displayName -ne $functionApplicationDisplayName) { out-logfile -string "Uninstall for Entra Connect not located - application path cannot be found." -isError:$true } out-logfile -string $functionEntraConnect $functionPathReturn = $functionEntraConnect.installSource.replace("\Microsoft Azure Active Directory Connect\SetupFiles\","\") out-logfile -string "Exiting validate-EntraConnectServer" return $functionPathReturn } function query-SourceAnchor { [string]$globalSourceAnchorValue = "Microsoft.SynchronizationOption.AnchorAttribute" out-logfile -string "Entering query-SourceAnchor" out-logfile -string "Obtain Entra Connect Global Settings" try { $functionGlobalSettings = Get-ADSyncGlobalSettings -errorAction STOP } catch { out-logfile -string $_ -isError:$TRUE } $functionSourceAnchor = $functionGlobalSettings.parameters | where {$_.name -eq $globalSourceAnchorValue} out-logfile -string $functionSourceAnchor $functionSourceAnchorValue = $functionSourceAnchor.value out-logfile -string $functionSourceAnchorValue out-logfile -string "Exiting query-SourceAnchor" return $functionSourceAnchorValue } function import-PowershellCommands { Param ( [Parameter(Mandatory = $true)] $powerShellModule ) out-logfile -string "Entering import-PowershellCommands" try { Import-Module $powerShellModule -errorAction STOP out-logfile -string "Powershell module imported successfully." } catch { out-logfile -string "Error importing powershell module necessary for script execution." out-logfile -string $_ -isError:$TRUE } out-logfile -string "Exiting import-PowershellCommands" } function collect-ADObject { Param ( [Parameter(Mandatory = $true)] $ADObjectDN, [Parameter(Mandatory = $true)] $ADObjectGUID, [Parameter(Mandatory = $true)] $ADObjectMAIL, [Parameter(Mandatory = $true)] $globalCatalogServer, [Parameter(Mandatory = $true)] $activeDirectoryCredential ) $functionADObject = $NULL out-logfile -string "Entering collect-ADObject" if ($ADObjectDN -ne "") { try { out-logfile -string "Finding AD Object by DN." $functionADObject=get-adobject -identity $ADObjectDN -Server $globalCatalogServer -credential $activeDirectoryCredential -Properties * -errorAction STOP } catch { out-logfile -string "ADObjectDN specified but object not found by DN." out-logfile -string $_ -isError:$TRUE } } elseif ($ADObjectGUID -ne "") { try { out-logfile -string "Finding AD Object by GUID" $functionADObject=Get-ADObject -filter "objectGUID -eq `"$ADObjectGUID`"" -Server $globalCatalogServer -credential $activeDirectoryCredential -Properties * -errorAction STOP } catch { out-logfile -string "ADObjectGUID specified but object not found by DN." out-logfile -string $_ -isError:$TRUE } } elseif ($ADObjectMail -ne "") { try { out-logfile -string "Finding AD Object by Mail." $functionADObject=Get-ADObject -filter "mail -eq `"$ADObjectMail`"" -Server $globalCatalogServer -credential $activeDirectoryCredential -Properties * -errorAction STOP } catch { out-logfile -string "ADObjectMAIL specified but object not found by DN." out-logfile -string $_ -isError:$TRUE } } if ($functionADObject -eq $NULL) { out-logfile -string "No ad object was found using specified criteria." -isError:$true } out-logfile -string $functionADObject out-logfile -string "Exiting collect-ADObject" return $functionADObject } function calculate-EntraDN { Param ( [Parameter(Mandatory = $true)] $adObject, [Parameter(Mandatory = $true)] $sourceAnchorAttribute ) $anchor0 = "objectGUID" $anchor1 = "ms-ds-ConsistencyGuid" $functionGUID = $NULL $functionBase64String=$NULL $functionDN = $NULL out-logfile -string "Enter calculate-EntraDN" if (($sourceAnchorAttribute -eq $anchor0) -or ($sourceAnchorAttribute -eq $anchor1)) { out-logfile -string "Source anchor is objectGUID or ms-ds-ConsistencyGUID" out-logfile -string "Determine if object has ms-ds-ConsistencyGUID" if ($adObject.'ms-ds-ConsistencyGUID' -ne $NULL) { out-logfile -string "MS-DS-ConsistencyGUID in use." out-logfile -string $adObject.'ms-ds-consistencyguid' $functionGuid = [GUID]$adObject.'ms-ds-ConsistencyGUID' } else { out-logfile -string "ObjectGUID in Use." out-logfile -string $adObject.objectGUID $functionGuid = [GUID]$adObject.objectGUID } out-logfile -string $functionGUID.Guid $functionBase64String = [System.Convert]::ToBase64String($functionGuid.ToByteArray()) out-logfile -string $functionBase64String $functionDN = ConvertTo-ADSyncAadDistinguishedName -sourceAnchor $functionBase64String out-logfile -string $functionDN } else { out-logfile -string "Source anchor attribute is a custom attribute." $functionBase64String = $adObject.$sourceAnchorAttribute out-logfile -string $functionBase64String $functionDN = ConvertTo-ADSyncAadDistinguishedName -sourceAnchor $functionBase64String out-logfile -string $functionDN } out-logfile -string "Exit calculate-EntraDN" return $functionDN } function get-Connector { Param ( [Parameter(Mandatory = $true)] $connectorType ) out-logfile -string "Enter get-Connector" $functionConnectors = $NULL [string]$functionConnectorName try { $functionConnectors = Get-ADSyncConnector -errorAction STOP | where {$_.connectorTypeName -eq $connectorType} } catch { out-logfile -string "Unable to obtain the Entra Connect connectors." out-logfile -string $_ } out-logfile -string $functionConnectors if ($functionConnectors.count -gt 1) { out-logfile -string "More than one Active Directory connector exists. Please specify -ADConnectorName with the name from Synchornization Manager -> Connectors" } else { $functionConnectorName = $functionConnectors.name } out-logfile -string "Exit get-Connector" return $functionConnectorName } Function Out-XMLFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $itemToExport, [Parameter(Mandatory = $true)] [string]$itemNameToExport ) Out-LogFile -string "********************************************************************************" Out-LogFile -string "BEGIN OUT-XMLFILE" Out-LogFile -string "********************************************************************************" #Declare function variables. $fileName = $itemNameToExport+".xml" #Update the log folder path to include the static folder. $logFolderPath = $logFolderPath+"\"+$logFileName+"\" # Get our log file path and combine it with the filename $LogFile = Join-path $logFolderPath $fileName #Write our variables to the log. out-logfile -string ("XML File Name = "+$fileName) out-logfile -string ("Log Folder Path = "+$logFolderPath) out-logfile -string ("Log File = "+$LogFile) # Write everything to our log file and the screen try { $itemToExport | export-CLIXML -path $LogFile } catch { throw $_ } Out-LogFile -string "END OUT-XMLFILE" Out-LogFile -string "********************************************************************************" } function get-CSObject { Param ( [Parameter(Mandatory = $true)] [string]$dn, [Parameter(Mandatory = $true)] [string]$connectorName ) out-logfile -string "Enter get-CSObject" $functionCSObject=$NULL try { $functionCSObject = Get-ADSyncCSObject -DistinguishedName $dn -ConnectorName $connectorName.trim() } catch { out-logfile -string "Uanble to locate CS Object by DN." out-logfile -string $_ -isError:$true } out-logfile -string $functionCSObject out-logfile -string "Exit get-CSObject" return $functionCSObject } Function start-sleepProgress { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] [string]$sleepString, [Parameter(Mandatory = $true)] [int]$sleepSeconds, [Parameter(Mandatory = $false)] [int]$sleepParentID=0, [Parameter(Mandatory = $false)] [int]$sleepID=0 ) #Output all parameters bound or unbound and their associated values. write-functionParameters -keyArray $MyInvocation.MyCommand.Parameters.Keys -parameterArray $PSBoundParameters -variableArray (Get-Variable -Scope Local -ErrorAction Ignore) Out-LogFile -string "********************************************************************************" Out-LogFile -string "BEGIN start-sleepProgess" Out-LogFile -string "********************************************************************************" if(($sleepId -eq 0)-and ($sleepParentID -eq 0)) { For ($i=$sleepSeconds; $i -gt 0; $i--) { Write-Progress -Activity $sleepString -SecondsRemaining $i Start-Sleep 1 } write-progress -activity $sleepString -Completed } else { For ($i=$sleepSeconds; $i -gt 0; $i--) { Write-Progress -Activity $sleepString -SecondsRemaining $i -Id $sleepID -ParentId $sleepParentID Start-Sleep 1 } Write-Progress -Activity $sleepString -Id $sleepID -ParentId $sleepParentID -Completed } Out-LogFile -string "END start-sleepProgess" Out-LogFile -string "********************************************************************************" } Function suspend-EntraSync { $retry = $TRUE out-logfile -string "Enter suspend-EntraSync" do { try { Set-ADSyncScheduler -SyncCycleEnabled:$FALSE -errorAction STOP out-logfile -string "Sync cycle suspended successfully." $retry=$FALSE } catch { out-logfile -string $_ start-sleepProgress -sleepString "Unable to set scheduled to false - sleeping" -sleepSeconds 15 } }until ($retry -eq $FALSE) out-logfile -string "End suspend-EntraSync" } Function resume-EntraSync { $retry = $TRUE out-logfile -string "Enter resume-EntraSync" do { try { Set-ADSyncScheduler -SyncCycleEnabled:$TRUE -errorAction STOP out-logfile -string "Sync cycle suspended successfully." $retry=$FALSE } catch { out-logfile -string $_ start-sleepProgress -sleepString "Unable to set scheduled to false - sleeping" -sleepSeconds 15 } }until ($retry -eq $FALSE) out-logfile -string "End resume-EntraSync" } Function delete-CSObject { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $csObject ) out-logfile -string "Enter delete-CSObject" try { Remove-ADSyncCSObject -CsObject $csObject -Force -errorAction STOP } catch { out-logfile -string "Error deleting CS Object." out-logfile -string $_ -isError:$true } out-logfile -string "End delete-CSObject" } Function start-EntraSync { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $policyType, [Parameter(Mandatory = $true)] $DN ) $retry = $true $delta = "Delta" $single = "Single" $output = $NULL out-logfile -string "Enter start-EntraSync" if ($policyType -eq $delta) { do { try { start-adSyncSyncCycle -policyType Delta -errorAction STOP out-logfile -string "Delta sync triggered successfully." $retry=$FALSE } catch { out-logfile -string $_ start-sleepProgress -sleepString "Unable to perform delta sync - sleeping" -sleepSeconds 15 } }until ($retry -eq $FALSE) } elseif ($policyType -eq $single) { try { out-logfile -string "Attempting single item sync." $output = Invoke-ADSyncSingleObjectSync -DistinguishedName $DN -errorAction STOP } catch { out-logfile -string "Uanble to perform single object sync." out-logfile -string $_ -isError:$true } } out-logfile -string "End start-EntraSync" if ($output -ne $NULL) { return $output } } Function Out-JSONFile { [cmdletbinding()] Param ( [Parameter(Mandatory = $true)] $itemToExport, [Parameter(Mandatory = $true)] [string]$itemNameToExport ) Out-LogFile -string "********************************************************************************" Out-LogFile -string "BEGIN OUT-XMLFILE" Out-LogFile -string "********************************************************************************" #Declare function variables. $fileName = $itemNameToExport+".json" #Update the log folder path to include the static folder. $logFolderPath = $logFolderPath+"\"+$logFileName+"\" # Get our log file path and combine it with the filename $LogFile = Join-path $logFolderPath $fileName #Write our variables to the log. out-logfile -string ("XML File Name = "+$fileName) out-logfile -string ("Log Folder Path = "+$logFolderPath) out-logfile -string ("Log File = "+$LogFile) # Write everything to our log file and the screen try { $itemToExport | Out-File -FilePath $LogFile } catch { throw $_ } Out-LogFile -string "END OUT-XMLFILE" Out-LogFile -string "********************************************************************************" } #Create the log file. new-logfile -logFileName $logFileName -logFolderPath $logFolderPath #Start logging out-logfile -string "*********************************************************************************" out-logfile -string "Start reset-EntraConnectObject" out-logfile -string "*********************************************************************************" #Capture paramters for review. out-logfile -string "Script paramters:" write-functionParameters -keyArray $MyInvocation.MyCommand.Parameters.Keys -parameterArray $PSBoundParameters -variableArray (Get-Variable -Scope Local -ErrorAction Ignore) #If an Active Directory DN and entra DN were provided - there's no need to calculate valies. if (($entraDN -ne "") -and ($ADObjectDN -ne "")) { out-logfile -string "Both an EntraDN and AD DN were specified - no calculations necessary." $CalculateEntraDN = $false $useActiveDirectoryLookup = $false out-logfile -string ("Calculate EntraDN: "+$CalculateEntraDN) out-logfile -string ("Use Active Directory Lookup: "+$useActiveDirectoryLookup) } elseif (($ADObjectDN -ne "") -or ($ADObjectGUID -ne "") -or ($ADObjectMail -ne "")) { out-logfile -string "Active Directory Information Provided." if (($entraDN -eq "") -and ($CalculateEntraDN -eq $TRUE)) { out-logfile -string "No entra ID provided." out-logfile -string "Calculate EntraDN is TRUE." out-logfile -string "Allow directory lookup to calculate entraDN." $useActiveDirectoryLookup = $TRUE out-logfile -string ("Use Active Directory Lookup: "+$useActiveDirectoryLookup) } elseif (($entraDN -ne "") -and ($CalculateEntraDN -eq $TRUE)) { out-logfile -string "Entra DN provided with AD Information - calculate EntraDN not necessary." $CalculateEntraDN=$false if ($adObjectDN -ne "") { out-logfile -string "AD Object DN specified - AD looksups no required." $useActiveDirectoryLookup = $false } else { out-logfile -string "AD Object Mail or GUID specified - lookup required." $useActiveDirectoryLookup = $true } } elseif (($entraDN -eq "") -and ($CalculateEntraDN -eq $FALSE)) { out-logfile -string "An EntraDN was not specified and calculate false - assume AD connector space only purge." if ($adObjectDN -ne "") { out-logfile -string "AD Object DN specified - AD looksups no required." $useActiveDirectoryLookup = $false } else { out-logfile -string "AD Object Mail or GUID specified - lookup required." $useActiveDirectoryLookup = $true } } } elseif (($ADObjectDN -eq "") -or ($ADObjectGUID -eq "") -or ($ADObjectMail -eq "")) { out-logfile -string "No AD information provided - test for Entra Connector space remove only." if ($EntraDN -ne "") { out-logfile -string "EntraDN specified only." $CalculateEntraDN=$false } else { out-logfile -string "No AD or EntraDN information provided - no work to do." -isError:$true } } #Determine the AD Connect installation path. out-logfile -string "Determine the Entra Connect installation root path - required for further script importation." $entraConnectInstallPath=validate-EntraConnectServer out-logfile -string $entraConnectInstallPath out-logfile -string "Construct powershell modules to import path." $ADConnectorPowershellFullpath = $entraConnectInstallPath+$ADConnectorPowershell out-logfile -string $ADConnectorPowershellFullpath $ADSyncDiagnosticsPowershellFullPath = $entraConnectInstallPath+$ADSyncDiagnosticsPowershell out-logfile -string $ADSyncDiagnosticsPowershellFullPath out-logfile -string "Importing powershell commands necessary for script execution." import-PowershellCommands -powerShellModule $ADConnectorPowershellFullpath import-PowershellCommands -powerShellModule $ADSyncDiagnosticsPowershellFullPath #The following is performed only if the distinguished name is not provided forcing active directory lookup. #If use active directory is true perform pre-req checks. if ($useActiveDirectoryLookup -eq $TRUE) { out-logfile -string "Lookup attribute provided - requires Active Directory connectivity. " #Validate the Active Directory Tools are installed validate-ActiveDirectoryTools #Validate the Active Directory Server information. validate-ActiveDirectoryServerInfo -globalCatalogServer $globalCatalogServer -activeDirectoryCredential $activeDirectoryCredential #Obtain the active directory object for futher work. $adObject = collect-ADObject -ADObjectDN $ADObjectDN -adobjectguid $adobjectGUID -adObjectMail $ADObjectMAIL -globalCatalogServer $globalCatalogServer -activeDirectoryCredential $activeDirectoryCredential out-logfile -string $adObject Out-XMLFile -itemToExport $adobject -itemNameToExport $adObjectXML } #At this time we can calculate the entraDN if necessary. if ($CalculateEntraDN -eq $TRUE) { out-logfile -string "Determine the source anchor." $sourceAnchorAttribute = query-SourceAnchor out-logfile -string "Calculate the Entra Connector Space DN" $entraDN = calculate-EntraDN -adObject $adObject -sourceAnchorAttribute $sourceAnchorAttribute out-logfile -string $EntraDN } out-logfile -string "Determine if Active Directory connector name specified - if so use otherwise determine - if more than 1 fail." if ($adConnectorName -eq "") { out-logfile -string "No AD Connector specified - determine if more than one or automatic selection." $adConnectorName = get-Connector -connectorType $adConnectorType out-logfile -string $adConnectorName } out-logfile -string "Determine the entra connector name." $entraConnectorName = get-Connector -connectorType $entraConnectorType out-logfile -string $entraConnectorName out-logfile -string "Capture the CS objects" if ($adobject -ne $NULL) { out-logfile -string "An active directory object was specified." $adCSObject = get-CSObject -dn $adobject.distinguishedName -connectorName $ADConnectorName Out-LogFile -string $adCSObject out-xmlFile -itemToExport $adCSObject -itemNameToExport $adCSObjectXML } elseif ($adObjectDN -ne "") { out-logfile -string "An active directory object DN was specified." $adCSObject = get-CSObject -dn $ADObjectDN -connectorName $ADConnectorName Out-LogFile -string $adCSObject out-xmlFile -itemToExport $adCSObject -itemNameToExport $adCSObjectXML } else { out-logfile -string "No Active Directory CS object information obtained." } if ($EntraDN -ne "") { out-logfile -string "An entra DN was specified or calculated." out-logfile -string $entraConnectorName.getType() $entraCSObject = get-CSObject -dn $EntraDN -connectorName $entraConnectorName out-logfile -string $entraCSObject out-xmlFile -itemToExport $entraCSObject -itemNameToExport $entraCSObjectXML } out-logfile -string "Suspend Entra Connect synchornization while object removal and sync is in progress." suspend-EntraSync out-logfile -string "Suspend Entra Connect synchronization successful - proceed with connector space object deletion." if ($adCSObject -ne $NULL) { delete-CSObject -csObject $adCSObject } if ($entraCSObject -ne $NULL) { delete-CSObject -csObject $entraCSObject } out-logfile -string "If the object was an entra connetor space only move detal sync required - otherwise single object is fine." if (($adCSObject -eq $NULL) -and ($entraCSObject -ne $NULL)) { start-EntraSync -policyType "Delta" -dn "NONE" } elseif ($skipSingleItemSync -eq $false) { if ($adobject -ne $NULL) { $singleItemData = start-EntraSync -policyType "Single" -dn $adobject.distinguishedName } else { $singleItemData = start-EntraSync -policyType "Single" -dn $ADObjectDN } } if ($singleItemData -ne $NULL) { Out-JSONFile -itemToExport $singleItemData -itemNameToExport $singleItemXML } out-logfile -string "Re-enable the sync cycle." resume-EntraSync out-logfile -string "Opertaion completed." |