DscResources/MimSyncRunProfile/MimSyncRunProfile.psm1
data DscParameterToXmlNodeMap { ConvertFrom-StringData @' CreationTime = creation-time LastModificationTime = last-modification-time Name = name RunSteps = configuration/step Version = version '@ } function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose ### Get the object XML from the server configuration files Write-Verbose "Finding run profile '$Name' on management agent '$ManagementAgentName'..." $xPathFilter = "//ma-data[name='$ManagementAgentName']/ma-run-data/run-configuration[name='$Name']" Write-Verbose " Using XPath: $xPathFilter" $fimSyncObject = Select-Xml -Path (Join-Path (Get-MimSyncConfigCache) *.xml) -XPath $xPathFilter if (-not $fimSyncObject) { ### No matching object so return nothing return } $runSteps = @($fimSyncObject.Node.SelectNodes($DscParameterToXmlNodeMap.RunSteps) | Convert-MimSyncRunStepToCimInstance) Write-Output @{ Name = $Name ManagementAgentName = $ManagementAgentName CreationTime = $fimSyncObject.Node.SelectSingleNode($DscParameterToXmlNodeMap.CreationTime).InnerText LastModificationTime = $fimSyncObject.Node.SelectSingleNode($DscParameterToXmlNodeMap.LastModificationTime).InnerText Version = $fimSyncObject.Node.SelectSingleNode($DscParameterToXmlNodeMap.Version).InnerText RunSteps = $runSteps } } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [Microsoft.Management.Infrastructure.CimInstance[]] $RunSteps, [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] $Name, [parameter(Mandatory = $true)] [System.String] $ManagementAgentName, [Microsoft.Management.Infrastructure.CimInstance[]] $RunSteps, [ValidateSet("Present","Absent")] [System.String] $Ensure ) ### Check the schema cache and update if necessary Write-MimSyncConfigCache -Verbose ### Get the FIM object XML from the server configuration files Write-Verbose "Finding run profile '$Name' on management agent '$ManagementAgentName'..." $xPathFilter = "//ma-data[name='$ManagementAgentName']/ma-run-data/run-configuration[name='$Name']" Write-Verbose " Using XPath: $xPathFilter" $fimSyncObject = Select-Xml -Path (Join-Path (Get-MimSyncConfigCache) *.xml) -XPath $xPathFilter $objectsAreTheSame = $true if ($Ensure -eq 'Present') { if ($fimSyncObject -eq $null) { Write-Verbose "Run Profile not found: $Name." $objectsAreTheSame = $false } else { Write-Verbose "Run Profile found, diffing the properties: $($fimSyncObject.Path)" $objectsAreTheSame = $true foreach ($dscResourceProperty in Get-DscResource -Name MimSyncRunProfile | Select-Object -ExpandProperty Properties) { if ($dscResourceProperty.Name -in 'Ensure','DependsOn','ManagementAgentName','PsDscRunAsCredential') { Write-Verbose " Skipping system-owned attribute: $($dscResourceProperty.Name)" continue } if ($dscResourceProperty.Name -eq 'RunSteps') { Write-Verbose " Comparing property $($dscResourceProperty.Name) using XPath: $($DscParameterToXmlNodeMap.($dscResourceProperty.Name))" $valuesFromDSC = @($RunSteps) $valuesFromFIM = @($fimSyncObject.Node.SelectNodes($DscParameterToXmlNodeMap.($dscResourceProperty.Name)) | Convert-MimSyncRunStepToCimInstance) Write-Verbose " From DSC: $($valuesFromDSC.count)" Write-Verbose " From FIM: $($valuesFromFIM.count)" #TODO - make this compare smarter - for example it needs to interpret a missing input as equal to a present input that has a null value $valueCompare = Compare-Object -ReferenceObject $valuesFromDSC -DifferenceObject $valuesFromFIM -Property StepType,StepSubtype,PartitionIdentifier,DropFileName,PageSize,Timeout,ObjectDeleteLimit,ObjectProcessLimit,InputFile if ($valueCompare) { Write-Warning " '$($dscResourceProperty.Name)' property is not the same." $objectsAreTheSame = $false Write-Verbose " From DSC: $(($valueCompare | Where-Object SideIndicator -eq '<='))" Write-Verbose " From FIM: $(($valueCompare | Where-Object SideIndicator -eq '=>'))" } } 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 } } } } } elseif($Ensure -eq 'Absent') { if ($fimSyncObject -ne $null) { Write-Warning "Run Profile found ($Name) but is supposed to be Absent. DESTROY!!!" $objectsAreTheSame = $false } } else { Write-Error "Expected the 'Ensure' parameter to be 'Present' or 'Absent'" } Write-Verbose "Returning: $objectsAreTheSame" return $objectsAreTheSame } Export-ModuleMember -Function *-TargetResource |