In this months DevOps Guide we're getting into scripting. It's just the fastest way to simplify complex tasks. Before you continue, please make sure you are familiar with command line basics.
Just the other day, I wrote a small script to
- download multiple swagger json files from services
- download the swagger-to-PDF tool
- generate a single pdf with all api endpoints
Now developers don't even have to know which tool we use to generate our api documentation. They see the script, run it, and have the pdf file.
Furthermore the tool just automatically identifies which API versions are available.
Cross-Platform PowerShell
Why PowerShell? Well, it is preinstalled on Windows and easy to install on macOS and Linux.
Installing most other scripting languages on Windows is complicated.
My main motivation here is to keep the entrance barrier as low as possible. Enable everyone on your team.
If your team is already familiar with another cross-platform scripting solution (e.g. bash on windows via Cygwin), you already have all you need for our series on DevOps. In that case you can skip this one for the series.
Installation
For this tutorial, we need PowerShell and Visual Studio Code.
PowerShell
For installation steps, follow this guide by microsoft for your operating system.
On Windows, the installation of PowerShell 7 is optional. However, some advanced scripts will require PowerShell 7.
Extra Step for Windows
Before running PowerShell scripts on Windows, you must run Set-ExecutionPolicy Unrestricted
.
On macOS and Linux, Unrestricted is the default.
For more information, see microsoft's documentation on Execution Policies.
Visual Studio Code
Now let's download and install Visual Studio Code from Microsoft.
Visual Studio Code offers coding assistance and even debugging functionality for PowerShell. So we will be using visual studio code as free cross-platform script editor within this tutorial.
If you prefer a different editor, I still recommend using Visual Studio Code for this tutorial. After the tutorial, you should check if your preferred editor has the same debugging functionality.
Start Scripting
After getting comfortable with moving around your file system, let's write your first script.
Open Visual Studio Code and create a new file and save it with the .ps1 ending.
This way Visual Studio Code will recognize it as PowerShell script and offer a play button in the top right.
Also I can really recommend reading Microsoft's Guides to Debugging PowerShell with Visual Studio Code to learn how to use Breakpoints and Watches.
She-Bang
As they use different default shells, the first line of your cross-platform script will tell macOS and Linux, that this is a PowerShell script.
pwsh is the command name for PowerShell in macOS and linux.
#! /usr/bin/env pwsh
Hello World
In PowerShell, you have different possibilities to write output.
While Write-Host is okay to give the user information on the state of your script. However, Write-Object, Write-Error Write-Debug and Write-Verbose will be important for advanced scripts.
It's a good idea to be very verbose and always tell the script-user what's happening.
So we can use Write-Host "Copying files, please wait."
to display exactly this text to the console.
#! /usr/bin/env pwsh Write-Host "Hello World."
Variables
Variables in PowerShell are names with a prefixed $ sign.
e.g. $count, $foldername, $date, etc.
#! /usr/bin/env pwsh $directory = Get-Location Write-Host "Current directory: $directory"
Objects
The main advantage of PowerShell is its object orientation.
Assuming that your script is called test.ps1, we can read this files properties:
#! /usr/bin/env pwsh Set-StrictMode -Version Latest $scriptfile = Get-Item test.ps1 Write-Host "File name: $scriptfile.Name" Write-Host "File extension: $scriptfile.Extension" Write-Host "Creation Date: $scriptfile.CreationTimeUtc"
You can use Visual Studio Codes Watch function to examine your script's objects.
As this would be a lot to cover, we will have a closer look at PowerShells object orientation later on. For now, just keep this fact in mind.
Strict Mode
I always recommend enabling Strict Mode in all your scripts.
This is basically your standard second line after the she-bang.
It causes your scripts to abort when using uninitialized variables, non-existant properties etc.
#! /usr/bin/env pwsh
Set-StrictMode -Version Latest
See Microsofts documentation for detailed information on strict mode.
If Else
Microsoft has a super documentation on if-else in PowerShell, including many great examples.
Therefore I only want to show one example here for completeness.
#! /usr/bin/env pwsh Set-StrictMode -Version Latest $number = 2; if ($number -gt 2) { Write-Host "$number is greater than 2" } elseif ($number -eq 2) { Write-Host "$number is equal to 2" } else { Write-Host ("$number is less than 2") }
Loops
Microsoft also has a super documentation on loops in PowerShell, so this example is also quite short.
As PowerShell is object oriented, I tend to use ForEach normally.
For
or While
Loops are quite rare in my scripts.
#! /usr/bin/env pwsh Set-StrictMode -Version Latest Write-Host "Listing files in current folder:" foreach ($file in Get-ChildItem) { Write-Host "- $file (created $($file.CreationTime))" }
See more more great examples at Microsoft's documentation:
Further Reading
PowerShell is very popular, so you can google "How to in PowerShell".
The following are among some of my favourite resources:
- Official PowerShell Documentation
- Strongly Typed Variables in PowerShell
- Parameters in PowerShell Scripts
- PowerShell Guru Best Practices
- Arrays in PowerShell
Next Steps
With this basic scripting knowledge, we are able to get started automating in the upcoming episodes of our DevOps Guide.
While most scripts will only run very few commands, these are a few commands that you and your colleagues save every day. And let's not forget the manual errors avoided by your scripts.
We can use them for builds, deployments, tests, project setup, anything!
If you have questions during your first steps in PowerShell, please contact me on Discord, Twitter or Facebook.
Top comments (0)