Using PSCodeHealth to check if your code meets metrics goals

Running Invoke-PSCodeHealth provides quite a few metrics related to the quality and maintainability of your PowerShell code. That's nice, but what is more important is how you can use this information.

PSCodeHealth comes with a set of default compliance rules for most of the code metrics it gathers. The purpose of these compliance rules is to help answer questions like :
- Which functions are nice and clean, and which ones are negatively impacting the overall quality and maintainability of my project ?
- Which aspect of quality or maintainability should I focus on to improve my code ? Complexity ? Test coverage ?
- The average complexity in my project is : 11. Is it bad, okay, or awesome ?

Viewing all the compliance rules

To view all the default compliance rules, simply run the following command :

PS C:\> Get-PSCodeHealthComplianceRule

Metric Name                   Metric Group       Warning Threshold Fail Threshold    Higher Is Better 
-----------                   ------------       ----------------- --------------    ---------------- 
LinesOfCode                   PerFunctionMetrics 30                60                False            
ScriptAnalyzerFindings        PerFunctionMetrics 7                 12                False            
TestCoverage                  PerFunctionMetrics 80                70                True             
CommandsMissed                PerFunctionMetrics 6                 12                False            
Complexity                    PerFunctionMetrics 15                30                False            
MaximumNestingDepth           PerFunctionMetrics 4                 8                 False            
LinesOfCodeTotal              OverallMetrics     1000              2000              False            
LinesOfCodeAverage            OverallMetrics     30                60                False            
ScriptAnalyzerFindingsTotal   OverallMetrics     30                60                False            
ScriptAnalyzerErrors          OverallMetrics     1                 3                 False            
ScriptAnalyzerWarnings        OverallMetrics     10                20                False            
ScriptAnalyzerInformation     OverallMetrics     20                40                False            
ScriptAnalyzerFindingsAverage OverallMetrics     7                 12                False            
NumberOfFailedTests           OverallMetrics     1                 3                 False            
TestsPassRate                 OverallMetrics     99                97                True             
TestCoverage                  OverallMetrics     80                70                True             
CommandsMissedTotal           OverallMetrics     200               400               False            
ComplexityAverage             OverallMetrics     15                30                False            
ComplexityHighest             OverallMetrics     30                60                False            
NestingDepthAverage           OverallMetrics     4                 8                 False            
NestingDepthHighest           OverallMetrics     8                 16                False            

For example, regarding the TestCoverage metric, the higher the value, the better it is. So below 70% is considered a "Fail", between 70% and 80% is a "Warning" and 80% or above is a "Pass".

For a brief explanation of the metrics and how the thresholds are set (hint: not arbitrarily), please refer to the page Metrics collected by PSCodeHealth.

Viewing the compliance rules in a specific metrics group

There are 2 groups of metrics : OverallMetrics (aggregated for the whole health report) and PerFunctionMetrics (at the function level).
To view only the compliance rules for per-function metrics, use the SettingsGroup parameter of Get-PSCodeHealthComplianceRule, like so :

PS C:\> Get-PSCodeHealthComplianceRule -SettingsGroup PerFunctionMetrics

Metric Name                   Metric Group       Warning Threshold Fail Threshold    Higher Is Better 
-----------                   ------------       ----------------- --------------    ---------------- 
LinesOfCode                   PerFunctionMetrics 30                60                False            
ScriptAnalyzerFindings        PerFunctionMetrics 7                 12                False            
TestCoverage                  PerFunctionMetrics 80                70                True             
CommandsMissed                PerFunctionMetrics 6                 12                False            
Complexity                    PerFunctionMetrics 15                30                False            
MaximumNestingDepth           PerFunctionMetrics 4                 8                 False           

Viewing the compliance rules for 1 or more specific metric(s)

In case you are only interested in 3 specific metrics, let's say NestingDepthAverage, NestingDepthHighest and TestCoverage, you can specify these metrics via the MetricName parameter :

PS C:\> Get-PSCodeHealthComplianceRule -MetricName NestingDepthAverage,NestingDepthHighest,TestCoverage

Metric Name                   Metric Group       Warning Threshold Fail Threshold    Higher Is Better 
-----------                   ------------       ----------------- --------------    ---------------- 
TestCoverage                  PerFunctionMetrics 80                70                True             
TestCoverage                  OverallMetrics     80                70                True             
NestingDepthAverage           OverallMetrics     4                 8                 False            
NestingDepthHighest           OverallMetrics     8                 16                False            

Have you noticed that this outputs 2 compliance rules for TestCoverage ?
This is because this metric is measured at 2 different levels :
- Across the entire set of analyzed PowerShell files (in the OverallMetrics metrics group)
- At the function level (in the PerFunctionMetrics metrics group)

Also, you don't have to memorize and type all the metric names, they are discoverable via tab-completion.

Checking some PowerShell code against all compliance rules

The cmdlet which brings together the values in a code health report and the compliance rules is Test-PSCodeHealthCompliance.
This cmdlet output objects of the type PSCodeHealth.Compliance.Result and the most important piece of information is in their Result property.
This Result property contains a string, and its possible values are :
- Fail
- Warning
- Pass

Here is the simplest way of using Test-PSCodeHealthCompliance :

PS C:\> $HealthReport = ipch C:\coveralls C:\coveralls

PS C:\> Test-PSCodeHealthCompliance -HealthReport $HealthReport

Metric Name                   Warning Threshold  Fail Threshold    Value             Result           
-----------                   -----------------  --------------    -----             ------           
LinesOfCode                   30                 60                39                Warning          
ScriptAnalyzerFindings        7                  12                2                 Pass             
TestCoverage                  80                 70                0                 Fail             
CommandsMissed                6                  12                20                Fail             
Complexity                    15                 30                5                 Pass             
MaximumNestingDepth           4                  8                 3                 Pass             
LinesOfCodeTotal              1000               2000              204               Pass             
LinesOfCodeAverage            30                 60                22.67             Pass             
ScriptAnalyzerFindingsTotal   30                 60                4                 Pass             
ScriptAnalyzerErrors          1                  3                 1                 Pass             
ScriptAnalyzerWarnings        10                 20                3                 Pass             
ScriptAnalyzerInformation     20                 40                0                 Pass             
ScriptAnalyzerFindingsAverage 7                  12                0.44              Pass             
NumberOfFailedTests           1                  3                 2                 Warning          
TestsPassRate                 99                 97                84.62             Fail             
TestCoverage                  80                 70                39.6              Fail             
CommandsMissedTotal           200                400               61                Pass             
ComplexityAverage             15                 30                2                 Pass             
ComplexityHighest             30                 60                5                 Pass             
NestingDepthAverage           4                  8                 1.11              Pass             
NestingDepthHighest           8                  16                3                 Pass            

Note : ipch is an alias for Invoke-PSCodeHealth.
An existing code health report needs to be input, so the HealthReport parameter is mandatory.

Note : Test-PSCodeHealthCompliance outputs a single compliance result for each per-function metric, even if there are multiple functions in the input health report. This is because, for a given per-function metric, the retained value will be the worst value of all functions.
So, for a metric where "Higher Is Better", the retained value is the value from the function which has the lowest value. This retained value is the single value that is compared with the warning threshold and fail threshold for this particular metric to determine the compliance result.

Also, if you use Invoke-PSCodeHealth to generate an HTML report, many HTML elements are styled (colored) according to their compliance result.

Checking some PowerShell code against specific compliance rules

Just like for Get-PSCodeHealthComplianceRule, Test-PSCodeHealthCompliance has the SettingsGroup and MetricName parameters, which can be used to filter compliance results.
The SettingsGroup parameter filters the compliance results for a specific group of metrics (OverallMetrics or PerFunctionMetrics).
The MetricName parameter filters the compliance results for 1 or more metric(s).
They can even be used in combination :

PS C:\> Test-PSCodeHealthCompliance $HealthReport -SettingsGroup OverallMetrics -MetricName TestCoverage

Metric Name                   Warning Threshold  Fail Threshold    Value             Result           
-----------                   -----------------  --------------    -----             ------           
TestCoverage                  80                 70                39.6              Fail             

The above tells us that it would be a good idea to spend some time on improving the code coverage of the tests in this project.
Also, the value 39.6% is below the generally accepted targets by a large margin, so this is likely a low hanging fruit : we could probably improve significantly this metric without a huge amount of effort.