PowerShell in .NET Core and Docker
Tags: netcore, docker, powershell
Published: 2020-06-16 20:37:47

---
title: PowerShell in .NET Core and Docker
published: true
date: 2020-06-16 08:00:00 UTC
tags: NETCore,Docker,PowerShell
canonical_url: https://SimonReynolds.ie/powershell-in-net-core-and-docker/
---

Since the beginning of ~~time~~.NET Core there has been one continuous annoyance about developing cross-platform solutions, including build scripts for windows and non-windows platforms.

We have at least fallen into a standard pattern, most repositories will contain both a `build.cmd` and `build.sh` that will build the project in whichever platform we're currently using.

Sometimes though there's only one or one is neglected in favour of the other. If we're using a build tool like [Cake](https://cakebuild.net/) or [Fake](https://fake.build/) then we have a simple setup, our build files can just trigger the build logic which is stored in a single file. In fact, both tools will give you default build files that do just that.

So what if we're just doing a relatively plain build task? Something like

<!--kg-card-begin: markdown-->
```bash
dotnet clean

dotnet tool restore

dotnet build ./src/*.csproj

dotnet build ./tests/*.csproj

dotnet test ./tests/*.csproj

dotnet package ./src/*.csproj
```
<!--kg-card-end: markdown-->

Over time changes will be made to this and human error is inevitable, a change will be made to `build.cmd` but not to `build.sh`, or vice versa.

Enter PowerShell Core, now available as a `dotnet tool`! Presuming you have the .NET Core SDK installed, you can simply run

<!--kg-card-begin: markdown-->
``` bash
dotnet tool install --global PowerShell
```
<!--kg-card-end: markdown-->

It will now be available with the `pwsh` command. But this still presumes that other developers will have it installed globally.

Let's add it on a project level.

<!--kg-card-begin: markdown-->
```bash
# add a tool manifest if there isn't one already
dotnet new tool-manifest

dotnet tool install PowerShell
```
<!--kg-card-end: markdown-->

Now PowerShell becomes a tool available in the project. Instead of `pwsh`, you will have to specify `dotnet pwsh` but now we can create a `build.ps1` file that can contain all our build logic and replace our `build.cmd` and `build.sh` files with a one-liner.

<!--kg-card-begin: markdown-->
``` bash
dotnet pwsh build.ps1
```
<!--kg-card-end: markdown-->

Now all our build logic is cross-platform without external dependencies!

Where this really comes into its own is that PowerShell has been included as a global tool in [.NET Core SDK docker images](https://hub.docker.com/_/microsoft-dotnet-core-sdk/).

Combined with Visual Studio Code's new Remote Development functionality, this means you can build a truly cross-platform development environment in a docker image. Simply [set it up for your project](https://simonreynolds.ie/developing-in-a-docker-container/), write one build script in PowerShell and rest secure in the knowledge that you're providing everything needed for another developer to be able to grab your project, open it up and build it immediately without having to worry about setting up dependencies or even what platform they're using!