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…
-
# (pound sign) to search the Powershell history
I spend a lot of time working at the Powershell console so it is common for me to type (or retype) the same command multiple times; of course I tend to not really retype the same command every time but rather use Get-History and related cmdlets to re-execute previous commands: The quickest way to re-execute a previous command is to use Invoke-History followed by the Id from Get-History: I like to use shortcuts (or aliases, as you can see from my history above 😊) so I would normally use h (Get-History) and r <id> (Invoke-History <id>). Sometimes I need to slightly modify the command before running it again, there’s an easy solution for that as well: Simply copy the CommandLine value from Get-History to the clipboard, paste it to the console and change what’s needed PSReadLine improves the history search capability, here’s a list of bound key handlers related to history management: For example, using Ctrl+R (search history backwards) I can type a part of a string (“keyhan” in this example) and PSReadLine shows the first matching command, I can either hit TAB to accept the command and run it, or use CTRL+R to cycle through other commands matching the…
-
Publish module to Powershell Gallery from Azure Pipelines
Now that I have my module on Github and built the module on Azure Pipelines, I want to publish it to the Powershell Gallery. The first step it of course to create a free account; once you have the account you can head to your profile, click on API Keys and then Create: The Create dialog allows to choose the key name, the expiration and very important, the scope (what permission the key will have on the Gallery) and which packages the key is allowed to control through Global Pattern. In my case I want the key to expire every year, I want the key to grant permission to publish new packages and update existing ones and I want this key to be used only for LSE modules: notice I used LSE* as Global Pattern, this way this same key will allow me to publish and manage new packages as long as their name begins with LSE. Azure Pipelines allows to securely store secrets (passwords and keys) as variables, if you want to do so you can use the Variables tab in your Pipeline then click the padlock icon: Anyway I prefer to store the key in Azure KeyVault since…
-
X509Certificate is immutable on this platform. Use the equivalent constructor instead
Quick tip today. Recently I decided to switch to to Powershell Core as default on all my machines for my daily work and it’s working great (except a few corner cases where I’m forced to go back to Powershell Desktop due to some old module incompatibility). To do so, over the last few weeks I had to go through the modules and script I use the most and port them to Pwsh. One of my cmdlets is meant to convert a certificate to and from its Base64 representation (this is useful to export certificates from Azure KeyVault for example), the heart of the code where the transformation happens looks like this: Unfortunately though, while testing the code on Powershell Core I got this error: It turns out the problem is with how I was creating the certificate object and loading its data. To avoid the exception the solution is to go from this: To this: I didn’t spent too much time to figure out why the exception is thrown (especially considering the Import() method is available on .NET Core/Pwsh) but at least I hope this will save someone else some time (and a headache 😉). I have never met a man so ignorant that…
-
Hogwarts colors for VSCode
Developers spend so much time in their IDE of choice that it has to feel like a second home: it is not uncommon for devs to spend time to customize, often in minute details, the look and feel of their code editor to maximize their productivity. My favorite editor by far is Visual Studio Code, the Marketplace has a growing number of extensions and Color Themes are a popular category, there are plenty of themes, colors, icons to choose from. But despite all this abundance I could not find a theme that reminded me of my other favorite environment (and book series): Harry Potter and Hogwarts 🤓 So I decided to create my own, trying to stay as close as possible to the colors seen in the movie series and described by J.K.Rowling on Pottermore: Colours Red, green and shocking pink: the importance of wizarding world colours How do you colour coordinate the wizarding world? Colours or Pottermore damngoodshindig.com for the Hogwarts and House crests On the technical side, creating a color theme for VSCode is not complicated, the documentation has what’s needed to get started and follow along some samples: Theming (under extensibility reference) Color Theme Theme color reference Maybe…
-
Run Pester tests on Azure Pipelines
Now that I have some simple functions and some tests in my master branch on Github, I want to make sure the tests are executed (and pass!) every time I merge some new code. At this point I do not care too much about my dev branch because I know I’ll commit often and things will not always be stable, but I’ll make sure all my test will pass before I merge from dev to master (and later I way want to publish from master to the Powershell Gallery, but only if all tests pass of course!). The first thing I need is an account on Azure DevOps (you can start with a free account) and when ready, head to Pipelines then Builds: Since my code is in Github, that’s what I’ll choose: The first time we setup this integration, Azure Pipelines must be authorized to access Github: Since I don’t have a yaml file already, I’ll select Starter pipeline At this point in my tests things got a bit murky. The Azure Devops Marketplace has (as of this post) two free extensions to run Pester tasks so I decided to try them. I installed both extensions and added them…
-
Test Azure custom modules with Pester
Before I go too far along with building my LSECosmos module I must add proper tests. Just as a quick refresher (or to get some context if you’re not familiar with the concept), here are some pointers about Test Driven Development and Unit Testing: Test Driven Development (Wikipedia) Unit Testing (Wikipedia) Software Testing Fundamentals While it is relatively straightforward to test simple scripts (we would likely manually run the script testing a 2-3 core scenarios to make sure nothing terrible happens), things can get complicated fairly quickly with longer scripts or modules, especially when they are using a variety of cmdlets to take actions (think about Azure resources for example, or any other system-wide on-prem operation), need to pass data and objects back and forth between calls and so on. If you have written enough lines of code (no matter the language/tool you use), I bet you can remember at least one occasion where you decided to make an apparently small and innocent change to a well working piece of software an all hell broke loose 😵. I recently came across this meme on Facebook, it sums it up nicely 😅 (thanks to CodeChef for sharing): At its core proper…