Best Practices: Analyze your PowerShell with PSScriptAnalyzer code [Quick Guide]
PSScriptAnalyzer is a module PowerShell that checks the code of your scripts and your modules to assess the quality of your code based on a set of rules of practice.
You can use predefined and corresponding rules on best practices identified by the PowerShell team and the community around this language. In addition, you can create your own set of rules specific to your company.
The advantage of using PSScriptAnalyzer is that it will tell you the results of my diagnosis according to rules of warnings or errors, with the potential risk, but also a suggestion to correct the points highlighted. As a result, you can on the one hand to improve the quality of your code, but also improve you in General so that you apply these best practices course.
In this tutorial, we will install the module and we’ll put it into practice on a few scripts.
Video version of the tutorial:
II. Install PSScriptAnalyzer
to begin with, we will install this module. It is compatible with Windows from PowerShell 3.0, and according to the page of the module, it works with PowerShell Core under Linux , at least on Ubuntu 14.04. Page of the module: GitHub PSScriptAnalyzer
to install it, simply, directly from the PSGallery:
Install-Module - Name PSScriptAnalyzer - Repository PSGallery - Force
the proof below image 🙂
before you continue, you can list the module commandlets, which there are 2 at the moment.
To use the PSScriptAnalyzer module in several concrete cases, including the commandlet “Invoke-ScriptAnalyzer” which allows you to start a scan of the code on a script or module PowerShell, I’ve used a few scripts that I have published on my GitHub (and coded by me).
III. PSScriptAnalyzer: Example # 1
Let’s start with the “Backup – AllGPO.ps1” script that allows to save its GPO… To run the analysis on this script, invoke the following command:
Invoke-ScriptAnalyzer - Path .ad-backup-allgpo
vous will notice that it is not clear a PS1 file directly, but a folder, which means that all PowerShell files will be scanned. The result of the analysis contains a property “ ScriptName ” which will indicate the name of the script exactly.
On the screenshot below, you’ll notice that a dozen corrections are suggested by the ScriptAnalyzer . Although there are several identical and are not critical in the sense where it does not prevent the script to function, it is important to pay attention to.
Make the point.
- Information: PSAvoidUsingPositionalParameters
this rule indicates that it is better to avoid using positional parameters, but to instead name the parameters and specify a value for each parameter. In fact, in my script I use “Write-Host” followed the text to display in the console without specifying a parameter, good practice like that instead of writing:
Write-Host "My text"
Write-Host - Object "My text"
which will allow me to correct two points back by the ScriptAnalyzer.
Note: In the result displayed in the console, property “Line” poster the line “mistakenly” escalation by the parser within the script named with the ScriptName property.
- Warning: PSAvoidUsingWriteHost
this rule indicates that the “Write-Host” commandlet is used so that it will not work in all cases, but especially because it is better to use Write-Output, Write-Verbose or Write Information instead. For more information on this recommendation: Write-Host, Attention!
Which is silly, because advantage other commandlets is we can redirect the output, or even pass it on to another object, it is not just the display in the console. Another way to manage the text output, but to follow best practices, it is necessary to adapt the script.
For my part, I direct myself to Write-Output since my behavior is close to Write-Host to display content in the console. After, feel free to choose the formula best suited to your needs.
- Warning: PSAvoidUsingCmdletAliases
a warning that comes up twice, about “Select” and “Foreach” that are aliases of the commands “Select Object” and “Foreach-Object”. The Analyzer Script recommends using the full names of the commandlets rather than the alias.
After having followed the advice and recommendations of PSScriptAnalyzer, we can see that there are more changes to the script:
IV. PSScriptAnalyzer: Example # 2
for example now, the “Start – BitsDownloadRecursive.ps1” script that allows to download a complete tree of files through BITS. If you look at the output of the command Invoke-ScriptAnalyzer, there is the result the recommendations already obtained in the previous example, we know how to fix. 🙂
ultimately is not surprising to see the same rules match because if one for the same logic in my scripts, one commits the same imperfections. The goal is to improve.
V. PSScriptAnalyzer: Example # 3
Finally, let’s take as an example the “Add – NetworkPrinter.ps1” script that allows to add a network printer on a machine via PowerShell, of course. The Analyzer Script for this script does not follow the same rules as before.
- Warning: PSAvoidUsingWMICmdlet
to work with printers, I use the “Get-WmiObject” commandlet, as its name suggests making a WMI query on the machine. However, it is now preferable to CIM request for benefit of the model common to different operating systems.
For my part, I believe that at the moment for reasons of compatibility and in this case, it is best to stay as it will not bring much to spend on a CIM query in WMI. This particularly, because it takes at least PowerShell 3.0 to support the CIM queries.
In the case of my script, here is a command to list the printers, whether in CIM or WMI gives the same information, only the format of the output is different.
This tutorial on the PSScriptAnalyzer module coming to an end, I hope it encourages you to use it for your creations in order to have an optimized code and in response to good practices. This groundwork also facilitates the recovery of the code by another person since it is beneficial to understanding the code also.
To go further:
- you can list the existing rules and thus take knowledge even before they emerge in an analysis: Get-ScriptAnalyzerRule
- you can include or exclude rules using the parameters “IncludeRule” and “ExcludeRule” followed of the name or the names of rules