Skip to content

Execute a PowerShell Script in C#: .NET 10 and sample fixes - #2264

Merged
vladimir-pecanac-main merged 3 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/91684-csharp-run-powershell-script
Oct 5, 2026
Merged

vladimir-pecanac-main merged 3 commits into
CodeMazeBlog:mainfrom
vladimir-pecanac-main:seo/91684-csharp-run-powershell-script

Conversation

@vladimir-pecanac-main

Copy link
Copy Markdown
Collaborator

Sample update for the article "Execute a PowerShell Script in C#" (https://code-maze.com/csharp-run-powershell-script/). Only dotnet-cli/ExecutingPowerShellScript changes.

Packages (re-queried on NuGet 2026-10-04):

  • Microsoft.PowerShell.SDK 7.6.6 (its only dependency group is net10.0, so the retarget is required)
  • Microsoft.NET.Test.Sdk 18.10.1
  • xunit 2.9.3, xunit.runner.visualstudio 4.0.0
  • coverlet.collector 10.1.0
    dotnet list package --vulnerable --include-transitive: clean.

Changes:

  • net7.0 to net10.0 in both projects.
  • ProcessStart starts pwsh with ArgumentList, UseShellExecute = false, reads both streams asynchronously, waits for exit and returns exit code, output and error (the old synchronous ReadToEnd on two redirected streams can deadlock, and the error text was dropped).
  • PowerShellClass.ExecuteScript uses AddCommand (AddScript with a path containing a space parses as a bare path and runs nothing) and sets InitialSessionState.ExecutionPolicy to Bypass; without it the hosted runspace inherits Restricted on a default Windows machine and throws PSSecurityException.
  • ExecuteCommand: FirstOrDefault plus a HadErrors check instead of First().
  • PSCustomRunspace is IDisposable; echo.ps1 ships with the project instead of a hardcoded desktop path; Program.cs uses top-level statements.

Local run (Windows, SDK 10.0.302, runtime 10.0.10, pwsh 7.6.6): build 0 warnings 0 errors; 7 of 8 tests passed, the eighth (starts Notepad) not run locally. All test classes keep the Live suffix, so CI builds the folder and runs none of them, as before.

- Both projects net7.0 to net10.0; Microsoft.PowerShell.SDK 7.3.3 to 7.6.6
  (7.6.x targets net10.0 only); test packages bumped, xunit kept.
- ProcessStart: start pwsh instead of powershell.exe, build arguments with
  ArgumentList, set UseShellExecute = false, read stdout and stderr
  asynchronously and wait for exit, return exit code, output and error.
- PowerShellClass.ExecuteScript: AddCommand instead of AddScript (a path with
  a space fails under AddScript) and a Bypass execution policy through
  InitialSessionState, since a hosted runspace otherwise inherits Restricted.
- ExecuteCommand: FirstOrDefault and a HadErrors check instead of First().
- PSCustomRunspace implements IDisposable and disposes its runspace.
- echo.ps1 added to the project; no more hardcoded desktop path.
- Program.cs uses top-level statements.
Drop the Microsoft.PowerShell.Utility import from PSCustomRunspace, which
made every cmdlet in that module (Get-Random, Invoke-Expression and more)
callable. The runspace now holds the Get-Date entry alone. Program.cs
comment names gedit as the Linux example.
@vladimir-pecanac-main
vladimir-pecanac-main merged commit bf611ac into CodeMazeBlog:main Oct 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant