Jorge's Quest For Knowledge!

All About Identity And Security On-Premises And In The Cloud – It's Just Like An Addiction, The More You Have, The More You Want To Have!

Archive for the ‘Tools’ Category

(2019-10-06) Examining Pending Export Deletions In Azure AD Connect

Posted by Jorge on 2019-10-06


If you know FIM/MIM, you also know that Azure AD Connect is based upon that under the hood. As described in Azure AD Connect sync: Prevent accidental deletes, Azure AD Connect allows you to configure a specific threshold that represents a normal/accepted amount of deletions towards Azure AD. Now, if you have a low amount of objects that you need to investigate you can easily click through the Sync Service Manager. But what happens if you need to investigate hundreds or thousands of pending deletions? Try to do that in the Sync Service Manager and you’ll through a loooooot of pain! Are there easier ways to do that? Fortunately, YES! Therefore keep reading.

Now please aware that if the number of deletions is equal to or higher than the deletion threshold it will stop the complete export operation to Azure AD, meaning no adds, updates and deletes to Azure AD! This prevents unintended deletion due to mistakes, bad configurations, etc.

To analyze those deletions, use the next steps.

  1. Logon to the ACTIVE (NON-Staging!) AAD Connect server (To determine the ACTIVE AAD Connect Server, see below!)
  2. Open a PowerShell Command Prompt Window and export the pending exports from the connector space that needs further analysis (see below)
  3. Parse the CS Export file to make it readable (see below) (PowerShell GridView Is Opened AND A CSV File Generated!)
  4. Either use the PowerShell GridView or the CSV to analyze the data being exported!
  5. For objects being deleted check if those still exist in AD and what the state is (see below)

[ad.1] Determine The Active AAD Connect Server

Open a PowerShell Command Prompt Window, and execute:

Import-Module ADSYNC

Get-ADSyncGlobalSettingsParameter | ?{$_.Name -eq "Microsoft.Synchronize.StagingMode"} | Select Name,Value

REMARK: If the VALUE mentions TRUE, then it is the Passive (staging) Server, if the VALUE mentions FALSE or is empty, then it is the Active (Non-Staging) Server

[ad.2] Export The Pending Exports From The Connector Space That Needs Analysis

On The Active AAD Connect Server, open a PowerShell Command Prompt Window, and execute:

CD "C:\Program Files\Microsoft Azure AD Sync\Bin"
$connectorHT = New-Object system.collections.hashtable
Write-Host ""
Write-Host "+++ Available Connectors +++" -ForegroundColor Cyan
$connectorNr = 0
Get-ADSyncConnector | %{
    $connectorNr++
    $connectorName = $null
    $connectorName = $_.Name
    $connectorHT[$connectorNr.ToString()] = $connectorName
    Write-Host "[$connectorNr] – $connectorName" -ForegroundColor Magenta
    Write-Host ""
}
$chosenConnectorNr = $null
$chosenConnectorNr = Read-host "Please Choose The Connector By Typing Its Number"

$chosenConnectorName = $null
$chosenConnectorName = $connectorHT[$chosenConnectorNr]
$datetime = Get-Date -Format "yyyy-MM-dd_HH.mm.ss"
$csExportXMLFilepath = Join-Path "C:\TEMP" $($datetime + "_CS-" + $chosenConnectorName + "_PendingExports.xml")
$csExportCMD = ".\CSEXPORT.EXE `"$chosenConnectorname`" `"$csExportXMLFilepath`" /f:x"
Invoke-Expression $csExportCMD
Write-Host ""
Write-Host "Export File…….: $csExportXMLFilepath" -ForegroundColor Cyan
Write-Host ""

[ad.3] Parse The CS Export XML File

On The Active AAD Connect Server, open a PowerShell Command Prompt Window, and execute:

CD "<Folder With Script>"

$csExportCSVFilepath = $csExportXMLFilepath.TrimEnd(".xml")

.\Parse-CS-Export-XML-To-CSV.ps1 -outToAll -sourceXMLfilePaths $csExportXMLFilepath -targetFilePath $csExportCSVFilepath

REMARK: the GridView will be opened automatically!

image

Figure 1: Results After Parsing The XML File(s) To A CSV

In the GridView or Excel, any value added or deleted, will be specified as such. Unchanged values are not listed

image

Figure 2: GridView Sample Output

image

Figure 3: GridView Sample Output

image

Figure 4: GridView Sample Output

 image

Figure 5: GridView Sample Output

REMARK: To reopen the GridView using the CSV file use the following command:

Import-CSV $($csExportCSVFilepath + ".csv") | Out-Gridview

or

Import-CSV "<CSV File Path>" | Out-Gridview

[ad.5a] Check Deleted USERS Against AD

$csExportCSV = Import-CSV $($csExportCSVFilepath + ".csv")
$objectListUsers = @()
$csExportCSV | ?{$_."Object-Type" -eq "user" -And $_."Ops-Type" -eq "delete"} | %{
    $immutableID = $null
    $immutableID = $_."Source-ID"
     $userPrincipalName = $null
    $userPrincipalName = $_."AD-ID"

    $ldapFilter = $null
    $ldapFilter = "(|(raboADImmutableID=$immutableID)(userPrincipalName=$userPrincipalName))"

    $adObject = $null
    $adObject = Get-ADObject -LDAPFilter $ldapFilter -Server :3268 -Properties *

    $displayName = $null
    $status = $null
    $canonicalName = $null

    If ($adObject) {
        $displayName = $adObject.DisplayName
        $status = If (($adObject.userAccountControl -band 2) -eq "2") {"Disabled"} Else {"Enabled"}
        $canonicalName = $adObject.CanonicalName
    } Else {
        $displayName = "Unavailable"
        $status = "Unavailable"
        $canonicalName = "Unavailable"
    }

    $object = New-Object -TypeName System.Object
    $object | Add-Member -MemberType NoteProperty -Name "immutableID" -Value $immutableID
    $object | Add-Member -MemberType NoteProperty -Name "userPrincipalName" -Value $userPrincipalName
    $object | Add-Member -MemberType NoteProperty -Name "displayName" -Value $displayName
    $object | Add-Member -MemberType NoteProperty -Name "status" -Value $status
    $object | Add-Member -MemberType NoteProperty -Name "canonicalName" -Value $canonicalName
    $objectListUsers += $object
}
$objectListUsers | Out-GridView

REMARK: A Gridview will be opened automatically telling you the status of the object and if it exists in AD

[ad.5b] Check Deleted GROUPS Against AD

$objectListGroups = @()
$csExportCSV | ?{$_."Object-Type" -eq "group" -And $_."Ops-Type" -eq "delete"} | %{
    $immutableID = $null
    $immutableID = $_."Source-ID"
    $domain = $null
     $domain = $($_."AD-ID").SubString(0, $($_."AD-ID").IndexOf("\"))
    $sAMAccountName = $null
    $sAMAccountName = $($_."AD-ID").SubString($($_."AD-ID").IndexOf("\") + 1)
    $ldapFilter = $null
    $ldapFilter = "(|(raboADImmutableID=$immutableID)(sAMAccountName=$sAMAccountName))"
    $adObject = $null
    $adObject = Get-ADObject -LDAPFilter $ldapFilter -Server $domain`:389 -Properties *
    $displayName = $null
    $canonicalName = $null
    If ($adObject) {
        $displayName = $adObject.DisplayName
        $canonicalName = $adObject.CanonicalName
    } Else {
        $displayName = "Unavailable"
        $canonicalName = "Unavailable"
    }
    $object = New-Object -TypeName System.Object
    $object | Add-Member -MemberType NoteProperty -Name "immutableID" -Value $immutableID
    $object | Add-Member -MemberType NoteProperty -Name "sAMAccountName" -Value $sAMAccountName
    $object | Add-Member -MemberType NoteProperty -Name "displayName" -Value $displayName
    $object | Add-Member -MemberType NoteProperty -Name "canonicalName" -Value $canonicalName
    $objectListGroups += $object
}
$objectListGroups | Out-GridView

REMARK: A Gridview will be opened automatically telling you the status of the object and if it exists in AD

[ad.5c] Check Deleted CONTACTS Against AD

Function GuidToEscapedByte($guid) {
    $guidParts = $guid.Split("-")
     $reverse = $guidParts[0].ToCharArray()[($guidParts[0].Length – 1)..0] + $guidParts[1].ToCharArray()[($guidParts[1].Length – 1)..0] + $guidParts[2].ToCharArray()[($guidParts[2].Length – 1)..0]
    $rest = $guidParts[3].ToCharArray() + $guidParts[4].ToCharArray()
    for ($inc =0; $inc -lt $reverse.Length; $inc+=2) {
        $escapedGUID = $escapedGUID + "\" + $reverse[$inc+1] + $reverse[$inc]
    }
    for ($inc =0; $inc -lt $rest.Length; $inc+=2) {
        $escapedGUID = $escapedGUID + "\" + $rest[$inc] + $rest[$inc+1]
    }
    return $escapedGUID
}
$csExportCSV = Import-CSV $($csExportCSVFilepath + ".csv")
$objectListContacts = @()
$csExportCSV | ?{$_."Object-Type" -eq "contact" -And $_."Ops-Type" -eq "delete"} | %{
    $immutableID = $null
    $immutableID = $_."Source-ID"
    $objectGUID = $null
    $objectGUID = (New-Object -TypeName System.Guid -ArgumentList(,(([System.Convert]::FromBase64String($immutableID))))).Guid
    $objectGUIDEscaped = $null
    $objectGUIDEscaped = GuidToEscapedByte $objectGUID
    $mail = $null
    $mail = $_."AD-ID"
     $ldapFilter = $null
    $ldapFilter = "(|(objectGUID=$objectGUIDEscaped)(mail=$mail))"
    $adObject = $null
    $adObject = Get-ADObject -LDAPFilter $ldapFilter -Server :3268 -Properties *
    $displayName = $null
    $canonicalName = $null
    If ($adObject) {
        $displayName = $adObject.DisplayName
         $canonicalName = $adObject.CanonicalName
    } Else {
         $displayName = "Unavailable"
        $canonicalName = "Unavailable"
    }
    $object = New-Object -TypeName System.Object
     $object | Add-Member -MemberType NoteProperty -Name "immutableID" -Value $immutableID
    $object | Add-Member -MemberType NoteProperty -Name "mail" -Value $mail
    $object | Add-Member -MemberType NoteProperty -Name "displayName" -Value $displayName
    $object | Add-Member -MemberType NoteProperty -Name "canonicalName" -Value $canonicalName
    $objectListContacts += $object
}
$objectListContacts | Out-GridView

REMARK: A Gridview will be opened automatically telling you the status of the object and if it exists in AD

Now assuming you have confirmed all deletions are expected, you can lift the threshold or increase its value (temporarily) to allow the sync cycle to succeed! You need an Azure AD Admin Account with the Global Administrator role

  • If needed elevate your account through https://portal.azure.com/ → Privileged Identity Management \ Azure AD Roles \ Global Administrator – Activate
  • On the active AAD Connect server, open a PowerShell Command prompt Window and execute:

$aadAdminCreds=Get-Credential

Get-ADSyncExportDeletionThreshold -AADCredential $aadAdminCreds

Disable-ADSyncExportDeletionThreshold -AADCredential $aadAdminCreds

REMARK: The sync engine maybe synching as you do that and you may receive an error. Just wait until the sync engine finishes.

  • As soon as the sync engine is not executing a sync cycle, execute:

Start-ADSyncCycle -PolicyType Delta

  • As soon as that sync cycle has finished enable the threshold again using the previous value

Enable-ADSyncExportDeletionThreshold -DeletionThreshold <value> -AADCredential $aadAdminCreds

PS: this script also works for Pending Export Deletes in FIM/MIM and the script supports multiple source XML files (each for a different CS) as input files!

Ohhh, and I almost forgot! You can download the script from here! Smile

Cheers,

Jorge

————————————————————————————————————————————————————-
This posting is provided "AS IS" with no warranties and confers no rights!
Always evaluate/test everything yourself first before using/implementing this in production!
This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
————————————————————————————————————————————————————-
########################### Jorge’s Quest For Knowledge ##########################
####################
http://JorgeQuestForKnowledge.wordpress.com/ ###################
————————————————————————————————————————————————————-

Posted in Azure AD Connect, Connector/MA, CSExport, Forefront Identity Manager (FIM) Sync, Microsoft Identity Manager (MIM), PowerShell, Tooling/Scripting, Tools, Windows Azure Active Directory | 2 Comments »

(2016-05-29) FIM PowerShell CMDlets Have Been Updated

Posted by Jorge on 2016-05-29


Brain Desmond has updated the FIM PowerShell Modules on Codeplex.

Download:

Documentation:

Significant number of enhancements and fixes, including:

New Cmdlets

  • New-FimEmailTemplate
  • New-FimWorkflowDefinition
  • New-FimManagementPolicyRule
  • New-FimSearchScope
  • New-FimNavigationBarLink
  • Get-FimSynchronizationRuleDependencyTree

Enhancements

  • Add Manual Members Support to New-FimSet
  • Add PassThru Switch Schema Cmdlets
  • AllowAuthorizationException switch on New-FimImportObject
  • Add Mode to Get-FimRequestParameter
  • Support null values for New-FimImportChange
  • Support Constants in Sync Rules in Get-ExportAttributeFlow

Bugs Fixed

  • 1850: FimSyncPowerShellModule Should Not Export Internal Functions
  • 1851: Create-ImportFileFromCSEntry Uses an Unapproved Verb
  • 1852: Update Help Text in FimSyncPowerShellModule to use Approved Names, Domains
  • 1885: Objects Emitted by Module Should have a Custom Type Name
  • 1886: Change New-FimImportChange, New-FimImportObject to use ValidateSet
  • 1888: Decorate New-FimSchemaAttribute with Cmdlet Attributes
  • 1889: Decorate New-FimSchemaObject with Parameter Attributes
  • 1939: Improve PSSnapin Load Error Handling
  • 1941: Update Comment Based Help
  • 1894: New-FimImportChange Does Not Support Numeric Inputs
  • 1896: New-FimImportChange Should Support Guid Values
  • 1897: Hide Progress Bar on Module Calls
  • 1948: Fix ‘DateTime’ $DataType casing on New-FimSchemaAttribute
  • 1951: Output Correct Data Type from New-FimSchemaBinding
  • 1968: SynchronizationRuleParameters typing issue
  • 1973: E2E attribute flow: constant sync rule values
  • 1982: Fixed a bug with OSR-Expression export flows. Added the following info to the output:
    • Allow nulls
    • Initial flow only
    • Is existence test
  • 1991: Get-MetaverseSchema Does Not Triage Boolean Attributes Correctly
  • 1997: If the msidmOutboundIsFilterBased is false, no value are submit to FIM and when you edit the SR with the form, you get a change for this attribute (no intial value to false)
  • 2083: Missing Error Handling in New-FimImportObject

Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
#########
http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————

Posted in Forefront Identity Manager (FIM) Portal, Forefront Identity Manager (FIM) Sync, PowerShell, Tooling/Scripting, Tools, Tools | Leave a Comment »

(2016-05-25) LithNet FIM Sync PowerShell CMDlets

Posted by Jorge on 2016-05-25


Ryan Newington  (Twitter and Blog), yet again wrote and created an impressive PowerShell module to manage the FIM/MIM Sync Engine. Many stuff to manage the FIM/MIM Sync Engine that was not yet possible through PowerShell, is now possible!!!

Lithnet FIM/MIM Synchronization Service PowerShell Module

DISCLAIMER

WARNING: USE THIS TOOL AT YOUR OWN RISK

This tool is provided for testing and diagnostic purposes and is intended for use in development and test environments. Any problems that arise from the use of the tool are not supported by the developers or by Microsoft.

The PowerShell module exposes functionality using a combination of

Supported WMI interfaces
Wrapping existing PowerShell modules
Wrapping existing executables
Libraries that the synchronization client UI uses to interface with the sync engine itself. These libraries are undocumented APIs.

The module does NOT interface with the sync engine database in any way.

It does not provide any mechanism to alter the internal configuration of the sync engine, unless an executable or documented API is available for that.

The developers make no warranties as to the suitability of these tools for use in your environment, nor will we be liable for any financial or other damages arising from the use of these tools.

image

Figure 1: The List Of PowerShell CMDlets In The Lithnet PowerShell Module For FIM/MIM Sync

Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
#########
http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————

Posted in Forefront Identity Manager (FIM) Sync, PowerShell, Tools | Leave a Comment »

(2015-12-14) LithNet Utilities And Tools For Your FIM/MIM Solution

Posted by Jorge on 2015-12-14


There is a guy called Ryan Newington  (Twitter and Blog), and he wrote and created some impressive utilities and tools that you can use in your challenge to design and configure an Identity Management system based  upon either FIM 2010 R2 or MIM 2016.

Lithnet Metadirectory Services Utilities

  • Description: The Lithnet Metadirectory Services Utilities package is a .NET library containing extensions and utilities for writing code for the FIM sync engine. The library contains various helper classes and extensions for objects in the Microsoft.MetadirectoryServices namespace, such as the CSEntryChange. It allows you to reduce code and introduces new functions, such as XML serialization of native metadirectory services objects. It can be used in any rules extension or ECMA2.2 project, along side the Microsoft.MetadirectoryServices component.
  • Documentation: https://lithnetmsu.codeplex.com/documentation
  • Download: https://www.nuget.org/packages/Lithnet.MetadirectoryServices/

Lithnet FIM Service REST API

Lithnet FIM PowerShell Module

Lithnet FIM Service Client

Lithnet FIM Unix/Linux SSH MA

  • Description: The Lithnet SSH MA is a ForeFront Identity Manager (FIM) ECMA2.2 management agent used to provision and synchronize objects to unix and linux systems using SSH. The management agent supports: Full and (optionally) delta imports, Exports (supporting either object replace, attribute replace, attribute update, or multivalued reference attribute update modes), Password set and change, Username and RSA key-based logins, as well as username/password logins, Dynamic DN construction
  • Documentation: https://lithnetsshma.codeplex.com/documentation
  • Download: https://lithnetsshma.codeplex.com/releases/view/113093

Lithnet ACMA

  • Description: Lithnet ACMA is a codeless rules engine for Microsoft Forefront Identity Manager 2010 R2. ACMA provides a means for performing powerful rules-based construction of objects and attributes without the need to write custom code.
    ACMA is implemented as an extensible management agent (ECMA2.2), built upon an SQL Server 2012 database, and comes with a powerful UI-based rules editor and PowerShell extensions.
  • Documentation: https://acma.codeplex.com/documentation
  • Download: https://acma.codeplex.com/releases/view/617213

Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
#########
http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————

Posted in Forefront Identity Manager (FIM) Portal, Forefront Identity Manager (FIM) Sync, Tools, Tools | Leave a Comment »