MOFCompare.psm1
using namespace System.Collections.Generic using namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal function Compare-MOF { [cmdletbinding()] param( [parameter(Mandatory)] $ReferenceMOF, [parameter(Mandatory, ValueFromPipeline = $true)] $DifferencingMOF, [parameter()] [switch] $CompareProperties ) process { $CompareResult = Compare-Object $ReferenceMOF.keys.ForEach{ $_ } $DifferencingMOF.keys.ForEach{ $_ } -IncludeEqual -PassThru $ReturnObject = [pscustomobject]@{ Missing = $CompareResult.Where( { $_.SideIndicator -eq "<=" }) New = $CompareResult.Where( { $_.SideIndicator -eq "=>" }) Changed = $null } if ($CompareProperties.IsPresent) { [Dictionary[string, PSCustomObject[]]]$ChangedResources = (New-Object 'System.Collections.Generic.Dictionary[string, PSCustomObject[]]') Foreach ($key in $CompareResult.Where( { $_.SideIndicator -eq "==" })) { $propertiestocheck = $ReferenceMOF[$key].CimInstanceProperties.name.Where{ $key -notin @("sourceinfo") } if (Compare-Object $ReferenceMOF[$key] $DifferencingMOF[$key] -Property $propertiestocheck) { $changedproperties = @() foreach ($property in $propertiestocheck) { $result = Compare-Object $ReferenceMOF[$key] $DifferencingMOF[$key] -Property $property if ($result) { $changedproperties += [PSCustomObject]@{ Name = $property NewValue = $result.where( { $_.SideIndicator -eq "=>" }).$property OldValue = $result.where( { $_.SideIndicator -eq "<=" }).$property } } } $ChangedResources.Add($ReferenceMOF[$key].ResourceId, $changedproperties) } } $ReturnObject.Changed = $ChangedResources } Write-Output $ReturnObject } } function ConvertFrom-MOF { [cmdletbinding()] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Path to one or more MOFs.")] [Alias("PSPath")] [ValidateNotNullOrEmpty()] [string] $Path ) process { [Dictionary[Tuple`3[string, string, string], ciminstance]]$ConfigurationElements = (New-Object 'System.Collections.Generic.Dictionary[Tuple`3[string,string,string], ciminstance]') [DscClassCache]::ImportInstances((Resolve-Path $Path)) | Foreach-Object -Process { trap { $item } $item = $_ if ($_.cimclass.cimclassname -eq "OMI_ConfigurationDocument") { $OMIConfig = $_ } else { $KeyValues = $_.CimInstanceProperties.Where{ $_.flags -match 'key' }.Value -join ';' $ConfigurationElements.Add( ([Tuple]::Create($_.modulename, $_.cimclass.cimclassname, $KeyValues)), $_ ) } } Write-Output $ConfigurationElements } } function Initialize-DscResourceCache { [cmdletbinding()] param( [parameter()] [string[]] $ModulePathsToImport ) begin { Reset-DscResourceCache $OldPSModulePath = $env:PSModulePath if ($ModulePathsToImport.count -gt 0) { $env:PSModulePath = $ModulePathsToImport.ForEach{ Resolve-Path $_ -ea SilentlyContinue } -join ';' } } process { Get-Module -ListAvailable | Import-DscResourceToCache -ErrorAction Continue } end { $env:PSModulePath = $OldPSModulePath } } function Import-DscResourceToCache { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [System.Management.Automation.PSModuleInfo] $Module ) begin { $errors = New-Object System.Collections.ObjectModel.Collection[Exception] } process { trap { } Write-Verbose "Processing module $($Module.Name) $($Module.Version)" # script/binary resources $importedSchemaFile = "" [DscClassCache]::ImportCimKeywordsFromModule($Module, $null, [ref]$importedSchemaFile) | Out-Null # class resources [DscClassCache]::ImportClassResourcesFromModule($Module, $Module.ExportedDscResources, $null) | Out-Null } } function Reset-DscResourceCache { [cmdletbinding()] param() process { [DscClassCache]::ClearCache() [DscClassCache]::LoadDefaultCimKeywords() } } Export-ModuleMember -Function Compare-MOF, ConvertFrom-MOF, Initialize-DscResourceCache |