$$ \newcommand\Tr{\mathrm{Tr}} \newcommand{\braket}[2]{\langle #1 \mid #2 \rangle} \newcommand\I{\mathbb{I}} \newcommand{\avg}[1]{\left< #1 \right>} \newcommand{\RD}{D} \newcommand{\ri}{\mathrm{i}} \DeclareMathOperator{\sign}{sign} \DeclareMathOperator{\Sign}{Sign} \newcommand{\ii}{\mathrm i} \newcommand{\vv}{\mathrm v} \newcommand{\ff}{\mathrm f} \newcommand{\mm}{\mathrm m} \newcommand{\ee}{\mathrm e} \newcommand{\xx}{\mathrm x} \newcommand{\RR}{\mathrm R} \newcommand{\dd}{\mathrm d} \newcommand{\FF}{\mathrm F} \newcommand{\BB}{\mathrm B} \newcommand{\vph}{v_{\mathrm{ph}}} $$

How to Run PowerShell Script from C# Application

In this article we will look at how you can run PowerShell scripts from C#, specifically in this example we will just create a simple console application.

Recently I discovered a great C# package for working with many different CLIs including PowerShell and I started to think about the many different things I could automate or improve on by running my PowerShell scripts from a C# application.

Problem

You have a bunch of PowerShell scripts that you have to run, some examples would be daily checks on your servers, sql instances and rebuilding dev environments after overnight batch jobs etc.

Instead of running these scripts manually from PowerShell, you would like a C# app which will run them for you, this way you can maintain it and add additional functionality to your scripts and simply run your C# application to perform all the tasks.

Solution

The CliWrap package makes working with CLIs in C# easy and powerful. It works with all CLIs, so think git, npm, docker, etc. but recently I was using it for the daily sanity checks I run.

I have a PowerShell script I keep up to date and it does things like check no database is missing a backup, test the last backup, look for failed jobs that have ran overnight and other daily admin tasks like that. I wanted a way to run this easily and also have additional functionality I can create within a C# application, so I created a simple C# console application to run the script for me.

Example: Running PowerShell Script from within C# Console Application

As mentioned previously, I got this idea after seeing the CliWrap package, which makes it simple to work with CLIs from within a C# application. This example focuses on PowerShell and calls a PowerShell script which imports a module and performs a basic check.

Based on these foundations you could create your own daily checks C# application, or perhaps some other useful app which will help with your daily work tasks.

First lets start with the C# app, we need to add a reference to the CliWrap package and then add the code to call our PowerShell script.


using CliWrap;
using CliWrap.Buffered;

var dbDailyTasks = await Cli.Wrap("powershell")
    .WithWorkingDirectory(@"C:\Temp")
    .WithArguments(new[] { @"C:\Temp\script0.ps1" })
    .ExecuteBufferedAsync();

Console.WriteLine(dbDailyTasks.StandardOutput);
Console.WriteLine(dbDailyTasks.StandardError);
Console.ReadLine();

Next, our PowerShell script, which just performs a simple task, it imports the popular module for working with databases (dbatools) checks what version we have by running get-module and then uses the Get-DbaDatabase command to list out the databases on the given server.


Write-Host "Script Started..."

import-module dbatools
get-module dbatools
Get-DbaDatabase -SqlInstance "localhost\mssqlserver01" | Select-Object Name

Write-Host "Script Finished..."

Below is an image of the output once we run our C# application. You can see it prints out the version of dbatools we imported which is 1.1.142 and then it lists out the database names from the sql instance as expected.

CliWrap Code

Conclusion

This example is very simple, but also gives you an idea of what a powerful combination C# and PowerShell could be. As developers and system administrators, running PowerShell scripts is typically something we do daily, so it is nice to think of how we could create an application around these scripts which would become a powerful tool to help us with our daily tasks and perhaps make our existing PowerShell scripts more useful.