From 02f5defa773893c4feacaa41588107035e51de41 Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 14:09:15 +0530 Subject: [PATCH 1/6] Add support for Pwsh execution --- .../ScriptExecutor/PowershellExecutorTests.cs | 14 +++++++++----- .../ScriptExecutor/PowershellExecutor.cs | 14 +++++++++++++- website/docs/guides/0221-usage-extensions.md | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs index a91405cb53..10a8d6e158 100644 --- a/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs +++ b/src/VirtualClient/VirtualClient.Actions.UnitTests/ScriptExecutor/PowershellExecutorTests.cs @@ -132,21 +132,25 @@ public void SetupTest(PlatformID platform = PlatformID.Win32NT) { nameof(PowershellExecutor.CommandLine), "parameter1 parameter2" }, { nameof(PowershellExecutor.ScriptPath), "genericScript.ps1" }, { nameof(PowershellExecutor.LogPaths), "*.log;*.txt;*.json" }, - { nameof(PowershellExecutor.ToolName), "GenericTool" } + { nameof(PowershellExecutor.ToolName), "GenericTool" }, + { nameof(PowershellExecutor.UsePwsh), false } }; this.fixture.ProcessManager.OnCreateProcess = (command, arguments, directory) => this.fixture.Process; } [Test] - [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", true)] - [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", false)] + [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", true, false, "powershell")] + [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", false, false, "powershell")] + [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", true, true, "pwsh")] + [TestCase(PlatformID.Win32NT, @"\win-x64", @"genericScript.ps1", false, true, "pwsh")] [Platform(Exclude = "Unix,Linux,MacOsX")] - public async Task PowershellExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command, bool runElevated) + public async Task PowershellExecutorExecutesTheCorrectWorkloadCommands(PlatformID platform, string platformSpecificPath, string command, bool runElevated, bool usePwsh, string executorType) { this.SetupTest(platform); this.fixture.Parameters[nameof(PowershellExecutor.RunElevated)] = runElevated; this.fixture.Parameters[nameof(PowershellExecutor.ScriptPath)] = command; + this.fixture.Parameters[nameof(PowershellExecutor.UsePwsh)] = usePwsh; string fullCommand = $"{this.mockPackage.Path}{platformSpecificPath}\\{command} parameter1 parameter2"; @@ -159,7 +163,7 @@ await executor.InitializeAsync(EventContext.None, CancellationToken.None) string workingDirectory = executor.ExecutableDirectory; - string expectedCommand = $"powershell -ExecutionPolicy Bypass -NoProfile -NonInteractive -WindowStyle Hidden -Command \"cd '{workingDirectory}';{fullCommand}\""; + string expectedCommand = $"{executorType} -ExecutionPolicy Bypass -NoProfile -NonInteractive -WindowStyle Hidden -Command \"cd '{workingDirectory}';{fullCommand}\""; this.fixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDirectory) => { if(expectedCommand == $"{exe} {arguments}") diff --git a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs index bada79d781..464f2fed19 100644 --- a/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs +++ b/src/VirtualClient/VirtualClient.Actions/ScriptExecutor/PowershellExecutor.cs @@ -9,6 +9,7 @@ namespace VirtualClient.Actions using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using VirtualClient.Common; + using VirtualClient.Common.Extensions; using VirtualClient.Common.Telemetry; /// @@ -26,6 +27,17 @@ public PowershellExecutor(IServiceCollection dependencies, IDictionary + /// The parameter specifies whether to use pwsh, by default it is false + /// + public bool UsePwsh + { + get + { + return this.Parameters.GetValue(nameof(this.UsePwsh), false); + } + } + /// /// Executes the PowerShell script. /// @@ -33,7 +45,7 @@ protected override async Task ExecuteAsync(EventContext telemetryContext, Cancel { using (BackgroundOperations profiling = BackgroundOperations.BeginProfiling(this, cancellationToken)) { - string command = "powershell"; + string command = this.UsePwsh ? "pwsh" : "powershell"; string commandArguments = SensitiveData.ObscureSecrets( $"-ExecutionPolicy Bypass -NoProfile -NonInteractive -WindowStyle Hidden -Command \"cd '{this.ExecutableDirectory}';{this.ExecutablePath} {this.CommandLine}\""); diff --git a/website/docs/guides/0221-usage-extensions.md b/website/docs/guides/0221-usage-extensions.md index 48986731f2..454bcc3d89 100644 --- a/website/docs/guides/0221-usage-extensions.md +++ b/website/docs/guides/0221-usage-extensions.md @@ -568,6 +568,7 @@ This component can be used to execute generic scripts using facilities common to | PackageName | Name of the workload package built for running the script. If the workload package is being downloaded from blob package store, this needs to match with the package name defined in DependencyPackageInstallation. | String | | FailFast | Flag indicates that the application should exit immediately on first/any errors regardless of their severity. | Boolean | | UsePython3 | (Only valid for PythonExecutor) A true value indicates use of "python3" as environment variable to execute python, a false value will use "python" as the environment variable. | Boolean (Default is true) | + | UsePwsh | (Only valid for PowershellExecutor) A true value indicates use of "pwsh", a false value will use "powershell" as the command executor. | Boolean (Default is false) | ``` json Example: From ca03a58e5f994caaae88d13dc8fe88457d7be19d Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 16:27:57 +0530 Subject: [PATCH 2/6] fix test cases --- .../VirtualClientComponentExtensionsTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs index b96d7d2d0a..911cb45aa9 100644 --- a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs +++ b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs @@ -252,7 +252,7 @@ public void CombineExtensionProducesTheExpectedPathOnUnixSystems() } [Test] - public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnUnixSystems_1() + public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnUnixSystems_1() { this.fixture.Setup(PlatformID.Unix); @@ -297,7 +297,7 @@ public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescript } [Test] - public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnUnixSystems_2() + public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnUnixSystems_2() { this.fixture.Setup(PlatformID.Unix); @@ -351,7 +351,7 @@ public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescript } [Test] - public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() + public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() { string directory = "C:\\Users\\User\\Logs"; string[] expectedFiles = new string[] @@ -394,7 +394,7 @@ public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescript } [Test] - public void CreateCreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_2() + public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_2() { string directory = "C:\\Users\\User\\Logs"; string[] expectedFiles = new string[] From 1a87b84e0e4ff940c254668bb424627eeae473e8 Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 17:08:35 +0530 Subject: [PATCH 3/6] fix test case --- .../VirtualClientComponentExtensionsTests.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs index 911cb45aa9..24f10f79c4 100644 --- a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs +++ b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs @@ -3,19 +3,20 @@ namespace VirtualClient.Contracts { + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.DependencyInjection.Extensions; + using Moq; + using NUnit.Framework; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; + using System.Runtime.Versioning; using System.Text; using System.Threading; using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.DependencyInjection.Extensions; - using Moq; - using NUnit.Framework; using VirtualClient.Common.Contracts; using VirtualClient.Common.Extensions; using VirtualClient.Common.Telemetry; @@ -351,6 +352,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnU } [Test] + [SupportedOSPlatform("windows")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() { string directory = "C:\\Users\\User\\Logs"; @@ -406,7 +408,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnW this.fixture.FileSystem .Setup(fs => fs.Path.GetDirectoryName(It.IsAny())) - .Returns(file => file.Replace(Path.GetFileName(file), string.Empty)); + .Returns(file => Path.GetDirectoryName(file)); this.fixture.FileSystem .Setup(fs => fs.Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories)) From a6da53329ff9d30160134e59b557a3dba9c5a373 Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 17:09:31 +0530 Subject: [PATCH 4/6] fix --- .../VirtualClientComponentExtensionsTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs index 24f10f79c4..fe0254914b 100644 --- a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs +++ b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs @@ -352,7 +352,6 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnU } [Test] - [SupportedOSPlatform("windows")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() { string directory = "C:\\Users\\User\\Logs"; From 65db5e0aa368251503d932d3d4c67b39daedb2ea Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 17:25:35 +0530 Subject: [PATCH 5/6] Fix --- .../VirtualClientComponentExtensionsTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs index fe0254914b..aa13ad98b3 100644 --- a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs +++ b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs @@ -352,6 +352,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnU } [Test] + [SupportedOSPlatform("windows")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() { string directory = "C:\\Users\\User\\Logs"; @@ -395,6 +396,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnW } [Test] + [SupportedOSPlatform("windows")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_2() { string directory = "C:\\Users\\User\\Logs"; From 3a22493e38c97a05a042ee5dfd7c5b37f3e644a7 Mon Sep 17 00:00:00 2001 From: Muskan Khedia Date: Tue, 1 Jul 2025 22:40:14 +0530 Subject: [PATCH 6/6] another try --- .../VirtualClientComponentExtensionsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs index aa13ad98b3..e64dc2db00 100644 --- a/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs +++ b/src/VirtualClient/VirtualClient.Contracts.UnitTests/VirtualClientComponentExtensionsTests.cs @@ -352,7 +352,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnU } [Test] - [SupportedOSPlatform("windows")] + [Platform(Include = "Win")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_1() { string directory = "C:\\Users\\User\\Logs"; @@ -396,7 +396,7 @@ public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnW } [Test] - [SupportedOSPlatform("windows")] + [Platform(Include = "Win")] public void CreateFileUploadDescriptorsExtensionCreatesTheExpectedDescriptorsOnWindowsSystems_2() { string directory = "C:\\Users\\User\\Logs";