diff --git a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h
index 43b2e7c095..b161598c9c 100644
--- a/src/AppInstallerSharedLib/Public/AppInstallerErrors.h
+++ b/src/AppInstallerSharedLib/Public/AppInstallerErrors.h
@@ -172,7 +172,7 @@
#define WINGET_CONFIG_ERROR_UNIT_INVOKE_GET ((HRESULT)0x8A15C104)
#define WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST ((HRESULT)0x8A15C105)
#define WINGET_CONFIG_ERROR_UNIT_INVOKE_SET ((HRESULT)0x8A15C106)
-
+#define WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT ((HRESULT)0x8A15C107)
namespace AppInstaller
{
diff --git a/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs b/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs
index a273fb95eb..3632686efd 100644
--- a/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs
+++ b/src/Microsoft.Management.Configuration.Processor/DscModules/DscModuleV2.cs
@@ -11,10 +11,8 @@ namespace Microsoft.Management.Configuration.Processor.DscModule
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
- using System.Management.Automation.Runspaces;
using Microsoft.Management.Configuration.Processor.DscResourcesInfo;
using Microsoft.Management.Configuration.Processor.Exceptions;
- using Microsoft.Management.Configuration.Processor.Extensions;
using Microsoft.Management.Configuration.Processor.Helpers;
using Microsoft.PowerShell.Commands;
using Windows.Foundation.Collections;
@@ -54,51 +52,26 @@ public DscModuleV2()
public string InvokeDscResourceCmd { get; } = Commands.InvokeDscResource;
///
- public IReadOnlyList GetAllDscResources(Runspace runspace)
+ public IReadOnlyList GetAllDscResources(PowerShell pwsh)
{
- var result = new List();
-
- using PowerShell pwsh = PowerShell.Create(runspace);
- var resources = pwsh.AddCommand(this.GetDscResourceCmd)
- .InvokeAndStopOnError();
-
- return this.ConvertToDscResourceInfoInternal(resources);
+ return this.GetDscResources(pwsh, null, null);
}
///
public IReadOnlyList GetDscResourcesInModule(
- Runspace runspace,
+ PowerShell pwsh,
ModuleSpecification moduleSpecification)
{
- var result = new List();
-
- using PowerShell pwsh = PowerShell.Create(runspace);
-
- var resources = pwsh.AddCommand(this.GetDscResourceCmd)
- .AddParameter(Parameters.Module, moduleSpecification)
- .InvokeAndStopOnError();
-
- return this.ConvertToDscResourceInfoInternal(resources);
+ return this.GetDscResources(pwsh, null, moduleSpecification);
}
///
public DscResourceInfoInternal? GetDscResource(
- Runspace runspace,
+ PowerShell pwsh,
string name,
ModuleSpecification? moduleSpecification)
{
- using PowerShell pwsh = PowerShell.Create(runspace);
- pwsh.AddCommand(this.GetDscResourceCmd)
- .AddParameter(Parameters.Name, name);
-
- if (moduleSpecification is not null)
- {
- pwsh.AddParameter(Parameters.Module, moduleSpecification);
- }
-
- var resources = pwsh.InvokeAndStopOnError();
-
- var dscResourceInfos = this.ConvertToDscResourceInfoInternal(resources);
+ var dscResourceInfos = this.GetDscResources(pwsh, name, moduleSpecification);
if (dscResourceInfos.Count == 0)
{
@@ -114,17 +87,15 @@ public IReadOnlyList GetDscResourcesInModule(
///
public ValueSet InvokeGetResource(
- Runspace runspace,
+ PowerShell pwsh,
ValueSet settings,
string name,
ModuleSpecification? moduleSpecification)
{
- using PowerShell pwsh = PowerShell.Create(runspace);
-
var getResult = pwsh.AddCommand(this.InvokeDscResourceCmd)
.AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))
.AddParameter(Parameters.Method, DscMethods.Get)
- .InvokeAndStopOnError()
+ .Invoke()
.FirstOrDefault();
if (getResult is null)
@@ -151,19 +122,17 @@ public ValueSet InvokeGetResource(
///
public bool InvokeTestResource(
- Runspace runspace,
+ PowerShell pwsh,
ValueSet settings,
string name,
ModuleSpecification? moduleSpecification)
{
- using PowerShell pwsh = PowerShell.Create(runspace);
-
// Returned type is InvokeDscResourceTestResult which is a PowerShell classed defined
// in PSDesiredStateConfiguration.psm1.
dynamic? testResult = pwsh.AddCommand(this.InvokeDscResourceCmd)
.AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))
.AddParameter(Parameters.Method, DscMethods.Test)
- .InvokeAndStopOnError()
+ .Invoke()
.FirstOrDefault();
if (testResult is null ||
@@ -177,19 +146,17 @@ public bool InvokeTestResource(
///
public bool InvokeSetResource(
- Runspace runspace,
+ PowerShell pwsh,
ValueSet settings,
string name,
ModuleSpecification? moduleSpecification)
{
- using PowerShell pwsh = PowerShell.Create(runspace);
-
// Returned type is InvokeDscResourceSetResult which is a PowerShell classed defined
// in PSDesiredStateConfiguration.psm1.
dynamic? setResult = pwsh.AddCommand(this.InvokeDscResourceCmd)
.AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))
.AddParameter(Parameters.Method, DscMethods.Set)
- .InvokeAndStopOnError()
+ .Invoke()
.FirstOrDefault();
if (setResult is null ||
@@ -226,6 +193,40 @@ private static Dictionary PrepareInvokeParameters(
return parameters;
}
+ private IReadOnlyList GetDscResources(
+ PowerShell pwsh,
+ string? name,
+ ModuleSpecification? moduleSpecification)
+ {
+ pwsh.AddCommand(this.GetDscResourceCmd);
+
+ if (name is not null)
+ {
+ pwsh.AddParameter(Parameters.Name, name);
+ }
+
+ if (moduleSpecification is not null)
+ {
+ pwsh.AddParameter(Parameters.Module, moduleSpecification);
+ }
+
+ try
+ {
+ var resources = pwsh.Invoke();
+ return this.ConvertToDscResourceInfoInternal(resources);
+ }
+ catch (RuntimeException e)
+ {
+ // Detect easily this.
+ if (e.ErrorRecord.FullyQualifiedErrorId == "ExceptionWhenSetting,GetResourceFromKeyword")
+ {
+ throw new GetDscResourceModuleConflict(name, moduleSpecification, e);
+ }
+
+ throw;
+ }
+ }
+
private List ConvertToDscResourceInfoInternal(Collection psObjects)
{
var result = new List();
diff --git a/src/Microsoft.Management.Configuration.Processor/DscModules/IDscModule.cs b/src/Microsoft.Management.Configuration.Processor/DscModules/IDscModule.cs
index 2afc0a79cc..bd1fb6a428 100644
--- a/src/Microsoft.Management.Configuration.Processor/DscModules/IDscModule.cs
+++ b/src/Microsoft.Management.Configuration.Processor/DscModules/IDscModule.cs
@@ -7,7 +7,7 @@
namespace Microsoft.Management.Configuration.Processor.DscModule
{
using System.Collections.Generic;
- using System.Management.Automation.Runspaces;
+ using System.Management.Automation;
using Microsoft.Management.Configuration.Processor.DscResourcesInfo;
using Microsoft.PowerShell.Commands;
using Windows.Foundation.Collections;
@@ -35,55 +35,55 @@ internal interface IDscModule
///
/// Gets all DSC resource.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// A list with the DSC resource.
- IReadOnlyList GetAllDscResources(Runspace runspace);
+ IReadOnlyList GetAllDscResources(PowerShell pwsh);
///
/// Gets all resources in a module.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// Module specification.
/// List of resources of that module and version.
- IReadOnlyList GetDscResourcesInModule(Runspace runspace, ModuleSpecification moduleSpecification);
+ IReadOnlyList GetDscResourcesInModule(PowerShell pwsh, ModuleSpecification moduleSpecification);
///
/// Gets a DSC Resource.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// Name.
/// Module specification.
/// DSC Resource from that module and version.
- DscResourceInfoInternal? GetDscResource(Runspace runspace, string name, ModuleSpecification? moduleSpecification);
+ DscResourceInfoInternal? GetDscResource(PowerShell pwsh, string name, ModuleSpecification? moduleSpecification);
///
/// Calls Invoke-DscResource -Method Get from this module.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// Settings.
/// Name.
/// Module specification.
/// Properties of resource.
- ValueSet InvokeGetResource(Runspace runspace, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
+ ValueSet InvokeGetResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
///
/// Calls Invoke-DscResource -Method Test from this module.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// Settings.
/// Name.
/// Module specification.
/// Is in desired state.
- bool InvokeTestResource(Runspace runspace, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
+ bool InvokeTestResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
///
/// Calls Invoke-DscResource -Method Set from this module.
///
- /// PowerShell Runspace.
+ /// PowerShell.
/// Settings.
/// Name.
/// Module specification.
/// If a reboot is required.
- bool InvokeSetResource(Runspace runspace, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
+ bool InvokeSetResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);
}
}
diff --git a/src/Microsoft.Management.Configuration.Processor/Exceptions/ErrorCodes.cs b/src/Microsoft.Management.Configuration.Processor/Exceptions/ErrorCodes.cs
index 14a11bd4eb..5a8505ba9e 100644
--- a/src/Microsoft.Management.Configuration.Processor/Exceptions/ErrorCodes.cs
+++ b/src/Microsoft.Management.Configuration.Processor/Exceptions/ErrorCodes.cs
@@ -40,5 +40,10 @@ internal static class ErrorCodes
/// Internal error calling Invoke-DscResource Set.
///
internal const int WinGetConfigUnitInvokeSet = unchecked((int)0x8A15C106);
+
+ ///
+ /// Internal error calling Get-DscResource. More than one module found with the same version.
+ ///
+ internal const int WinGetConfigUnitModuleConflict = unchecked((int)0x8A15C107);
}
}
diff --git a/src/Microsoft.Management.Configuration.Processor/Exceptions/GetDscResourceModuleConflict.cs b/src/Microsoft.Management.Configuration.Processor/Exceptions/GetDscResourceModuleConflict.cs
new file mode 100644
index 0000000000..dee4ba9a52
--- /dev/null
+++ b/src/Microsoft.Management.Configuration.Processor/Exceptions/GetDscResourceModuleConflict.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
+//
+// -----------------------------------------------------------------------------
+
+namespace Microsoft.Management.Configuration.Processor.Exceptions
+{
+ using System;
+ using System.Management.Automation;
+ using Microsoft.PowerShell.Commands;
+
+ ///
+ /// A call to Get-DscResource failed because at least two modules with the same version where found in the module path.
+ /// If you are getting this verify the module path.
+ ///
+ internal class GetDscResourceModuleConflict : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Resource name.
+ /// Optional module.
+ /// The original runtime exception thrown.
+ public GetDscResourceModuleConflict(string? resourceName, ModuleSpecification? module, RuntimeException inner)
+ : base($"Multiple modules with same version in module path: {resourceName?.ToString() ?? ""} [{module?.ToString() ?? ""}]", inner)
+ {
+ this.HResult = ErrorCodes.WinGetConfigUnitModuleConflict;
+ this.ResourceName = resourceName;
+ this.Module = module;
+ }
+
+ ///
+ /// Gets the resource name.
+ ///
+ public string? ResourceName { get; }
+
+ ///
+ /// Gets the module, if any.
+ ///
+ public ModuleSpecification? Module { get; }
+ }
+}
diff --git a/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/HostedEnvironment.cs b/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/HostedEnvironment.cs
index e9a9593cc5..15b53891ed 100644
--- a/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/HostedEnvironment.cs
+++ b/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/HostedEnvironment.cs
@@ -15,8 +15,6 @@ namespace Microsoft.Management.Configuration.Processor.Runspaces
using Microsoft.Management.Configuration.Processor.Constants;
using Microsoft.Management.Configuration.Processor.DscModule;
using Microsoft.Management.Configuration.Processor.DscResourcesInfo;
- using Microsoft.Management.Configuration.Processor.Exceptions;
- using Microsoft.Management.Configuration.Processor.Extensions;
using Microsoft.Management.Configuration.Processor.Helpers;
using Microsoft.Management.Configuration.Processor.ProcessorEnvironments;
using Microsoft.PowerShell.Commands;
@@ -51,7 +49,12 @@ public HostedEnvironment(Runspace runspace, ConfigurationProcessorType type, IDs
///
/// Gets the DscModule.
///
- protected IDscModule DscModule { get; }
+ internal IDscModule DscModule { get; }
+
+ ///
+ /// Gets or initializes the set processor factory.
+ ///
+ internal ConfigurationSetProcessorFactory? SetProcessorFactory { get; init; }
///
public void ValidateRunspace()
@@ -84,28 +87,58 @@ public void ValidateRunspace()
}
///
- public IReadOnlyList GetAllDscResources() =>
- this.DscModule.GetAllDscResources(this.Runspace);
+ public IReadOnlyList GetAllDscResources()
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var results = this.DscModule.GetAllDscResources(pwsh);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return results;
+ }
///
- public IReadOnlyList GetDscResourcesInModule(ModuleSpecification moduleSpecification) =>
- this.DscModule.GetDscResourcesInModule(this.Runspace, moduleSpecification);
+ public IReadOnlyList GetDscResourcesInModule(ModuleSpecification moduleSpecification)
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var results = this.DscModule.GetDscResourcesInModule(pwsh, moduleSpecification);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return results;
+ }
///
- public DscResourceInfoInternal? GetDscResource(ConfigurationUnitInternal unitInternal) =>
- this.DscModule.GetDscResource(this.Runspace, unitInternal.Unit.UnitName, unitInternal.Module);
+ public DscResourceInfoInternal? GetDscResource(ConfigurationUnitInternal unitInternal)
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var result = this.DscModule.GetDscResource(pwsh, unitInternal.Unit.UnitName, unitInternal.Module);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return result;
+ }
///
- public ValueSet InvokeGetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification) =>
- this.DscModule.InvokeGetResource(this.Runspace, settings, name, moduleSpecification);
+ public ValueSet InvokeGetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var result = this.DscModule.InvokeGetResource(pwsh, settings, name, moduleSpecification);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return result;
+ }
///
- public bool InvokeTestResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification) =>
- this.DscModule.InvokeTestResource(this.Runspace, settings, name, moduleSpecification);
+ public bool InvokeTestResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var result = this.DscModule.InvokeTestResource(pwsh, settings, name, moduleSpecification);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return result;
+ }
///
- public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification) =>
- this.DscModule.InvokeSetResource(this.Runspace, settings, name, moduleSpecification);
+ public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)
+ {
+ using PowerShell pwsh = PowerShell.Create(this.Runspace);
+ var result = this.DscModule.InvokeSetResource(pwsh, settings, name, moduleSpecification);
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
+ return result;
+ }
///
public PSModuleInfo? GetImportedModule(ModuleSpecification moduleSpecification)
@@ -117,6 +150,7 @@ public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecificatio
.Invoke()
.FirstOrDefault();
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return moduleInfo;
}
@@ -131,6 +165,7 @@ public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecificatio
.Invoke()
.FirstOrDefault();
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return moduleInfo;
}
@@ -145,6 +180,7 @@ public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecificatio
.Invoke()
.FirstOrDefault();
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return moduleInfo;
}
@@ -156,6 +192,8 @@ public void ImportModule(ModuleSpecification moduleSpecification)
_ = pwsh.AddCommand(Commands.ImportModule)
.AddParameter(Parameters.FullyQualifiedName, moduleSpecification)
.Invoke();
+
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
}
///
@@ -188,6 +226,7 @@ public void ImportModule(ModuleSpecification moduleSpecification)
.Invoke()
.FirstOrDefault();
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return result;
}
@@ -236,6 +275,7 @@ public void ImportModule(ModuleSpecification moduleSpecification)
.Invoke()
.FirstOrDefault();
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return result;
}
@@ -247,7 +287,9 @@ public void SaveModule(PSObject inputObject, string location)
_ = pwsh.AddCommand(Commands.SaveModule)
.AddParameter(Parameters.Path, location)
.AddParameter(Parameters.InputObject, inputObject)
- .InvokeAndStopOnError();
+ .Invoke();
+
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
}
///
@@ -265,7 +307,9 @@ public void InstallModule(PSObject inputObject)
_ = pwsh.AddCommand(Commands.InstallModule)
.AddParameter(Parameters.InputObject, inputObject)
.AddParameter(Parameters.Force)
- .InvokeAndStopOnError();
+ .Invoke();
+
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
}
///
@@ -298,7 +342,9 @@ public void InstallModule(ModuleSpecification moduleSpecification)
_ = pwsh.AddCommand(Commands.InstallModule)
.AddParameters(parameters)
.AddParameter(Parameters.Force)
- .InvokeAndStopOnError();
+ .Invoke();
+
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
}
}
@@ -310,7 +356,7 @@ public List GetCertsOfValidSignedFiles(string[] paths)
var signatures = pwsh.AddCommand(Commands.GetChildItem)
.AddParameter(Parameters.Path, paths)
.AddCommand(Commands.GetAuthenticodeSignature)
- .InvokeAndStopOnError();
+ .Invoke();
var thumbprint = new HashSet();
var certificates = new List();
@@ -326,6 +372,7 @@ public List GetCertsOfValidSignedFiles(string[] paths)
}
}
+ this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);
return certificates;
}
@@ -408,5 +455,10 @@ private bool ValidateModule(ModuleSpecification moduleSpecification)
return false;
}
+
+ private void OnDiagnostics(DiagnosticLevel level, PowerShell pwsh)
+ {
+ this.SetProcessorFactory?.OnDiagnostics(level, pwsh);
+ }
}
}
diff --git a/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/ProcessorEnvironmentFactory.cs b/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/ProcessorEnvironmentFactory.cs
index 703f356d8c..c55d20f415 100644
--- a/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/ProcessorEnvironmentFactory.cs
+++ b/src/Microsoft.Management.Configuration.Processor/ProcessorEnvironments/ProcessorEnvironmentFactory.cs
@@ -33,13 +33,9 @@ public ProcessorEnvironmentFactory(ConfigurationProcessorType type)
///
/// Create process environment.
///
+ /// Optional processor factory.
/// IProcessorEnvironment.
- public IProcessorEnvironment CreateEnvironment()
- {
- return this.CreateProcessorEnvironment();
- }
-
- private IProcessorEnvironment CreateProcessorEnvironment()
+ public IProcessorEnvironment CreateEnvironment(ConfigurationSetProcessorFactory? setProcessorFactory)
{
IDscModule dscModule = new DscModuleV2();
@@ -67,7 +63,10 @@ private IProcessorEnvironment CreateProcessorEnvironment()
var runspace = RunspaceFactory.CreateRunspace(initialSessionState);
runspace.Open();
- return new HostedEnvironment(runspace, this.type, dscModule);
+ return new HostedEnvironment(runspace, this.type, dscModule)
+ {
+ SetProcessorFactory = setProcessorFactory,
+ };
}
throw new ArgumentException(this.type.ToString());
diff --git a/src/Microsoft.Management.Configuration.Processor/Public/ConfigurationSetProcessorFactory.cs b/src/Microsoft.Management.Configuration.Processor/Public/ConfigurationSetProcessorFactory.cs
index 6d5cb14e84..bf904b60a4 100644
--- a/src/Microsoft.Management.Configuration.Processor/Public/ConfigurationSetProcessorFactory.cs
+++ b/src/Microsoft.Management.Configuration.Processor/Public/ConfigurationSetProcessorFactory.cs
@@ -7,6 +7,8 @@
namespace Microsoft.Management.Configuration.Processor
{
using System;
+ using System.Management.Automation;
+ using System.Text;
using Microsoft.Management.Configuration;
using Microsoft.Management.Configuration.Processor.ProcessorEnvironments;
using Microsoft.Management.Configuration.Processor.Set;
@@ -52,7 +54,7 @@ public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet set)
this.OnDiagnostics(DiagnosticLevel.Verbose, $"Creating set processor for `{set.Name}`...");
var envFactory = new ProcessorEnvironmentFactory(this.type);
- var processorEnvironment = envFactory.CreateEnvironment();
+ var processorEnvironment = envFactory.CreateEnvironment(this);
processorEnvironment.ValidateRunspace();
if (this.properties is not null)
@@ -85,11 +87,57 @@ internal void OnDiagnostics(DiagnosticLevel level, string message)
EventHandler? diagnostics = this.Diagnostics;
if (diagnostics != null && level >= this.MinimumLevel)
{
- DiagnosticInformation information = new DiagnosticInformation();
- information.Level = level;
- information.Message = message;
- diagnostics.Invoke(this, information);
+ this.InvokeDiagnostics(diagnostics, level, message);
}
}
+
+ ///
+ /// Sends diagnostic if appropriate for PowerShell streams.
+ ///
+ /// The level of this diagnostic message.
+ /// The PowerShell object.
+ internal void OnDiagnostics(DiagnosticLevel level, PowerShell pwsh)
+ {
+ EventHandler? diagnostics = this.Diagnostics;
+ if (diagnostics != null && level >= this.MinimumLevel && pwsh.HadErrors)
+ {
+ var builder = new StringBuilder();
+
+ // There are the last commands ran by that PowerShell obj, not all in our session.
+ builder.Append("PowerShellCommands: ");
+ foreach (var c in pwsh.Commands.Commands)
+ {
+ builder.Append($"['{c.CommandText}'");
+ if (c.Parameters.Count > 0)
+ {
+ builder.Append(" Parameters: ");
+ foreach (var p in c.Parameters)
+ {
+ builder.Append($"{p.Name} = '{p.Value}' ");
+ }
+ builder.Append("]");
+ }
+
+ builder.AppendLine();
+ }
+
+ foreach (var error in pwsh.Streams.Error)
+ {
+ builder.AppendLine($"[WriteError] {error}");
+ }
+
+ this.InvokeDiagnostics(diagnostics, level, builder.ToString());
+ }
+ }
+
+ private void InvokeDiagnostics(EventHandler diagnostics, DiagnosticLevel level, string message)
+ {
+ DiagnosticInformation information = new ()
+ {
+ Level = level,
+ Message = message,
+ };
+ diagnostics.Invoke(this, information);
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs
index b66d05df1c..65e5417f3a 100644
--- a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs
+++ b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs
@@ -57,7 +57,7 @@ public UnitTestFixture(IMessageSink messageSink)
/// PowerShellRunspace.
internal IProcessorEnvironment PrepareTestProcessorEnvironment(bool validate = false)
{
- var processorEnv = new ProcessorEnvironmentFactory(ConfigurationProcessorType.Hosted).CreateEnvironment();
+ var processorEnv = new ProcessorEnvironmentFactory(ConfigurationProcessorType.Hosted).CreateEnvironment(null);
processorEnv.PrependPSModulePath(this.TestModulesPath);
if (validate)
diff --git a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs
index 879df72f39..85d8c507d5 100644
--- a/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs
+++ b/src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs
@@ -25,7 +25,9 @@ internal class TestConfigurationProcessorFactory : IConfigurationSetProcessorFac
///
/// Diagnostics event; useful for logging and/or verbose output.
///
+#pragma warning disable CS0067 // The event is never used
public event EventHandler? Diagnostics;
+#pragma warning restore CS0067 // The event is never used
///
/// Gets or sets the minimum diagnostic level to send.
diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2SimpleFileResourceTests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2SimpleFileResourceTests.cs
index cb01e4e677..6bbf22d2a4 100644
--- a/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2SimpleFileResourceTests.cs
+++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2SimpleFileResourceTests.cs
@@ -7,6 +7,7 @@
namespace Microsoft.Management.Configuration.UnitTests.Tests
{
using System.IO;
+ using System.Management.Automation;
using Microsoft.Management.Configuration.Processor.DscModule;
using Microsoft.Management.Configuration.Processor.Helpers;
using Microsoft.Management.Configuration.UnitTests.Fixtures;
@@ -58,10 +59,12 @@ public void SimpleFileResource_FileAbsent(string ensureValue, bool expectedResul
};
var dscModule = new DscModuleV2();
+
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
Assert.Equal(
expectedResult,
dscModule.InvokeTestResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -86,8 +89,9 @@ public void SimpleFileResource_FilePresent()
};
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
Assert.True(dscModule.InvokeTestResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -112,8 +116,9 @@ public void SimpleFileResource_DifferentContent()
};
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
Assert.False(dscModule.InvokeTestResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -139,8 +144,9 @@ public void SimpleFileResource_SameContent()
};
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
Assert.True(dscModule.InvokeTestResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -181,8 +187,9 @@ public void SimpleFileResource_Set_Ensure(string ensureValue, bool preCondition,
File.Exists(tmpFile.FullFileName));
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
dscModule.InvokeSetResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -221,8 +228,9 @@ public void SimpleFileResource_Set_Content(string? preSetContent, string postSet
};
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
dscModule.InvokeSetResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -250,8 +258,9 @@ public void SimpleFileResource_Get()
};
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);
var properties = dscModule.InvokeGetResource(
- processorEnv.Runspace,
+ pwsh,
settings,
TestModule.SimpleFileResourceName,
PowerShellHelpers.CreateModuleSpecification(
diff --git a/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2Tests.cs b/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2Tests.cs
index 4ce2a57f5a..95e861a22a 100644
--- a/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2Tests.cs
+++ b/src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2Tests.cs
@@ -6,10 +6,10 @@
namespace Microsoft.Management.Configuration.UnitTests.Tests
{
- using System;
using System.IO;
using System.Management.Automation;
using Microsoft.Management.Configuration.Processor.DscModule;
+ using Microsoft.Management.Configuration.Processor.Exceptions;
using Microsoft.Management.Configuration.Processor.Helpers;
using Microsoft.Management.Configuration.UnitTests.Fixtures;
using Microsoft.Management.Configuration.UnitTests.Helpers;
@@ -48,7 +48,8 @@ public void GetAllDscResources_Test()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
- var resources = dscModule.GetAllDscResources(testEnvironment.Runspace);
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var resources = dscModule.GetAllDscResources(pwsh);
Assert.True(resources.Count > 0);
Assert.Contains(resources, r => r.Name == TestModule.SimpleFileResourceName);
@@ -67,8 +68,9 @@ public void GetDscResourcesInModule_Test(string module, int expectedResources)
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var resources = dscModule.GetDscResourcesInModule(
- testEnvironment.Runspace,
+ pwsh,
PowerShellHelpers.CreateModuleSpecification(module));
Assert.Equal(expectedResources, resources.Count);
}
@@ -102,27 +104,35 @@ public void GetDscResourcesInModule_VersionTest()
//// testEnvironment.Runspace,
//// PowerShellHelpers.CreateModuleSpecification(TestModule.SimpleTestResourceModuleName));
////Assert.Equal(8, allResources.Count);
-
- var ogResources = dscModule.GetDscResourcesInModule(
- testEnvironment.Runspace,
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var ogResources = dscModule.GetDscResourcesInModule(
+ pwsh,
PowerShellHelpers.CreateModuleSpecification(
TestModule.SimpleTestResourceModuleName,
version: TestModule.SimpleTestResourceVersion));
- Assert.Equal(4, ogResources.Count);
+ Assert.Equal(4, ogResources.Count);
+ }
- var newVersionResources = dscModule.GetDscResourcesInModule(
- testEnvironment.Runspace,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- version: newVersion));
- Assert.Equal(4, ogResources.Count);
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var newVersionResources = dscModule.GetDscResourcesInModule(
+ pwsh,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ version: newVersion));
+ Assert.Equal(4, newVersionResources.Count);
+ }
- var badVersionResources = dscModule.GetDscResourcesInModule(
- testEnvironment.Runspace,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- version: "1.2.3.4"));
- Assert.Equal(0, badVersionResources.Count);
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var badVersionResources = dscModule.GetDscResourcesInModule(
+ pwsh,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ version: "1.2.3.4"));
+ Assert.Equal(0, badVersionResources.Count);
+ }
}
///
@@ -134,8 +144,9 @@ public void GetDscResource_ResourceExists()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var resource = dscModule.GetDscResource(
- testEnvironment.Runspace,
+ pwsh,
TestModule.SimpleTestResourceName,
PowerShellHelpers.CreateModuleSpecification(TestModule.SimpleTestResourceModuleName));
@@ -151,12 +162,13 @@ public void GetDscResource_ResourceDoesntExist()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
- Assert.Throws(
- () => dscModule.GetDscResource(
- testEnvironment.Runspace,
- "FakeResourceName",
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName)));
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var resource = dscModule.GetDscResource(
+ pwsh,
+ "FakeResourceName",
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName));
+ Assert.Null(resource);
}
///
@@ -174,10 +186,10 @@ public void GetDscResource_Conflict()
testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);
var dscModule = new DscModuleV2();
-
- Assert.Throws(
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ Assert.Throws(
() => dscModule.GetDscResource(
- testEnvironment.Runspace,
+ pwsh,
TestModule.SimpleTestResourceName,
PowerShellHelpers.CreateModuleSpecification(
TestModule.SimpleTestResourceModuleName)));
@@ -208,24 +220,30 @@ public void GetDscResource_DiffVersions()
var dscModule = new DscModuleV2();
// specific version.
- var resource = dscModule.GetDscResource(
- testEnvironment.Runspace,
- TestModule.SimpleTestResourceName,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- TestModule.SimpleTestResourceVersion));
- Assert.NotNull(resource);
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var resource = dscModule.GetDscResource(
+ pwsh,
+ TestModule.SimpleTestResourceName,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ TestModule.SimpleTestResourceVersion));
+ Assert.NotNull(resource);
+ }
- var dsc = dscModule.GetDscResource(
- testEnvironment.Runspace,
- TestModule.SimpleTestResourceName,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- version: newVersion));
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ var dsc = dscModule.GetDscResource(
+ pwsh,
+ TestModule.SimpleTestResourceName,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ version: newVersion));
- Assert.NotNull(dsc);
- Assert.NotNull(dsc.Version);
- Assert.Equal(newVersion, dsc.Version.ToString());
+ Assert.NotNull(dsc);
+ Assert.NotNull(dsc.Version);
+ Assert.Equal(newVersion, dsc.Version.ToString());
+ }
}
///
@@ -237,9 +255,9 @@ public void InvokeGetResource_Test()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var getResult = dscModule.InvokeGetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -260,9 +278,10 @@ public void InvokeGetResource_ResourceThrows()
var dscModule = new DscModuleV2();
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(() =>
dscModule.InvokeGetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceThrowsName,
PowerShellHelpers.CreateModuleSpecification(
@@ -280,10 +299,10 @@ public void InvokeGetResource_ResourceError()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
Assert.Throws(() =>
dscModule.InvokeGetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceErrorName,
PowerShellHelpers.CreateModuleSpecification(
@@ -299,10 +318,10 @@ public void InvokeGetResource_ResourceDoesntExist()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(
() => dscModule.InvokeGetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
"FakeResourceName",
PowerShellHelpers.CreateModuleSpecification(
@@ -330,8 +349,9 @@ public void InvokeTestResource_Test(string value, bool expectedResult)
{ "secretCode", value },
};
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var testResult = dscModule.InvokeTestResource(
- testEnvironment.Runspace,
+ pwsh,
settings,
TestModule.SimpleTestResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -349,10 +369,10 @@ public void InvokeTestResource_Throws()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(() =>
dscModule.InvokeTestResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceThrowsName,
PowerShellHelpers.CreateModuleSpecification(
@@ -370,10 +390,10 @@ public void InvokeTestResource_ResourceError()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
Assert.Throws(() =>
dscModule.InvokeTestResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceErrorName,
PowerShellHelpers.CreateModuleSpecification(
@@ -389,10 +409,10 @@ public void InvokeTestResource_ResourceDoesntExist()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(() =>
_ = dscModule.InvokeTestResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
"FakeResourceName",
PowerShellHelpers.CreateModuleSpecification(
@@ -418,8 +438,9 @@ public void InvokeSetResource_Test()
{ "secretCode", "4815162342" },
};
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var testResult = dscModule.InvokeSetResource(
- testEnvironment.Runspace,
+ pwsh,
settings,
TestModule.SimpleTestResourceName,
PowerShellHelpers.CreateModuleSpecification(
@@ -438,10 +459,10 @@ public void InvokeSetResource_Throws()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(() =>
dscModule.InvokeSetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceThrowsName,
PowerShellHelpers.CreateModuleSpecification(
@@ -459,10 +480,10 @@ public void InvokeSetResource_ResourceError()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
Assert.Throws(() =>
dscModule.InvokeSetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
TestModule.SimpleTestResourceErrorName,
PowerShellHelpers.CreateModuleSpecification(
@@ -478,10 +499,10 @@ public void InvokeSetResource_ResourceDoesntExist()
var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();
var dscModule = new DscModuleV2();
-
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
var exception = Assert.Throws(() =>
dscModule.InvokeSetResource(
- testEnvironment.Runspace,
+ pwsh,
new ValueSet(),
"FakeResourceName",
PowerShellHelpers.CreateModuleSpecification(
@@ -513,22 +534,27 @@ public void InvokeResource_MultipleVersions()
testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);
var dscModule = new DscModuleV2();
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ dscModule.InvokeSetResource(
+ pwsh,
+ new ValueSet(),
+ TestModule.SimpleTestResourceName,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ TestModule.SimpleTestResourceVersion));
+ }
- dscModule.InvokeSetResource(
- testEnvironment.Runspace,
- new ValueSet(),
- TestModule.SimpleTestResourceName,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- TestModule.SimpleTestResourceVersion));
-
- dscModule.InvokeSetResource(
- testEnvironment.Runspace,
- new ValueSet(),
- TestModule.SimpleTestResourceName,
- PowerShellHelpers.CreateModuleSpecification(
- TestModule.SimpleTestResourceModuleName,
- version: newVersion));
+ {
+ using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);
+ dscModule.InvokeSetResource(
+ pwsh,
+ new ValueSet(),
+ TestModule.SimpleTestResourceName,
+ PowerShellHelpers.CreateModuleSpecification(
+ TestModule.SimpleTestResourceModuleName,
+ version: newVersion));
+ }
}
}
}