DscResources/MimSyncImportAttributeFlowRule/MimSyncImportAttributeFlowRule.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $FakeIdentifier, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $MVObjectType, [parameter(Mandatory = $true)] [System.String] $MVAttribute, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [parameter(Mandatory = $true)] [ValidateSet("direct-mapping","scripted-mapping","constant-mapping","dn-part-mapping")] [String] $Type, [String[]] $SrcAttribute, [String] $ConstantValue, [Uint16] $DNPart, [String] $ScriptContext ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose $xPathFilter = Get-MimSyncXpathForIafRule @PSBoundParameters Write-Verbose " Using XPath: $xPathFilter" $fimSyncObject = Select-Xml -Path (Join-Path (Get-MimSyncConfigCache) mv.xml) -XPath $xPathFilter if (-not $fimSyncObject) { ### No matching object so return nothing return } if ($fimSyncObject -is [Array]) { ### Mre than one matching object so return nothing Write-Warning "More than one object found - expected just one!" return } $fimSrcAttributes = @() foreach($fimSrcAttribute in Select-Xml -Xml $fimSyncObject.Node -XPath '*/src-attribute') { $fimSrcAttributes += $fimSrcAttribute } $outputObject = @{ ManagementAgentName = $ManagementAgentName CDObjectType = $CDObjectType MVObjectType = $MVObjectType MVAttribute = $MVAttribute Type = $Type ID = $fimSyncObject.Node.ID } switch ($Type) { 'scripted-mapping' { $outputObject.Add('ScriptContext',$fimSyncObject.Node.'scripted-mapping'.'script-context') $outputObject.Add('SrcAttribute', $fimSrcAttributes) } 'direct-mapping' { $outputObject.Add('SrcAttribute', $fimSrcAttributes) } 'constant-mapping' { $outputObject.Add('ConstantValue', $fimSyncObject.Node.'constant-mapping'.'constant-value') } 'dn-part-mapping' { $outputObject.Add('DNPart', $fimSyncObject.Node.'dn-part-mapping'.'dn-part') } Default {} } Write-Output $outputObject } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $FakeIdentifier, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $MVObjectType, [parameter(Mandatory = $true)] [System.String] $MVAttribute, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [parameter(Mandatory = $true)] [ValidateSet("direct-mapping","scripted-mapping","constant-mapping","dn-part-mapping")] [String] $Type, [String[]] $SrcAttribute, [String] $ConstantValue, [Uint16] $DNPart, [String] $ScriptContext, [ValidateSet("Present","Absent")] [System.String] $Ensure ) Write-Warning "DSC resources for the Synchronization Service are not able to update the Synchronization configuration." } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.String] $FakeIdentifier, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $MVObjectType, [parameter(Mandatory = $true)] [System.String] $MVAttribute, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [parameter(Mandatory = $true)] [ValidateSet("direct-mapping","scripted-mapping","constant-mapping","dn-part-mapping")] [String] $Type, [String[]] $SrcAttribute, [String] $ConstantValue, [Uint16] $DNPart, [String] $ScriptContext, [ValidateSet("Present","Absent")] [System.String] $Ensure ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose ### Get the XML from the server configuration files Write-Verbose "Finding import attribute flow rule [$ManagementAgentName].$CDObjectType.[$($SrcAttribute -Join ',')] --> MV.$MVObjectType.[$MVAttribute] ..." $xPathFilter = Get-MimSyncXpathForIafRule @PSBoundParameters Write-Verbose " Using XPath: $xPathFilter" $fimSyncObject = Select-Xml -Path (Join-Path (Get-MimSyncConfigCache) mv.xml) -XPath $xPathFilter $objectsAreTheSame = $true if ($Ensure -eq 'Present') { if ($fimSyncObject -eq $null) { Write-Verbose "Attribute flow rule not found: $Name." $objectsAreTheSame = $false } else { Write-Verbose "Attribute flow rule found, diffing the properties..." #region Compare type Write-Verbose " Comparing property 'type'" if ($fimSyncObject.Node.'direct-mapping') { $fimMappingType = 'direct-mapping' } elseif ($fimSyncObject.Node.'scripted-mapping') { $fimMappingType = 'scripted-mapping' } elseif ($fimSyncObject.Node.'constant-mapping') { $fimMappingType = 'constant-mapping' } elseif ($fimSyncObject.Node.'dn-part-mapping') { $fimMappingType = 'dn-part-mapping' } elseif ($fimSyncObject.Node.'sync-rule-mapping') { $fimMappingType = 'sync-rule-mapping' } else { Write-Error "Unexpected rule type" } Write-Verbose " From DSC: $Type" Write-Verbose " From MIM: $fimMappingType" if ($Type -ne $fimMappingType) { Write-Warning " 'type' property is not the same." $objectsAreTheSame = $false } #endregion #region Compare cd-object-type Write-Verbose " Comparing property 'cd-object-type'" Write-Verbose " From DSC: $CDObjectType" Write-Verbose " From MIM: $($fimSyncObject.Node.'cd-object-type')" if ($fimSyncObject.Node.'cd-object-type' -ne $CDObjectType) { Write-Warning " 'cd-object-type' property is not the same." $objectsAreTheSame = $false } #endregion #region Compare script-context if ($Type -eq 'scripted-mapping') { Write-Verbose " Comparing property 'script-context'" Write-Verbose " From DSC: $ScriptContext" Write-Verbose " From MIM: $($fimSyncObject.Node.'scripted-mapping'.'script-context')" if ($fimSyncObject.Node.'scripted-mapping'.'script-context' -ne $ScriptContext) { Write-Warning " 'script-context' property is not the same." $objectsAreTheSame = $false } } #endregion #region Compare src-attribute if ($Type -in 'scripted-mapping','direct-mapping') { $fimSrcAttributes = @() foreach($fimSrcAttribute in Select-Xml -Xml $fimSyncObject.Node -XPath '*/src-attribute') { $fimSrcAttributes += $fimSrcAttribute } Write-Verbose " Comparing property 'src-attribute'" Write-Verbose " From DSC: $($SrcAttribute -join ',')" Write-Verbose " From MIM: $($fimSrcAttributes -join ',')" if (Compare-Object -ReferenceObject $SrcAttribute -DifferenceObject $fimSrcAttributes ) { Write-Warning " 'src-attribute' property is not the same." $objectsAreTheSame = $false } } #endregion #region Compare constant-value if ($Type -eq 'constant-mapping') { Write-Verbose " Comparing property 'constant-mapping'" Write-Verbose " From DSC: $ConstantValue" Write-Verbose " From MIM: $($fimSyncObject.Node.'constant-mapping'.'constant-value')" if ($fimSyncObject.Node.'constant-mapping'.'constant-value' -ne $ConstantValue) { Write-Warning " 'constant-value' property is not the same." $objectsAreTheSame = $false } } #endregion #region Compare dn-part if ($Type -eq 'dn-part-mapping') { Write-Verbose " Comparing property 'dn-part'" Write-Verbose " From DSC: $DNPart" Write-Verbose " From MIM: $($fimSyncObject.Node.'dn-part-mapping'.'dn-part')" if ($fimSyncObject.Node.'dn-part-mapping'.'dn-part' -ne $DNPart) { Write-Warning " 'dn-part' property is not the same." $objectsAreTheSame = $false } } #endregion $objectsAreTheSame = $objectsAreTheSame } } elseif($Ensure -eq 'Absent') { if ($fimSyncObject -ne $null) { Write-Warning "Attribute flow rule found ($Name) but is supposed to be Absent. DESTROY!!!" $objectsAreTheSame = $false } else { $objectsAreTheSame = $true } } else { Write-Error "Expected the 'Ensure' parameter to be 'Present' or 'Absent'" } Write-Verbose "Returning: $objectsAreTheSame" return $objectsAreTheSame } function Get-MimSyncXpathForIafRule { param ( $FakeIdentifier, $Ensure, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $MVObjectType, [parameter(Mandatory = $true)] [System.String] $MVAttribute, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [parameter(Mandatory = $true)] [ValidateSet("direct-mapping","scripted-mapping","constant-mapping","dn-part-mapping")] [String] $Type, [String[]] $SrcAttribute, [String] $ConstantValue, [Uint16] $DNPart, [String] $ScriptContext ) ### Find an MA XML by Name $maDataXml = Select-Xml -Path (Join-Path (Get-MimSyncConfigCache) *.xml)-XPath "//ma-data[name='$ManagementAgentName']" | Select-Object -First 1 $managementAgentID = $maDataXml.Node.id ### Get the XML from the server configuration files Write-Verbose "Finding import attribute flow rule [$ManagementAgentName].$CDObjectType.[$($SrcAttribute -Join ',')] --> MV.$MVObjectType.[$MVAttribute] ..." $xPathFilter = "//mv-data/import-attribute-flow/import-flow-set[@mv-object-type='$MVObjectType']/import-flows[@mv-attribute='$MVAttribute']/import-flow[@src-ma='$managementAgentID' and @cd-object-type='$CDObjectType' and $Type" switch ($Type) { 'scripted-mapping' { $xPathFilter += " and scripted-mapping[script-context='$ScriptContext']]" } 'direct-mapping' { $xPathFilter += " and direct-mapping[src-attribute='$SrcAttribute']]" } 'constant-mapping' { $xPathFilter += " and constant-mapping[constant-value='$ConstantValue']]" } 'dn-part-mapping' { $xPathFilter += " and dn-part-mapping[dn-part='$DNPart']]" } Default {} } return $xPathFilter } Export-ModuleMember -Function *-TargetResource |