Bob Bradley 1 year ago • updated by Carol Wapshere 1 year ago 2

I am working on a variation of the Safety Catch script for a customer whereby I have an MA (sync) filter specified in the application settings of MIISERVER.EXE.CONFIG file, and I need to exclude CS objects that are filtered disconnectors as a result. The following is my code - which works OK, but is kind of slow, and I am after some ideas as to how to do this more efficiently. Any ideas please?

The following code snippet is a variant of the "Get-ThresholdCounters" function, and uses a new function to return the XML from miiserver.exe.config.

$FIMServicePath = "E:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\"

    [xml]$directoryEntries = Get-AuditDropFile -FIMServicePath $FIMServicePath
    $ns = New-Object Xml.XmlNamespaceManager($directoryEntries.NameTable)
    $ns.AddNamespace( "a", $directoryEntries.DocumentElement.xmlns )

    # Examine delta data
    $Counters.StepType = $directoryEntries.mmsml."step-type"
    $deltas = $null #$directoryEntries.SelectNodes("//a:delta",$ns)

    # Client only - load miiserver.exe.config files to read config data
    [xml]$fimConfig = Get-FIMSyncConfigFile -FIMServicePath $FIMServicePath
    $sourceContactDNsToJoin = @($fimConfig.configuration.applicationSettings.'Mms_ManagementAgent_CORPExtensions.Properties.Settings'.setting.Where({$_.name -eq "sourceContactDNsToJoin"}).value.ArrayOfString.string)

    if ($sourceContactDNsToJoin) {
        # Client only
        $deltasToRemove = @()
        foreach($dn in $sourceContactDNsToJoin) {
            $deltasToRemove += $directoryEntries.SelectNodes("//a:delta",$ns).Where({$_.dn -like "*$dn"}).dn
        $deltas = $directoryEntries.SelectNodes("//a:delta",$ns).Where({$_.dn -notin $deltasToRemove})
    } else {
        $deltas = $directoryEntries.SelectNodes("//a:delta",$ns)

Any help most appreciated.

In case you were wondering, the $sourceContactDNsToJoin variable is a collection of DNs such that all objects below this node in the LDAP subtree are to be filtered.


Where is the inefficiency do you think? Is it in loading the XML in the first place (can't see here how you're doing that - get-content?) or in looping through?

Looping is usually pretty quick and I tend to find that exporting and loading the XML takes all the time. I have a stylesheet that breaks the csexport file down into individual xml files per csobject which are then very fast to read and loop through. It completely changed the performance of my Pending Exports script my many orders of magnitude - in fact that script didn't even work on large csexports before.

The other alternative - I know you don't like this - but you can go through the database. It is possible to do SQL queries into the XML structure, and you will entirely remove the need to do a csexport at all.