|
| 1 | +TOPIC |
| 2 | + about_PSScriptAnalyzer |
| 3 | + |
| 4 | +SHORT DESCRIPTION |
| 5 | + PSScriptAnalyzer is a static code checker for PowerShell script. |
| 6 | + |
| 7 | +LONG DESCRIPTION |
| 8 | + PSScriptAnalyzer checks the quality of Windows PowerShell script by evaluating |
| 9 | + that script against a set of rules. The script can be in the form of a |
| 10 | + stand-alone script (.ps1 files), a module (.psm1, .psd1 and .ps1 files) or |
| 11 | + a DSC Resource (.psm1, .psd1 and .ps1 files). |
| 12 | + |
| 13 | + The rules are based on PowerShell best practices identified by the |
| 14 | + PowerShell Team and the community. These rules can help you create more |
| 15 | + readable, maintainable and reliable scripts. PSScriptAnalyzer generates |
| 16 | + DiagnosticResults (errors and warnings) to inform you about potential script |
| 17 | + issues, including the reason why there might be an issue, and provide you |
| 18 | + with guidance on how to fix the issue. |
| 19 | + |
| 20 | + PSScriptAnalyzer is shipped with a collection of built-in rules that check |
| 21 | + various aspects of PowerShell code such as presence of uninitialized |
| 22 | + variables, usage of the PSCredential Type, usage of Invoke-Expression, etc. |
| 23 | + |
| 24 | + The following additional functionality is also supported: |
| 25 | + |
| 26 | + * Including and/or excluding specific rules globally |
| 27 | + * Suppression of rules within script |
| 28 | + * Creation of custom rules |
| 29 | + * Creation of loggers |
| 30 | + |
| 31 | +RUNNING SCRIPT ANALYZER |
| 32 | + |
| 33 | + There are two commands provided by the PSScriptAnalyzer module, those are: |
| 34 | + |
| 35 | + Get-ScriptAnalyzerRule [-CustomizedRulePath <string[]>] [-Name <string[]>] |
| 36 | + [-Severity <string[]>] |
| 37 | + [<CommonParameters>] |
| 38 | + |
| 39 | + Invoke-ScriptAnalyzer [-Path] <string> [-CustomizedRulePath <string[]>] |
| 40 | + [-ExcludeRule <string[]>] [-IncludeRule<string[]>] |
| 41 | + [-Severity <string[]>] [-Recurse] [-SuppressedOnly] |
| 42 | + [<CommonParameters>] |
| 43 | + |
| 44 | + To run the script analyzer against a single script file execute: |
| 45 | + |
| 46 | + PS C:\> Invoke-ScriptAnalyzer -Path myscript.ps1 |
| 47 | + |
| 48 | + This will analyze your script against every built-in rule. As you may find |
| 49 | + if your script is sufficiently large, that could result in a lot of warnings |
| 50 | + and/or errors. See the next section on recommendations for running against |
| 51 | + an existing script, module or DSC resource. |
| 52 | + |
| 53 | + To run the script analyzer against a whole directory, specify the folder |
| 54 | + containing the script, module and DSC files you want analyzed. Specify |
| 55 | + the Recurse parameter if you also want sub-directories searched for files |
| 56 | + to analyze. |
| 57 | + |
| 58 | + PS C:\> Invoke-ScriptAnalyzer -Path . -Recurse |
| 59 | + |
| 60 | + To see all the built-in rules execute: |
| 61 | + |
| 62 | + PS C:\> Get-ScriptAnalyzerRule |
| 63 | + |
| 64 | +RUNNING SCRIPT ANALYZER ON A NEW SCRIPT, MODULE OR DSC RESOURCE |
| 65 | + |
| 66 | + If you have the luxury of starting a new script, module or DSC resource, it |
| 67 | + is in your best interest to run the script analyzer with all the rules |
| 68 | + enabled. Be sure to evaluate your script often to address rule violations as |
| 69 | + soon as they occur. |
| 70 | + |
| 71 | + Over time, you may find rules that you don't find value in or have a need to |
| 72 | + explicitly violate. Suppress those rules as necessary but try to avoid |
| 73 | + "knee jerk" suppression of rules. Analyze the diagnostic output and the part |
| 74 | + of your script that violates the rule to be sure you understand the reason for |
| 75 | + the warning and that it is indeed OK to suppress the rule. For information on |
| 76 | + how to suppress rules see the RULE SUPPRESSION section below. |
| 77 | + |
| 78 | +RUNNING SCRIPT ANALYZER ON AN EXISTING SCRIPT, MODULE OR DSC RESOURCE |
| 79 | + |
| 80 | + If you have existing scripts, they are not likely following all of these best |
| 81 | + practices, practices that have just found their way into books, web sites, |
| 82 | + blog posts and now the PSScriptAnalyer in the past few years. |
| 83 | + |
| 84 | + For these existing scripts, if you just run the script analyzer without |
| 85 | + limiting the set of rules executed, you may get deluged with diagnostics |
| 86 | + output in the form of information, warning and error messages. You should |
| 87 | + try running the script analyzer with all the rules enabled (the default) and |
| 88 | + see if the output is "manageable". If it isn't, then you will want to "ease |
| 89 | + into" things by starting with the most serious violations first - errors. |
| 90 | + |
| 91 | + You may be temtped to use the Invoke-ScriptAnalyzer command's Severity |
| 92 | + parameter with the argument Error to do this - don't. This will run every |
| 93 | + built-in rule and then filter the results during output. The more rules the |
| 94 | + script analyzer runs, the longer it will take to analyze a file. You can |
| 95 | + easily get Invoke-ScriptAnalyzer to run just the rules that are of severity |
| 96 | + Error like so: |
| 97 | + |
| 98 | + PS C:\> $errorRules = Get-ScriptAnalyzer -Severity Error |
| 99 | + PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $errorRules |
| 100 | + |
| 101 | + The output should be much shorter (hopefully) and more importantly, these rules |
| 102 | + typically indicate serious issues in your script that should be addressed. |
| 103 | + |
| 104 | + Once you have addressed the errors in the script, you are ready to tackle |
| 105 | + warnings. This is likely what generated the most output when you ran the |
| 106 | + first time with all the rules enabled. Now not all of the warnings generated |
| 107 | + by the script analyzer are of equal importance. For the existing script |
| 108 | + scenario, try running error and warning rules included but with a few rules |
| 109 | + "excluded": |
| 110 | + |
| 111 | + PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning |
| 112 | + PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule ` |
| 113 | + PSAvoidUsingCmdletAliases, PSAvoidUsingPositionalParameters |
| 114 | + |
| 115 | + The PSAvoidUsingCmdletAliases and PSAvoidUsingPositionalParameters warnings |
| 116 | + are likely to generate prodigious amounts of output. While these rules have |
| 117 | + their reason for being many existing scripts violate these rules over and |
| 118 | + over again. It would be a shame if you let a flood of warnings from these two |
| 119 | + rules, keep you from addressing more potentially serious warnings. |
| 120 | + |
| 121 | + There may be other rules that generate a lot of output that you don't care |
| 122 | + about - at least not yet. As you examine the remaining diagnostics output, |
| 123 | + it is often helpful to group output by rule. You may decide that the one or |
| 124 | + two rules generating 80% of the output are rules you don't care about. You |
| 125 | + can get this view of your output easily: |
| 126 | + |
| 127 | + PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning |
| 128 | + PS C:\> $res = Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule ` |
| 129 | + PSAvoidUsingPositionalParameters, PSAvoidUsingCmdletAliases |
| 130 | + PS C:\> $res | Group RuleName | Sort Count -Desc | Format-Table Count, Name |
| 131 | + |
| 132 | + This renders output like the following: |
| 133 | + |
| 134 | + Count Name |
| 135 | + ----- ---- |
| 136 | + 23 PSAvoidUsingInvokeExpression |
| 137 | + 8 PSUseDeclaredVarsMoreThanAssigments |
| 138 | + 8 PSProvideDefaultParameterValue |
| 139 | + 6 PSAvoidUninitializedVariable |
| 140 | + 3 PSPossibleIncorrectComparisonWithNull |
| 141 | + 1 PSAvoidUsingComputerNameHardcoded |
| 142 | + |
| 143 | + You may decide to exclude the PSAvoidUsingInvokeExpression rule for the moment |
| 144 | + and focus on the rest, especially the PSUseDeclaredVarsMoreThanAssigments, |
| 145 | + PSAvoidUninitializedVariable and PSPossibleIncorrectComparisonWithNull rules. |
| 146 | + |
| 147 | + As you fix rules, go back and enable more rules as you have time to address |
| 148 | + the associated issues. In some cases, you may want to suppress a rule at |
| 149 | + the function, script or class scope instead of globally excluding the rule. |
| 150 | + See the RULE SUPPRESSION section below. |
| 151 | + |
| 152 | + While getting a completely clean run through every rule is a noble goal, it |
| 153 | + may not always be feasible. You have to weigh the gain of passing the rule |
| 154 | + and eliminating a "potential" issue with changing script and possibly |
| 155 | + introducing a new problem. In the end, for existing scripts, it is usually |
| 156 | + best to have evaluated the rule violations that you deem the most valuable to |
| 157 | + address. |
| 158 | + |
| 159 | +RULE SUPPRESSSION |
| 160 | + |
| 161 | + Rule suppression allows you to turn off rule verification on a function, |
| 162 | + scripts or class definition. This allows you to exclude only specified |
| 163 | + scripts or functions from verification of a rule instead of globally |
| 164 | + excluding the rule. |
| 165 | + |
| 166 | + There are several ways to suppress rules. You can suppress a rule globally |
| 167 | + by using the ExcludeRule parameter when invoking the script analyzer e.g.: |
| 168 | + |
| 169 | + PS C:\> Invoke-ScriptAnalyzer -Path . -ExcludeRule ` |
| 170 | + PSProvideDefaultParameterValue, PSAvoidUsingWMICmdlet |
| 171 | + |
| 172 | + Note that the ExcludeRule parameter takes an array of strings i.e. rule names. |
| 173 | + |
| 174 | + Sometimes you will want to suppress a rule for part of your script but not for |
| 175 | + the entire script. PSScriptAnalyzer allows you to suppress rules at the |
| 176 | + script, function and class scope. You can use the .NET Framework |
| 177 | + System.Diagnoctics.CodeAnalysis.SuppressMesssageAttribute in your script |
| 178 | + like so: |
| 179 | + |
| 180 | + function Commit-Change() { |
| 181 | + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", |
| 182 | + "", Scope="Function", |
| 183 | + Target="*")] |
| 184 | + param() |
| 185 | + } |
| 186 | + |
| 187 | +EXTENSIBILITY |
| 188 | + |
| 189 | + PSScriptAnalyzer has been designed to allow you to create your own rules via |
| 190 | + a custom .NET assembly or PowerShell module. PSScriptAnalyzer also allows |
| 191 | + you to plug in a custom logger (implemented as a .NET assembly). |
| 192 | + |
| 193 | +CONTRIBUTE |
| 194 | + |
| 195 | + PSScriptAnalyzer is open source on GitHub: |
| 196 | + |
| 197 | + https://github.com/PowerShell/PSScriptAnalyzer |
| 198 | + |
| 199 | + As you run the script analyzer and find what you believe to be are bugs, |
| 200 | + please submit them to: |
| 201 | + |
| 202 | + https://github.com/PowerShell/PSScriptAnalyzer/issues |
| 203 | + |
| 204 | + Better yet, fix the bug and submit a pull request. |
| 205 | + |
| 206 | +SEE ALSO |
| 207 | + Get-ScriptAnalyzerRule |
| 208 | + Invoke-ScriptAnalyzer |
| 209 | + Set-StrictMode |
| 210 | + about_Pester |
0 commit comments