ActionPlans/Start-SyncDDGasContactwithAADConnect.ps1

# Function to validate if required custom rules exists and to create them
Function new-AADSyncDDGRules {

    # select local AD connector
    $selectConnector = Get-ADSyncConnector | Where-Object { $_.Name -notlike "*onmicrosoft*" } | Select-Object name, identifier | Out-GridView -Title "Please select the connector to your local Active Directory!" -OutputMode Single
    if ($selectConnector)
    {
        [string]$SectionTitle = "On-premises AD Connector used by the created rules"
        [string]$Description = "The rules will be created using the selected connector: $($selectConnector.name)"
        [PSCustomObject]$OnPremisesADConnectorSelectedHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Green" -Description $Description -DataType "String" -EffectiveDatastring "See next sections for rule creations!"
        $null = $TheCollectionToConvertToHTML.Add($OnPremisesADConnectorSelectedHTML)

    #region Create ADSync PROVISION rule
    $ruleName = 'Custom In from AD - Dynamic Distribtution Group - Provision'
    if (!(Get-ADSyncRule | Where-Object { ($_.Name -eq $ruleName) -and ($_.Connector -eq $selectConnector.identifier.guid) })) {

        $slot = Get-ADSyncRuleFreeSlot -ruleName $ruleName 
        if ($slot.count -eq 0) {
            Write-Host "You select CANCEL so the rule `"$ruleName`" won't be created"
            Read-Key
            #TODO: write this on the report

            [string]$SectionTitle = "`"$ruleName`" - creation"
            [string]$Description = "The rule `"$ruleName`" has not been created using selected connector: $($selectConnector.name) because no slot was selected"
            [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Red" -Description $Description -DataType "String" -EffectiveDatastring ""
            $null = $TheCollectionToConvertToHTML.Add($RuleHTML)
        }
        else {
    

            New-ADSyncRule  `
                -Name $ruleName  `
                -Description 'Dynamic Distribution Groups provision rule' `
                -Direction 'Inbound' `
                -Precedence $($slot.precedence) `
                -PrecedenceAfter '00000000-0000-0000-0000-000000000000' `
                -PrecedenceBefore '00000000-0000-0000-0000-000000000000' `
                -SourceObjectType 'msExchDynamicDistributionList' `
                -TargetObjectType 'person' `
                -Connector $selectConnector.identifier.guid `
                -LinkType 'Provision' `
                -SoftDeleteExpiryInterval 0 `
                -OutVariable syncRule | Out-Null
            #endregion Create ADSync PROVISION rule

            #region Created Attribute Flow Mappings for the PROVISION rule
            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'cloudFiltered' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(IsPresent([isCriticalSystemObject]) || ( (InStr([displayName], "(MSOL)") > 0) && (CBool([msExchHideFromAddressLists]))) || (Left([mailNickname], 4) = "CAS_" && (InStr([mailNickname], "}") > 0)) || CBool(InStr(DNComponent(CRef([dn]),1),"\\0ACNF:")>0), True, NULL)' `
                -OutVariable syncRule | Out-Null

            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'mailEnabled' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(( (IsPresent([proxyAddresses]) = True) && (Contains([proxyAddresses], "SMTP:") > 0) && (InStr(Item([proxyAddresses], Contains([proxyAddresses], "SMTP:")), "@") > 0)) || (IsPresent([mail]) = True && (InStr([mail], "@") > 0)), True, False)' `
                -OutVariable syncRule | Out-Null
            #endregion Created Attribute Flow Mappings for the PROVISION rule

            #region Create Scope Condition to match all Dynamic Distribtuion object type for PROVISION rule
            New-Object  `
                -TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.ScopeCondition' `
                -ArgumentList 'isCriticalSystemObject', 'True', 'NOTEQUAL' `
                -OutVariable condition0 | Out-Null

            New-Object  `
                -TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.ScopeCondition' `
                -ArgumentList 'msExchRecipientDisplayType', '3', 'EQUAL' `
                -OutVariable condition1  | Out-Null

            Add-ADSyncScopeConditionGroup  `
                -SynchronizationRule $syncRule[0] `
                -ScopeConditions @($condition0[0], $condition1[0]) `
                -OutVariable syncRule  | Out-Null

            #endregion Create Scope Condition to match all Dynamic Distribtuion object type

            #region Create join condition for PROVISION rule
            New-Object  `
                -TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.JoinCondition' `
                -ArgumentList 'mail', 'mail', $false `
                -OutVariable condition0  | Out-Null

            Add-ADSyncJoinConditionGroup  `
                -SynchronizationRule $syncRule[0] `
                -JoinConditions @($condition0[0]) `
                -OutVariable syncRule  | Out-Null
            #endregion Create Join Condition for PROVISION rule

            #region Create the PROVISION rule
            Add-ADSyncRule -SynchronizationRule $syncRule[0] | Out-Null
            Remove-Variable syncRule -Force

            $CurrentProperty = "New-AADSyncDDGRules"
            $CurrentDescription = "Rule `"$ruleName`" has been created"
            Write-Host $CurrentDescription -ForegroundColor Green
            write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 
            
            [string]$SectionTitle = "`"$ruleName`" - creation"
            [string]$Description = "The rule `"$ruleName`" has been succesfully created using selected connector: $($selectConnector.name)"
            [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Green" -Description $Description -DataType "String" -EffectiveDatastring ""
            $null = $TheCollectionToConvertToHTML.Add($RuleHTML)
            
            Read-Key    


        }
    }
    else {
        Write-Host "Rule `"$ruleName`" already exist. If you want to re-create it, you can delete it from AAD Connect and re-run the script to re-created with the latest version"
        $CurrentProperty = "New-AADSyncDDGRules"
        $CurrentDescription = "rule `"$ruleName`" was already created"
        write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 
        
        [string]$SectionTitle = "`"$ruleName`" - creation"
        [string]$Description = "The rule `"$ruleName`" has not been succesfully created using selected connector: $($selectConnector.name) because already exists."
        [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Black" -Description $Description -DataType "String" -EffectiveDatastring ""
        $null = $TheCollectionToConvertToHTML.Add($RuleHTML)

        Read-Key    
    }
    #endregion Create the PROVISION rule


    #region Create ADSync JOIN rule (Has All Attribute Transformations)
    $ruleName = 'Custom In from AD - Dynamic Distribution Group - Join'
    if (!(Get-ADSyncRule | Where-Object { ($_.Name -eq $ruleName) -and ($_.Connector -eq $selectConnector.identifier.guid) })) {

        $slot = Get-ADSyncRuleFreeSlot -ruleName $ruleName 
        if ($slot.count -eq 0) {
            Write-Host "You select CANCEL so the rule `"$ruleName`" won't be created"
            #TODO: write this on the report
            #TODO: write to the log file
            [string]$SectionTitle = "`"$ruleName`" - creation"
            [string]$Description = "The rule `"$ruleName`" has not been created using selected connector: $($selectConnector.name) because no slot was selected"
            [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Red" -Description $Description -DataType "String" -EffectiveDatastring ""
            $null = $TheCollectionToConvertToHTML.Add($RuleHTML)

            Read-Key

        }
        else {
            New-ADSyncRule  `
                -Name $ruleName  `
                -Description 'Dynamic Distribution Group Join - Transformations rule' `
                -Direction 'Inbound' `
                -Precedence $($slot.precedence) `
                -PrecedenceAfter '00000000-0000-0000-0000-000000000000' `
                -PrecedenceBefore '00000000-0000-0000-0000-000000000000' `
                -SourceObjectType 'msExchDynamicDistributionList' `
                -TargetObjectType 'person' `
                -Connector $selectConnector.identifier.guid  `
                -LinkType 'Join' `
                -SoftDeleteExpiryInterval 0 `
                -OutVariable syncRule  | Out-Null
            #endregion Create ADSync JOIN rule

            #region Create Attribute Flow Mappings
            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('dn') `
                -Destination 'distinguishedName' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('authOrig') `
                -Destination 'authOrig' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('cn') `
                -Destination 'cn' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'description' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(IsNullOrEmpty([description]),NULL,Left(Trim(Item([description],1)),448))' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'displayName' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(IsNullOrEmpty([displayName]),[cn],[displayName])' `
                -OutVariable syncRule  | Out-Null


            # to verify what the attribute is doing
            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('dLMemSubmitPerms') `
                -Destination 'dLMemSubmitPerms' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            # to verify what the attribute is doing
            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('dLMemRejectPerms') `
                -Destination 'dLMemRejectPerms' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute1' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute1])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute2' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute2])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute3' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute3])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute4' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute4])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute5' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute5])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute6' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute6])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute7' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute7])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute8' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute8])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute9' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute9])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute10' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute10])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute11' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute11])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute12' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute12])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute13' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute13])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute14' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute14])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'extensionAttribute15' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([extensionAttribute15])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'legacyExchangeDN' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(IsPresent([legacyExchangeDN]), [legacyExchangeDN], NULL)' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'mail' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([mail])' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'mailNickname' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'IIF(IsPresent([mailNickname]), [mailNickname], [cn])' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msDS-HABSeniorityIndex') `
                -Destination 'msDS-HABSeniorityIndex' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msDS-PhoneticDisplayName') `
                -Destination 'msDS-PhoneticDisplayName' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchExtensionCustomAttribute1') `
                -Destination 'msExchExtensionCustomAttribute1' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchExtensionCustomAttribute2') `
                -Destination 'msExchExtensionCustomAttribute2' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchExtensionCustomAttribute3') `
                -Destination 'msExchExtensionCustomAttribute3' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchExtensionCustomAttribute4') `
                -Destination 'msExchExtensionCustomAttribute4' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchExtensionCustomAttribute5') `
                -Destination 'msExchExtensionCustomAttribute5' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchHideFromAddressLists') `
                -Destination 'msExchHideFromAddressLists' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchRecipientDisplayType') `
                -Destination 'msExchRecipientDisplayType' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchRecipientTypeDetails') `
                -Destination 'msExchRecipientTypeDetails' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchRequireAuthToSendTo') `
                -Destination 'msExchRequireAuthToSendTo' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('msExchSenderHintTranslations') `
                -Destination 'msExchSenderHintTranslations' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'proxyAddresses' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'RemoveDuplicates(Trim(ImportedValue("proxyAddresses")))' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'sourceAnchor' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'ConvertToBase64([objectGUID])' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('objectGUID') `
                -Destination 'sourceAnchorBinary' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('Contact') `
                -Destination 'sourceObjectType' `
                -FlowType 'Constant' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Destination 'telephoneNumber' `
                -FlowType 'Expression' `
                -ValueMergeType 'Update' `
                -Expression 'Trim([telephoneNumber])' `
                -OutVariable syncRule  | Out-Null


            Add-ADSyncAttributeFlowMapping  `
                -SynchronizationRule $syncRule[0] `
                -Source @('unauthOrig') `
                -Destination 'unauthOrig' `
                -FlowType 'Direct' `
                -ValueMergeType 'Update' `
                -OutVariable syncRule  | Out-Null


            #endregion Create Attribute Flow Mappings

            #region Create Scope Condition to match all Dynamic Distribtuion object type
            New-Object  `
                -TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.ScopeCondition' `
                -ArgumentList 'msExchRecipientDisplayType', '3', 'EQUAL' `
                -OutVariable condition0  | Out-Null

            Add-ADSyncScopeConditionGroup  `
                -SynchronizationRule $syncRule[0] `
                -ScopeConditions @($condition0[0]) `
                -OutVariable syncRule  | Out-Null
            #endregion Create Scope Condition to match all Dynamic Distribtuion object type


            # Add the rule in the AAD Connect engine
            Add-ADSyncRule -SynchronizationRule $syncRule[0] | Out-Null
            Remove-Variable syncRule -Force
            $CurrentProperty = "New-AADSyncDDGRules"
            $CurrentDescription = "Rule `"$ruleName`" has been created"
            Write-Host $CurrentDescription -ForegroundColor Green
            write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 
            
            [string]$SectionTitle = "`"$ruleName`" - creation"
            [string]$Description = "The rule `"$ruleName`" has been succesfully created using selected connector: $($selectConnector.name)"
            [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Green" -Description $Description -DataType "String" -EffectiveDatastring ""
            $null = $TheCollectionToConvertToHTML.Add($RuleHTML)
            
            

            Read-Key    
        }
    }
    else {
        Write-Host "Rule `"$ruleName`" already exist. If you want to re-create it, you can delete it from AAD Connect and re-run the script to re-created with the latest version"
        $CurrentProperty = "New-AADSyncDDGRules"
        $CurrentDescription = "rule `"$ruleName`" was already created"
        write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 

        [string]$SectionTitle = "`"$ruleName`" - creation"
        [string]$Description = "The rule `"$ruleName`" has not been succesfully created using selected connector: $($selectConnector.name) because already exists."
        [PSCustomObject]$RuleHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Black" -Description $Description -DataType "String" -EffectiveDatastring ""
        $null = $TheCollectionToConvertToHTML.Add($RuleHTML)

        Read-Key    
    }
}
else {
    #TODO: write in report
    $CurrentProperty = "selectConnector"
    $CurrentDescription = "No connector was selected!"
    write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 
    Write-Host $CurrentDescription

    [string]$SectionTitle = "On-premises AD Connector used by the created rules"
    [string]$Description = "No On-premises AD Connector was selected."
    [PSCustomObject]$OnPremisesADConnectorSelectedHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Red" -Description $Description -DataType "String" -EffectiveDatastring "No rules will be created!"
    $null = $TheCollectionToConvertToHTML.Add($OnPremisesADConnectorSelectedHTML)

    read-Key    
}
}

# Check if Admin previously created similar rules (not used now as a different check was implemented)
Function Get-AADSyncDDGRulesExists {

    $adConnectors = (Get-ADSyncConnector | Where-Object { $_.Name -notlike "*onmicrosoft*" }).identifier.guid
    # ADSync rule with Dynamic Distribution Groups as source object
    $ADSyncDDGRules = Get-ADSyncRule | Where-Object { $_.Direction -eq "Inbound" -and $_.Connector -eq $adConnectors -and $_.SourceObjectType -eq "msExchDynamicDistributionList" -and $_.TargetObjectType -eq "person" }

    # Verify if the AAD DDG Rule exists
    $AdSyncDDG_Join = $ADSyncDDGRules | Where-Object { $_.LinkType -eq "Join" }
    foreach ($prop in ($AdSyncDDG_Join).AttributeFlowMappings) {
        if ($prop.Destination -eq "sourceObjectType" -and $prop.Source -contains "Contact" -and $prop.FlowType -eq "Constant") {
            $prop
        }
    }
    ($AdSyncDDG_Join).ScopeFilter.ScopeConditionList
}

# Show free slots for rules to administrator and allow him to chose the position where the rules will be created
Function Get-ADSyncRuleFreeSlot {
    param ([string]$ruleName)
 
    $ADSyncRulesAndEmptySlots = New-Object Collections.ArrayList
    $allRules = Get-ADSyncRule | Select-Object name, Precedence | Where-Object Precedence -lt 100
    
    $correctSlot = $False

    for ($i = 0; $i -lt 100; $i++) {
        $Entry = New-Object PSObject
        $Entry | Add-Member -NotePropertyName Precedence -NotePropertyValue $i
        $Entry | Add-Member -NotePropertyName Name -NotePropertyValue $null
        if ($i -in $allRules.Precedence) {
            Foreach ($rule in $allRules) {
                If ($rule.Precedence -eq $i) {
                    $Entry.name = $rule.name
                }
            }
        }
        Else {
            $Entry.name = "Free Slot"
        }

        $ADSyncRulesAndEmptySlots.Add($Entry) | out-null
    }
        
    While (!$correctSlot) {
        [array]$slot = $ADSyncRulesAndEmptySlots | Out-GridView  -Title "Please select the precedence for rule `"$ruleName`" by choosing a Free Slot."  -OutputMode Single

        If ($slot.count -eq 1) {
            if ($slot.name -ne "Free Slot") {
                Write-Host "Please select one row out of the Free Slots" -ForegroundColor Red
                #read-Key
            }
            else {
                $correctSlot = $True
            }
        }
        else {
            $correctSlot = $True
        }
    }
    return $slot

}

# Inform about the prerequisites
Write-Host "This dianostic have to be executed on AAD Connect server to have access to AADSync PowerShell Module!" -ForegroundColor Yellow
Read-Key

Clear-Host

# Import Module ADSync
$Workloads = "ADSync"
Connect-O365PS -O365Service $Workloads -requireCredentials $false


$CurrentProperty = "Connecting to: $Workloads"
$CurrentDescription = "Success"
write-log -Function "Connecting to workloads" -Step $CurrentProperty -Description $CurrentDescription 
    
$ts = get-date -Format yyyyMMdd_HHmmss
$ExportPath = "$global:WSPath\SyncDDGasContactwithAADConnect_$ts"
mkdir $ExportPath -Force | Out-Null


##Initialize HTML Object
[System.Collections.ArrayList]$TheCollectionToConvertToHTML = @()

[string]$SectionTitle = "Information"
[string]$article1='<a href="https://docs.microsoft.com/previous-versions/office/exchange-server-2010/jj150422(v=exchg.141)?redirectedfrom=MSDN" target="_blank">Configure Dynamic Distribution Groups in a Hybrid Deployment</a>'
[string]$article2='<a href="https://answers.microsoft.com/en-us/msoffice/forum/msoffice_o365admin-mso_exchon-mso_o365b/creating-aad-connect-rules-to-synchronize-on/41444825-f62f-4f1a-a449-152806319568?tm=1621510359210" target="_blank">Creating AAD Connect rules to synchronize on-premises Dynamic Distribution Groups as Exchange Online Contacts</a>'
[string]$Description = "In a Hybrid Exchange environment, the on-premises Dynamic Distribution Groups (DDGs) are not synced in Azure AD / Exchange Online and this is by design. To workaround this limitation Microsoft recommends to create Exchange Online contacts for every on-premises dynamic distribution group. See $article1. To automatically maintain this Exchange Online contacts we can implement some custom AAD Connect rules without touching any default ones. For more information see article $article2."
[PSCustomObject]$InformatioHTML = New-ObjectForHTMLReport -SectionTitle $SectionTitle -SectionTitleColor "Black" -Description $Description -DataType "String" -EffectiveDatastring "Please check bellow for what was implemented!"
$null = $TheCollectionToConvertToHTML.Add($InformatioHTML)

# Write current step in the log
$CurrentProperty = "new-AADSyncDDGRules"
$CurrentDescription = "Start"
write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 

# Call the function to create the AAD Connect rules
new-AADSyncDDGRules

# Write current step in the log
$CurrentProperty = "new-AADSyncDDGRules"
$CurrentDescription = "Finished"
write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 

# Creating the Final report with all sections previously created
[string]$FilePath = $ExportPath + "\AADConnectSyncDDGasContacts.html"
Export-ReportToHTML -FilePath $FilePath -PageTitle "Creating AAD Connect rules to synchronize on-premises Dynamic Distribution Groups as Exchange Online Contacts" -ReportTitle "Implementing AAD Connect rules to synchronize on-premises Dynamic Distribution Groups as Exchange Online Contacts" -TheObjectToConvertToHTML $TheCollectionToConvertToHTML

# Write current step in the log
$CurrentProperty = "HTML report which contains information about creation of the AAD Connect rules can be found here: $ExportPath "
$CurrentDescription = "The script will return to main menu!"
write-log -Function "Start-SyncDDGasContactwithAADConnect" -Step $CurrentProperty -Description $CurrentDescription 

# Ask enduser for opening the HTMl report
Write-Host "`nReport was exported in the following location: $ExportPath" -ForegroundColor Cyan 
$OpenHTMLfile=Read-Host "Do you wish to open HTML report file now?`nType Y(Yes) to open or N(No) to exit!"
if ($OpenHTMLfile.ToLower() -eq "y")
{
    # Open report with default browswer
    Write-Host "Opening report with default browswer." -ForegroundColor Cyan
    Start-Process $FilePath
    
    Write-Host "The script will return to main menu!" -ForegroundColor Cyan
    Read-Key
    # Go back to the main menu
    Start-O365TroubleshootersMenu

}
elseif($OpenHTMLfile.ToLower() -eq "n")
{
    Write-Host "The script will return to main menu!" -ForegroundColor Cyan
    Read-Key
    # Go back to the main menu
    Start-O365TroubleshootersMenu
}
else {
    Write-Host "You didn't provide an expected input!" -ForegroundColor Yellow
    Write-Host "The script will return to main menu!" -ForegroundColor Cyan
    Read-Key
    # Go back to the main menu
    Start-O365TroubleshootersMenu
}