DscResources/MimSyncJoinRule/MimSyncJoinRule.psm1
data DscParameterToXmlNodeMap { ConvertFrom-StringData @' CDObjectType = //join/join-profile[@cd-object-type='{0}'] JoinCriterion = join-criterion JoinCriteriaType = join-cri-type MVObjectType = mv-object-type MVAttribute = mv-attribute CDAttribute = src-attribute ResolutionType = resolution/type ScriptContext = join-criterion/resolution/script-context '@ } data XmlParameters { 'JoinCriterion' } function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $CDObjectType ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose $svrexportPath = Get-MimSyncConfigCache Write-Verbose "Getting sync configuration files from '$svrexportPath'" ### Get the FIM object XML from the server configuration files Write-Verbose "Finding join rule with a CD object type of '$CDObjectType' on management agent '$ManagementAgentName'..." $xPathFilter = "//ma-data[name='$ManagementAgentName']/join/join-profile[@cd-object-type='$CDObjectType']" Write-Verbose " Using XPath: $xPathFilter" $fimSyncObject = Select-Xml -Path (Join-Path $svrexportPath *.xml) -XPath $xPathFilter if (-not $fimSyncObject) { Write-Warning "Join Rule not found: $Name." return } $joinCriterion = @($fimSyncObject.Node.SelectNodes($DscParameterToXmlNodeMap.JoinCriterion) | Convert-MimSyncJoinCriterionToCimInstance) Write-Output @{ ManagementAgentName = $Name CDObjectType = $CDObjectType JoinCriterion = $joinCriterion } } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [Microsoft.Management.Infrastructure.CimInstance[]] $JoinCriterion, [ValidateSet("Present","Absent")] [System.String] $Ensure ) Write-Warning "DSC resources for the MIM Synchronization Service are not able to update the MIM Synchronization configuration." } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [parameter(Mandatory = $true)] [System.String] $CDObjectType, [Microsoft.Management.Infrastructure.CimInstance[]] $JoinCriterion, [ValidateSet("Present","Absent")] [System.String] $Ensure ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose $svrexportPath = Get-MimSyncConfigCache Write-Verbose "Getting sync configuration files from '$svrexportPath'" ### Get the FIM object XML from the server configuration files Write-Verbose "Finding join rule with a CD object type of '$CDObjectType' on management agent '$ManagementAgentName'..." $fimSyncObject = Select-Xml -Path (Join-Path $svrexportPath *.xml) -XPath "//ma-data[name='$ManagementAgentName']/join/join-profile[@cd-object-type='$CDObjectType']" $objectsAreTheSame = $true if ($Ensure -eq 'Present') { if ($fimSyncObject -eq $null) { Write-Warning "Join Rule not found: $Name." return $false } else { Write-Verbose "Join Rule found, diffing the properties: $($fimSyncObject.Path)" $objectsAreTheSame = $true foreach ($dscResourceProperty in Get-DscResource -Name MimSyncJoinRule | Select-Object -ExpandProperty Properties) { if ($dscResourceProperty.Name -in 'Ensure','DependsOn','PsDscRunAsCredential','ManagementAgentName','CDObjectType') { Write-Verbose " Skipping system-owned attribute: $($dscResourceProperty.Name)" continue } if ($dscResourceProperty.Name -eq 'JoinCriterion') { Write-Verbose " Comparing property $($dscResourceProperty.Name) using XPath: $($DscParameterToXmlNodeMap.($dscResourceProperty.Name))" $valuesFromDSC = @($JoinCriterion) $valuesFromFIM = @($fimSyncObject.Node.SelectNodes($DscParameterToXmlNodeMap.($dscResourceProperty.Name)) | Convert-MimSyncJoinCriterionToCimInstance) Write-Verbose " From DSC: $($valuesFromDSC.count)" Write-Verbose " From FIM: $($valuesFromFIM.count)" $JoinCriterionCompareResults = Compare-Object -ReferenceObject $valuesFromDSC -DifferenceObject $valuesFromFIM -Property MVObjectType,ResolutionType,ResolutionScriptContext,Order $AttributeMappingCompareResults = Compare-Object -ReferenceObject $valuesFromDSC.AttributeMapping -DifferenceObject $valuesFromFIM.AttributeMapping -Property MVAttribute,CDAttribute,MappingType,ScriptContext if ($JoinCriterionCompareResults) { Write-Warning " '$($dscResourceProperty.Name)' property is not the same." $objectsAreTheSame = $false Write-Verbose " From DSC: $(($JoinCriterionCompareResults | Where-Object SideIndicator -eq '<=' | Format-Table -AutoSize | out-string))" Write-Verbose " From FIM: $(($JoinCriterionCompareResults | Where-Object SideIndicator -eq '=>' | Format-Table -AutoSize | out-string))" } elseif ($AttributeMappingCompareResults) { Write-Warning " '$($dscResourceProperty.Name)' attribute mappings property is not the same." $objectsAreTheSame = $false Write-Verbose " From DSC: $(($AttributeMappingCompareResults | Where-Object SideIndicator -eq '<=' | Format-Table -AutoSize | out-string))" Write-Verbose " From FIM: $(($AttributeMappingCompareResults | Where-Object SideIndicator -eq '=>' | Format-Table -AutoSize | out-string))" } } else { Write-Verbose " Comparing property '$($dscResourceProperty.Name)' using XPath: $($DscParameterToXmlNodeMap.($dscResourceProperty.Name))" $fimValue = $fimSyncObject.Node.SelectSingleNode($DscParameterToXmlNodeMap.($dscResourceProperty.Name)).InnerText if ($dscResourceProperty.PropertyType -eq '[bool]') { $fimValue = [Convert]::ToBoolean([int]$fimValue) #HACK - not loving this } Write-Verbose " From DSC: $($PSBoundParameters[$dscResourceProperty.Name])" Write-Verbose " From FIM: $fimValue" if ((-not $PSBoundParameters.ContainsKey($dscResourceProperty.Name)) -and [String]::IsNullOrEmpty($fimValue)) { #Empty on both sides, do nothing } elseif ($PSBoundParameters[$dscResourceProperty.Name] -ne $fimValue) { Write-Warning " '$($dscResourceProperty.Name)' property is not the same." $objectsAreTheSame = $false } } } Write-Verbose "Returning: $objectsAreTheSame" return $objectsAreTheSame } } elseif($Ensure -eq 'Absent') { if ($fimSyncObject -ne $null) { Write-Warning "Join Rule found ($Name) but is supposed to be Absent. DESTROY!!!" return $false } else { return $true } } else { Write-Error "Expected the 'Ensure' parameter to be 'Present' or 'Absent'" } } Export-ModuleMember -Function *-TargetResource |