PSScriptAnalyzer (PSSA) 1.19.0 has been released


TL;DR; (Too Long; Didn’t Read)

This new minor version brings 5 new rules, the formatter is much faster and other enhancements and fixes. You can get it from the PSGallery here. At the same time the PowerShell extension for VS Code has released a new preview version. This ships with this new version of PSSA so that you can also take advantage of all the new configuration options. Therefore, whenever we reference the next version of the extension below, we mean the recently updated preview version or the next, upcoming release of the GA version. You can still take advantage of the new PSSA release in the GA version of the extension as well now by installing the module locally via Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -Force, but you won’t have access to the configuration settings of some of the new features. The full changelog is here.

New Script Analysis Rules

There are a total of five new analyzer rules and they were all added by the community!

  • AvoidLongLines (thanks Thomas Rayner!): Warns when a line is too long (default is 120 characters) but is not enabled by default.
  • AvoidOverwritingBuiltInCmdlets (thanks Thomas Rayner!): Warns you if you accidentally try to re-define a built-in cmdlet such as e.g. Get-Item by writing code like e.g. function Get-Item { }.
  • UseUsingScopeModifierInNewRunspaces (thanks Jos Koelewijn!): Warns you when trying to incorrectly reference a variable that is not defined directly in the scope of the current scriptblock. This applies e.g. to the -Command parameter of Invoke-Command or -Parallel of ForEach-Object (added in PowerShell 7, see blog here). It recommends to use the $using scope modifier to reference the variable correctly.
  • UseProcessBlockForPipelineCommand (thanks Matt McNabb!): Warns when a function declares support for pipeline input (via the [Parameter(ValueFromPipeline)] attribute) that the function needs to declare a process { } block.
  • ReviewUnusedParameter (thanks Matt McNabb!): Warns on parameters declared in a script, scriptblock, or function scope that have not been used in that scope. You can think of it as the equivalent of the UseDeclaredVarsMoreThanAssignments rule but for parameters instead of variables.

The added computational work for those rules are being compensated for by a performance improvement in the AvoidTrailingWhitespace rule, therefore the speed of running Invoke-ScriptAnalyzer for all rules is roughly the same compared to the previous version of PSScriptAnalyzer.



Several improvements have been made to the formatting rules and the engine that should result in the formatter being multiple times faster, especially for large scripts. The improvements were:

  • Reduced initialisation overhead.
  • Improved efficiency of formatting rules, which addresses the scaling problems that were seen for large scripts.
  • Reduced number of times the script text has to be re-parsed. In its current architecture, the formatter has to re-parse the script after every rule run and every applied correction. When a rule has no violations then the parsed AST and tokens are being recycled. This leads to faster formatting when no or only some correction have to be made.

To give a specific example, running the formatter on PowerShell‘s build.psm1 module, which has over 3000 lines, we’ve measure the following times for a ‘warm’ run:

  • Version 1.18.3 takes around 1,250 ms.
  • Version 1.19.0 takes around 550 ms.
  • Version 1.19.0 takes around 170 ms on the pre-formatted file.

The reason why we measure a ‘warm’ run is because in the editor scenario, the PowerShell extension will have likely already finished a run Invoke-ScriptAnalyzer in the background on the script, which means the CommandInfo cache has already been populated. Although the default set of formatting rules in the PowerShell extension for VS Code doesn’t need the CommandInfo cache so there isn’t much of a difference between cold and warm for most users, the following 2 optional rules do use the CommandInfo:

  • UseCorrectCasing: Controlled via the powershell.codeFormatting.useCorrectCasing setting of the PowerShell extension for VS Code.
  • AvoidUsingCmdletAliases: Controlled via the powershell.codeFormatting.autoCorrectAliases setting of the PowerShell extension for VS Code.

New Formatter features

  • Parameter Casing: The UseCorrectCasing rule now correct also the casing of parameters and not just the cmdlet names.
  • The PipelineIndentationStyle setting of UseConsistentIndentation has a new option now and will also become the default setting in the next version of the PowerShell extension for VS Code. The new value is named None and will not change the user’s pipeline indentation at all which makes this feature an opt-in scenario. For the previous non-default settings IncreaseIndentationForFirstPipeline and IncreaseIndentationAfterEveryPipeline all new user reported bugs are fixed now and therefore we encourage you to please try it out again.
  • The UseConsistentWhitespace option CheckPipe has not been changed to only ADD whitespace around the pipe if it is missing but does not remove extraneous whitespace. This is because some people prefer to line up their pipelines in Pester tests. For anyone who still wants to trim redundant whitespace around pipes, the new CheckPipeForRedundantWhitespace option has been provided. For users of the PowerShell extension for VS Code this means that in the next version of the PowerShell extension for VS Code we plan to split the existing powershell.codeFormatting.whitespaceAroundPipe (enabled by default) setting into 2 new ones: powershell.codeFormatting.addWhitespaceAroundPipe (enabled by default) and powershell.codeFormatting.trimWhitespaceAroundPipe (disabled by default). The preview extension will automatically create the addWhitespaceAroundPipe setting for you with the value of whitespaceAroundPipe if you are using this setting. In the next stable extension, the left-over whitespaceAroundPipe setting will be removed completely.
  • The UseConsistentWhitespace option CheckParameter has been added and you will be able to control it via this setting of the PowerShell extension for VS Code in its next update: powershell.codeFormatting.whitespaceBetweenParameters.

Other improvements

  • The compatibility rules were updated to includes profiles for PowerShell 7; support single number version strings; and analysis for PowerShell 7 syntax (null-conditional method invocation, null-coalescing operator, ternary expression and pipeline chain operator).
  • AvoidAssignmentToAutomaticVariable rule was enhanced to include not only warn on read-only automatic variables, but also other automatic variables that can but should not be assigned to, which also includes the commonly misused $input variable.
  • The minimum supported version of PowerShell Core is 6.2.4 now but please bear in mind that support for PowerShell 6.2 itself ends on September 04 2020, see support policy here.
  • Our CI system has been migrated to use multi-stage Azure Pipelines, meaning that every commit gets tested against Windows (Server 2016 and 2019), Ubuntu (16.04 and 18.04) and macOS (10.14 and 10.15) for PowerShell 7 and also Windows PowerShell 5.1. The previous AppVeyor build still provides coverage for PowerShell 4 and before the release a manual test was executed to guarantee functionality for PowerShell 3.

What’s next?

As mentioned in multiple, previous posts here and here, the PowerShell team is looking at a partial re-write of PSScriptAnalyzer, which will require a bump of the major version. Version 1.x continues to be supported for PowerShell 3 and 4, but will not receive new features and only critical security fixes. In version 2.x, support for PowerShell version 3 and 4 are expected to be dropped.

On behalf of the Script Analyzer team,

Christoph Bergmeister, Project Maintainer from the community, BJSS

Jim Truher, Senior Software Engineer, PowerShell Team, Microsoft

Rob Holt, Software Engineer, PowerShell team, Microsoft


Leave a comment