Overview
ConfigurationProcessor is the central class for interacting with configuration sets. It provides methods to:
- Open and parse configuration files
- Apply configuration sets to the system
- Test if the system matches the desired state
- Get current system state
- Check for conflicts between configurations
- Manage configuration history
Class Definition
runtimeclass ConfigurationProcessor
{
ConfigurationProcessor(IConfigurationSetProcessorFactory factory);
// Diagnostics
event EventHandler<IDiagnosticInformation> Diagnostics;
DiagnosticLevel MinimumLevel;
// Telemetry
String Caller;
Guid ActivityIdentifier;
Boolean GenerateTelemetryEvents;
// Events
event TypedEventHandler<ConfigurationSet, ConfigurationChangeData> ConfigurationChange;
// History
IVector<ConfigurationSet> GetConfigurationHistory();
IAsyncOperation<IVector<ConfigurationSet>> GetConfigurationHistoryAsync();
// Opening configurations
OpenConfigurationSetResult OpenConfigurationSet(IInputStream stream);
IAsyncOperation<OpenConfigurationSetResult> OpenConfigurationSetAsync(IInputStream stream);
// Conflict detection
IVector<ConfigurationConflict> CheckForConflicts(
IVectorView<ConfigurationSet> configurationSets,
Boolean includeConfigurationHistory
);
IAsyncOperation<IVector<ConfigurationConflict>> CheckForConflictsAsync(
IVectorView<ConfigurationSet> configurationSets,
Boolean includeConfigurationHistory
);
// Details
GetConfigurationSetDetailsResult GetSetDetails(
ConfigurationSet configurationSet,
ConfigurationUnitDetailFlags detailFlags
);
IAsyncOperationWithProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult>
GetSetDetailsAsync(
ConfigurationSet configurationSet,
ConfigurationUnitDetailFlags detailFlags
);
GetConfigurationUnitDetailsResult GetUnitDetails(
ConfigurationUnit unit,
ConfigurationUnitDetailFlags detailFlags
);
IAsyncOperation<GetConfigurationUnitDetailsResult> GetUnitDetailsAsync(
ConfigurationUnit unit,
ConfigurationUnitDetailFlags detailFlags
);
// Apply operations
ApplyConfigurationSetResult ApplySet(
ConfigurationSet configurationSet,
ApplyConfigurationSetFlags flags
);
IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData>
ApplySetAsync(
ConfigurationSet configurationSet,
ApplyConfigurationSetFlags flags
);
ApplyConfigurationUnitResult ApplyUnit(ConfigurationUnit unit);
IAsyncOperation<ApplyConfigurationUnitResult> ApplyUnitAsync(ConfigurationUnit unit);
// Test operations
TestConfigurationSetResult TestSet(ConfigurationSet configurationSet);
IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult>
TestSetAsync(ConfigurationSet configurationSet);
TestConfigurationUnitResult TestUnit(ConfigurationUnit unit);
IAsyncOperation<TestConfigurationUnitResult> TestUnitAsync(ConfigurationUnit unit);
// Get settings
GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit);
IAsyncOperation<GetConfigurationUnitSettingsResult> GetUnitSettingsAsync(ConfigurationUnit unit);
GetAllConfigurationUnitSettingsResult GetAllUnitSettings(ConfigurationUnit unit);
IAsyncOperation<GetAllConfigurationUnitSettingsResult> GetAllUnitSettingsAsync(ConfigurationUnit unit);
// Find processors
IVector<IConfigurationUnitProcessorDetails> FindUnitProcessors(FindUnitProcessorsOptions findOptions);
IAsyncOperation<IVector<IConfigurationUnitProcessorDetails>> FindUnitProcessorsAsync(FindUnitProcessorsOptions findOptions);
// Get all units
GetAllConfigurationUnitsResult GetAllUnits(ConfigurationUnit unit);
IAsyncOperation<GetAllConfigurationUnitsResult> GetAllUnitsAsync(ConfigurationUnit unit);
}
Constructor
ConfigurationProcessor()
Creates a configuration processor with the specified factory.
factory
IConfigurationSetProcessorFactory
required
The processor factory implementation (e.g., PowerShell DSC)
using Microsoft.Management.Configuration;
// Create PowerShell DSC factory
var factory = await ConfigurationStaticFunctions
.CreateConfigurationSetProcessorFactoryAsync("pwsh");
var processor = new ConfigurationProcessor(factory);
// Configure diagnostics
processor.MinimumLevel = DiagnosticLevel.Informational;
processor.Caller = "MyApp";
processor.GenerateTelemetryEvents = true;
Opening Configuration Sets
OpenConfigurationSetAsync()
Loads a configuration set from a stream.
Input stream containing YAML configuration
Returns
IAsyncOperation<OpenConfigurationSetResult>
Result containing the loaded configuration set or error details
using Windows.Storage;
// Open configuration file
var file = await StorageFile.GetFileFromPathAsync(
@"C:\Configs\setup.yml"
);
using (var stream = await file.OpenReadAsync())
{
var openResult = await processor.OpenConfigurationSetAsync(stream);
if (openResult.ResultCode == 0)
{
var configSet = openResult.Set;
Console.WriteLine($"Loaded: {configSet.Name}");
Console.WriteLine($"Units: {configSet.Units.Count}");
Console.WriteLine($"Schema: {configSet.SchemaVersion}");
// List units
foreach (var unit in configSet.Units)
{
Console.WriteLine($" - {unit.Type} ({unit.Identifier})");
}
}
else
{
Console.WriteLine($"Failed to open configuration:");
Console.WriteLine($" HRESULT: 0x{openResult.ResultCode:X8}");
Console.WriteLine($" Field: {openResult.Field}");
Console.WriteLine($" Value: {openResult.Value}");
Console.WriteLine($" Location: Line {openResult.Line}, Column {openResult.Column}");
}
}
Applying Configurations
ApplySetAsync()
Applies a configuration set to the system.
The configuration set to apply
flags
ApplyConfigurationSetFlags
required
Flags controlling application behavior
Returns
IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData>
Async operation with progress updates
ApplyConfigurationSetFlags values:
None - Default behavior
DoNotOverwriteMatchingOriginSet - Create new instance instead of updating existing
PerformConsistencyCheckOnly - Only validate, don’t apply
var configSet = openResult.Set;
// Apply configuration with progress tracking
var operation = processor.ApplySetAsync(
configSet,
ApplyConfigurationSetFlags.None
);
operation.Progress = (op, data) =>
{
switch (data.Change)
{
case ConfigurationSetChangeEventType.SetStateChanged:
Console.WriteLine($"Set State: {data.SetState}");
break;
case ConfigurationSetChangeEventType.UnitStateChanged:
Console.WriteLine($"Unit: {data.Unit.Type}");
Console.WriteLine($" State: {data.UnitState}");
if (data.UnitState == ConfigurationUnitState.Completed)
{
var result = data.ResultInformation;
if (result.ResultCode == 0)
{
Console.WriteLine($" ✓ Success");
}
else
{
Console.WriteLine($" ✗ Failed: {result.Description}");
Console.WriteLine($" HRESULT: 0x{result.ResultCode:X8}");
Console.WriteLine($" Details: {result.Details}");
}
}
break;
}
};
var applyResult = await operation;
Console.WriteLine($"\nApply Result: 0x{applyResult.ResultCode:X8}");
Console.WriteLine($"Unit Results: {applyResult.UnitResults.Count}");
foreach (var unitResult in applyResult.UnitResults)
{
Console.WriteLine($" {unitResult.Unit.Type}: {unitResult.State}");
if (unitResult.State == ConfigurationUnitState.Completed)
{
Console.WriteLine($" Previously in desired state: {unitResult.PreviouslyInDesiredState}");
Console.WriteLine($" Reboot required: {unitResult.RebootRequired}");
}
}
Testing Configurations
TestSetAsync()
Tests if the system state matches the configuration set.
The configuration set to test
Returns
IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult>
Async operation with progress for each unit tested
var configSet = openResult.Set;
var operation = processor.TestSetAsync(configSet);
operation.Progress = (op, unitResult) =>
{
Console.WriteLine($"Testing: {unitResult.Unit.Type}");
Console.WriteLine($" Result: {unitResult.TestResult}");
if (unitResult.ResultInformation.ResultCode != 0)
{
Console.WriteLine($" Error: {unitResult.ResultInformation.Description}");
}
};
var testResult = await operation;
Console.WriteLine($"\nOverall Test Result: {testResult.TestResult}");
Console.WriteLine($"\nUnit Results:");
foreach (var unitResult in testResult.UnitResults)
{
Console.WriteLine($" {unitResult.Unit.Type}:");
switch (unitResult.TestResult)
{
case ConfigurationTestResult.Positive:
Console.WriteLine($" ✓ System is in desired state");
break;
case ConfigurationTestResult.Negative:
Console.WriteLine($" ✗ System is NOT in desired state");
break;
case ConfigurationTestResult.Failed:
Console.WriteLine($" ✗ Test failed: {unitResult.ResultInformation.Description}");
break;
case ConfigurationTestResult.NotRun:
Console.WriteLine($" - Test not run");
break;
}
}
Getting Details
GetSetDetailsAsync()
Retrieves detailed information about all units in a configuration set.
detailFlags
ConfigurationUnitDetailFlags
required
Level of detail to retrieve
ConfigurationUnitDetailFlags values:
None - No details
Local - Only local data
Catalog - Query catalog (no downloads)
Download - Download modules (don’t load)
Load - Download and load modules
ReadOnly - Local | Catalog
var configSet = openResult.Set;
var operation = processor.GetSetDetailsAsync(
configSet,
ConfigurationUnitDetailFlags.Load
);
operation.Progress = (op, unitDetails) =>
{
Console.WriteLine($"Loading details for: {unitDetails.Unit.Type}");
};
var detailsResult = await operation;
foreach (var unitDetails in detailsResult.UnitResults)
{
var unit = unitDetails.Unit;
var details = unitDetails.Details;
if (details != null)
{
Console.WriteLine($"\nUnit: {unit.Type}");
Console.WriteLine($" Description: {details.UnitDescription}");
Console.WriteLine($" Module: {details.ModuleName}");
Console.WriteLine($" Version: {details.Version}");
Console.WriteLine($" Author: {details.Author}");
Console.WriteLine($" Publisher: {details.Publisher}");
Console.WriteLine($" Is Public: {details.IsPublic}");
Console.WriteLine($" Is Local: {details.IsLocal}");
if (details.UnitDocumentationUri != null)
{
Console.WriteLine($" Docs: {details.UnitDocumentationUri}");
}
// Settings details
Console.WriteLine($" Settings:");
foreach (var setting in details.Settings)
{
Console.WriteLine($" - {setting.Identifier}");
Console.WriteLine($" Description: {setting.Description}");
Console.WriteLine($" Type: {setting.Type}");
Console.WriteLine($" Required: {setting.IsRequired}");
Console.WriteLine($" IsKey: {setting.IsKey}");
}
}
else if (unitDetails.ResultInformation.ResultCode != 0)
{
Console.WriteLine($"\nFailed to get details for: {unit.Type}");
Console.WriteLine($" Error: {unitDetails.ResultInformation.Description}");
}
}
Checking for Conflicts
CheckForConflictsAsync()
Checks for conflicts between configuration sets.
configurationSets
IVectorView<ConfigurationSet>
required
Configuration sets to check
includeConfigurationHistory
Whether to check against previously applied configurations
var configSet = openResult.Set;
// Check against history
var configSets = new List<ConfigurationSet> { configSet };
var conflicts = await processor.CheckForConflictsAsync(
configSets.AsReadOnly(),
includeConfigurationHistory: true
);
if (conflicts.Count > 0)
{
Console.WriteLine($"Found {conflicts.Count} conflicts:");
foreach (var conflict in conflicts)
{
Console.WriteLine($"\nConflict Type: {conflict.Conflict}");
Console.WriteLine($" First Set: {conflict.FirstSet.Name}");
Console.WriteLine($" Second Set: {conflict.SecondSet.Name}");
switch (conflict.Conflict)
{
case ConfigurationConflictType.MatchingOrigin:
Console.WriteLine($" Both sets have same origin: {conflict.FirstSet.Origin}");
break;
case ConfigurationConflictType.IdenticalSetApplied:
Console.WriteLine($" Identical set already applied");
break;
case ConfigurationConflictType.SettingsConflict:
Console.WriteLine($" First Unit: {conflict.FirstUnit.Type}");
Console.WriteLine($" Second Unit: {conflict.SecondUnit.Type}");
Console.WriteLine($" Conflicting settings:");
foreach (var setting in conflict.Settings)
{
Console.WriteLine($" {setting.Name}");
Console.WriteLine($" First: {setting.FirstValue}");
Console.WriteLine($" Second: {setting.SecondValue}");
}
break;
}
}
}
else
{
Console.WriteLine("No conflicts detected");
}
Configuration History
GetConfigurationHistoryAsync()
Retrieves previously applied configuration sets.
var history = await processor.GetConfigurationHistoryAsync();
Console.WriteLine($"Configuration History ({history.Count} sets):\n");
foreach (var configSet in history)
{
Console.WriteLine($"Name: {configSet.Name}");
Console.WriteLine($" Origin: {configSet.Origin}");
Console.WriteLine($" State: {configSet.State}");
Console.WriteLine($" Instance ID: {configSet.InstanceIdentifier}");
Console.WriteLine($" First Apply: {configSet.FirstApply}");
if (configSet.ApplyBegun != default)
{
Console.WriteLine($" Last Apply Begun: {configSet.ApplyBegun}");
}
if (configSet.ApplyEnded != default)
{
Console.WriteLine($" Last Apply Ended: {configSet.ApplyEnded}");
var duration = configSet.ApplyEnded - configSet.ApplyBegun;
Console.WriteLine($" Duration: {duration.TotalSeconds:F2}s");
}
Console.WriteLine($" Units: {configSet.Units.Count}");
Console.WriteLine();
}
Diagnostics
Diagnostics Event
Receive diagnostic information from the configuration system.
processor.MinimumLevel = DiagnosticLevel.Verbose;
processor.Diagnostics += (sender, diagnostics) =>
{
var level = diagnostics.Level switch
{
DiagnosticLevel.Verbose => "[VERBOSE]",
DiagnosticLevel.Informational => "[INFO]",
DiagnosticLevel.Warning => "[WARN]",
DiagnosticLevel.Error => "[ERROR]",
DiagnosticLevel.Critical => "[CRITICAL]",
_ => "[UNKNOWN]"
};
Console.WriteLine($"{level} {diagnostics.Message}");
};