Some time ago my team was involved in a reorg (I’ll skip the boring details), the end result is that I am now working on a different (and new) service and I am transitioning to a new role. This seemed a good moment to do some spring cleaning and reorganize my tools/scripts/modules etc… Over the years I have built a good amount of powershell scripts and modules (among other tools), most of them targeted for my and my colleagues specific work and role but I wanted to see if there was some I could instead share to hopefully help someone else. It took some time, I ended up deleting a number of old scripts no longer relevant (well, I couldn’t really delete them, they are just archived in a private GitHub repo 😉) and I have reworked some of my modules and functions into a collection hopefully worth sharing. The result is three new modules you can download either from the Powershell Gallery or from GitHub (and contributions are welcome, should you feel generous enough to open issues or send me a pull request 😊). PSToolbox (GitHub, Powershell Gallery) is a collection of functions for every day operations, things like…
-
-
Reverse a string in powershell
Exactly a month in of working from home and social distancing, last night I was playing around with some scripts and at some point I needed to read the last index or an array without knowing its length. Easy enough, regardless the array length, the last index is always -1: This reminded me of a conversation I had some time ago with a colleague, he was trying to convince me of much much Python is better than Powershell (and I stoically resisted and counter-punched 😉). One of the many arguments he used to convince me was to show how easy it is in Python to revert a string: True, that looks easy and elegant but the Powershell solution is not that bad, is it? A string is an array of characters, so I’m using the square brackets to read a sequence of characters from the original string. The trick here is that my starting point is index -1 (the last character of the string) and I’m moving backwards towards the first character; here I’m just using a negative index greater than the string length and powershell happily complies. I also need to join the output (with an empty string). If…
-
Break the pipeline
foreach can be confusing if you don’t pay attention to the context. Googling (or Binging, is that even a word? 🤔) around you can easily find articles and blog posts about foreach, how it is both a keyword and an alias (shortcut) for Foreach-Object and how foreach as keyword is different from Foreach-Object. Here are a couple of examples: PowerShell foreach loops and ForEach-Object Getting to know ForEach and Foreach-Object foreach as keyword is a pattern common across many programming and scripting languages used to loop through a list: foreach as alias for Foreach-Object can be used to get a similar output: In a more complex, real life scenario I may need to exit the loop without going through the whole list, that’s easily done using the break keyword: Ok, this is not a real, real world scenario but you get the idea: I’m looping through the list of files till a reach one named jobs.ps1 and skip the rest of the iteration, and as expected, the sample still prints the after loop message. Let’s try with Foreach-Object: Uhm… The loop was interrupted but at the wrong moment (jobs.ps1 should have not been printed to the console), moreover the output…
-
Test Powershell on Linux with Visual Studio Code and Docker
One of the promises (maybe, the biggest promise) of .NET Core and Powershell Core is being cross-platform, be able to develop applications (or Powershell scripts and modules) that can be executed on Windows, Linux and macOS; but how can we be sure the our application or script/module will actually run properly across all those platforms and distros? Talking about Powershell, PSScriptAnalyzer helps to check a script or function compatibility with certain Powershell versions or different platforms. But what if I want to actually write and test my script/module on Linux (assuming my main machine is Windows, of course 😉)? One easy solution is to spin up a virtual machine, install the tools I need (.NET Core, Powershell Core, Visual Studio Code and anything else required) or use the Remote Development extension pack for Visual Studio Code and use Docker containers instead. Note: this requires Visual Studio Code Insiders at this time; pay attention to the Installation notes for good tips to get started. Also, take a look at Developing Inside a Container in the official VSCode documentation. The extension pack allows to choose between Windows Substrate for Linux, connect to a remote machine through SSH or run a Docker container…
-
Powershell Core binary module with Visual Studio Code
I wrote countless scripts and a good amount of modules (and functions) in my years as Service Engineer but all of them are script modules, I never really created binary modules. The main reason is that I like to write in Powershell but I also like the fact that, not being a compiled language, it is very easy to share and modify the source code for a script module and it is immediately ready to be reloaded and used. Anyway out of curiosity and to learn a different approach to building modules, I decided to try to convert one of mine from script to binary; my first step was (of course) a quick search to find some samples and getting started articles and I found a few good ones (referenced below) but all of them use Visual Studio and the full version of the .NET Framework, while I want to use Visual Studio Code and .NET Core. So here’s what I came up with. First off of course I need .NET Core (I am using the latest .NET Core 3 preview 8 at the moment), Visual Studio Code and the C# Extension. Next, I’m going to create a Class Library…
-
Three modules and a video
While I took a longer break than I wanted to from blogging (busy days at work… 🤔) I still managed to stumble across a number of interesting Powershell modules, they bring little improvements here and there in my workflow and smooths out wrinkles from some tasks that are not are painless are they are supposed to be. PSReleaseTools This module by Jeff Hicks makes it easy to stay up to date with the latest Powershell releases: get information about the release changes, download and install the new bits and so on. PSScriptTools Another module by Jeff Hicks, this one is a collection of tools for different occasions, there are functions to work with modules, create extended type files, create objects from text output, work with files and optimize the text content, improve and colorize the output to the powershell console and so on. Check it out, you’ll likely find something useful for your scenario. EnvironmentVariableCmdlet This is a module by my colleague James Truher to simplify working with environment variables; Jason Helmick has a funny Youtube video where he (among other things) gives an overview of this module. And in the end it’s not the years in your life that count. It is the life…
-
Get all Switch Parameters for a Powershell function or script
The other day I was working on a Powershell function to return a list and filter it through a number of switch parameters; anyway if no switch is used I want to return a default, raw result without manipulation, in other words I want the result to look like this: One possible approach to obtain it is code similar to this: It works, but it’s not very elegant or efficient… for example, what if I need to add more switch options? I would have to add additional if statements but also update the last if to make sure no switch has been used. The example above can be refactored like this: The magic happens an line 17, here I have it on a one line but let me break it down: first, we can use Get-Command to retrieve the list of parameters for any script or function (here I have even getting the parameter list for the script ListSwitchParameters.ps1 from within the script itself) The Values property contains the list of ParameterNames, their type and a boolean indicating if the parameter is a SwitchParameter; since it’s switch parameters we’re looking for, it is easy to filter this list. Last, we…
-
Custom types with Powershell (part 2)
I’ve been doing some more experiments with custom types after my previous post on this topic and when working with classes there is an additional consideration to keep in mind: depending on where the class is declared, the object type (actually, the type name) changes which in turn will affect how the custom format file needs to be crafted. For example, let’s consider an example where the type declaration is outside a function declaration: If we execute this function and check the output with Get-Member, the type name matches exactly the class name as expected: If, on the other hand I define the class as part of the function, things change: Now if I execute this function again and pipe the output to Get-Member, the type name returned uses the function name as a namespace declaration; this is important and must be taken into account and used in the view name if we want it to match and properly format the output for this custom type: One final note about OutputType: The OutputType attribute value is only a documentation note. It is not derived from the function code or compared to the actual function output. As such, the value might…
-
Custom output formatting with Powershell
Now that I have my custom type I can use cmdlets such as Format-Table or Format-List to format its output while at the console, but it would be nice if I did not have to remember to usem the every time. Powershell uses Format.ps1xml to define how types should be formatted when their output is sent to the console and this technique can come to our rescue. If an output object exposes up to 4 properties, by default Powershell formats it as a table while objects with 5+ displayed properties are formatted as list for better readability; for example, in this first example I am selecting only four properties and Powershell prints data in a table format, while in the second example I am selecting five properties and Powershell presents then in a list: This is not always true though, for example Get-Process returns a table with 6 columns: This is because Get-Process returns a type that happens to have a custom format defined; which type is that? System.Diagnostic.Process. If we check $PSHOME and search the *.format.ps1xml files we can find that C:\Windows\System32\WindowsPowerShell\v1.0\DotNetTypes.format.ps1xml contains a definition for this .NET type: This is a relatively complex View definition with custom column…
-
Custom types with Powershell
Objects in Powershell do not necessarily have to have a defined type (or better, they can simply all be generic PSCustomObject) but from time to time it can be useful to use a custom type, for example to get nice TAB completion when passing those objects down the pipeline or to use custom formatting (more on this in a future post). Custom types are relatively easy to add; in essence, once we have an object ready to be returned as function output we can simply insert the type name in the TypeNames collection Here I am retrieving some properties from an Azure Sql Database, add them to a PSCustomObject and call $outObj.PSObject.TypeNames.Insert to insert a custom type name (AzSqlDatabaseSize) at index zero of the TypeNames collection. The output of commands would look like this: If I pipe the command to Get-Member instead, we can see the object type returned: Also, if I use this command in a pipeline I get TAB auto-completion: notice when I pipe the command to Where-Object (? is the shortcut) the property names suggested are exactly the ones returned by my custom type: Powershell 5 added classes support and custom types is one of the supported…