Replace Powershell with C# scripts!
I was mind blown when I first saw this tool. It let you use the C# language in all it's glory with the framework, classes and namespaces to make small apps compiled just in time like scripts. We will walk throught the pros and cons of using it.
The sources files from this article are available here.
Installation
Using the dotnet extensibility tool, the installation process is resumed to one line and will make dotnet-script
accessible from anywhere.
dotnet tool install -g dotnet-script
You're first C# script
The next command will initialize the current folder with a hello-world like csx file and create the required configs to debug with Visual Studio Code.
dotnet script init
Making a script to backup an Azure File Share
This will be a port of our previously made powershell script.
Nugets
Nugets are supported through a special syntaxe. You can also specify Dlls.
Add thoses line to the main.csx
.
#r "nuget: CliWrap, 3.2.3"
using System;
using CliWrap;
using CliWrap.Buffered;
When changing a Nuget with VS Code, you must restart OmniSharp.
Ctrl+Shit+P -> Restart OmniSharp
Add variables
var storageSubscription = "";
var storageAccountName = "";
var storageAccountKey = "";
var storageRessourceGroup = "";
var storageFileShareName = "";
var expiry = DateTime.Now.AddHours(12).ToString("yyyy-MM-ddTHH:mmZ");
Generate a SAS key
With CliWrap we can't call az
directly but the full path of the bootraper.
In a Command Promt :
C:\Users\nfs12>where az
C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.cmd
Next, append the API call to the file.
const string AZ = @"C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.cmd";
var sasTokenCmdResult = await Cli.Wrap(AZ)
.WithArguments($@"storage share generate-sas --subscription {storageSubscription} --account-key {storageAccountKey} --account-name {storageAccountName} --name {storageFileShareName} --expiry {expiry} --permissions lr")
.ExecuteBufferedAsync();
Be aware that the StandardOutput
returns a Windows new line so we remove it to grab only the token.
var sasToken = sasTokenCmdResult.StandardOutput.Replace("\r\n", "");
Delete the olds files
if(Directory.Exists(storageFileShareName))
Directory.Delete(storageFileShareName, true);
Copy the files from the Cloud to a local folder
There is currently a bug with OmniSharp that breaks the coloration if we don't use the var
keyword.
var a = await Cli.Wrap(@"azcopy.exe")
.WithArguments($"copy https://{storageAccountName}.file.core.windows.net/{storageFileShareName}?{sasToken} ./ --recursive")
.ExecuteAsync();
Delete the SAS key
Lastly we revoke the delegation key after it's use.
var b = await Cli.Wrap(AZ)
.WithArguments($@"storage account revoke-delegation-keys --subscription {storageSubscription} --name {storageAccountName} --resource-group {storageRessourceGroup}")
.ExecuteAsync();
Wrap it up
If you're a C# developper and you need a quick modifiable script but you don't have to call any other executables, I would recommand dotnet-script
as experimental. The tool is backed by OmniSharp, who is part of the .Net Fondation.
If you need to call executables, it is a little more work and when a process crashes, it is not verbose. dotnet-script
could and should implements a custom and simpliest way to call external executables. When that happens, goodbye Powershell!
Don't forget, the source code is in GitHub!