Skip to content

Added an about help topic file and fixed a typo in rule description #275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Engine/ScriptAnalyzerEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Include="about_PSScriptAnalyzer.help.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSHARP.Targets" />
<ProjectExtensions>
<VisualStudio AllowExistingFolder="true" />
Expand All @@ -99,6 +102,8 @@
<PostBuildEvent>mkdir "$(SolutionDir)$(SolutionName)"
copy /y "$(ProjectDir)\*.ps1xml" "$(SolutionDir)$(SolutionName)"
copy /y "$(ProjectDir)\*.psd1" "$(SolutionDir)$(SolutionName)"
copy /y "$(TargetPath)" "$(SolutionDir)$(SolutionName)"</PostBuildEvent>
copy /y "$(TargetPath)" "$(SolutionDir)$(SolutionName)"
mkdir "$(SolutionDir)$(SolutionName)\en-US"
copy /y "$(ProjectDir)\about_*.help.txt" "$(SolutionDir)$(SolutionName)\en-US"</PostBuildEvent>
</PropertyGroup>
</Project>
210 changes: 210 additions & 0 deletions Engine/about_PSScriptAnalyzer.help.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
TOPIC
about_PSScriptAnalyzer

SHORT DESCRIPTION
PSScriptAnalyzer is a static code checker for PowerShell script.

LONG DESCRIPTION
PSScriptAnalyzer checks the quality of Windows PowerShell script by evaluating
that script against a set of rules. The script can be in the form of a
stand-alone script (.ps1 files), a module (.psm1, .psd1 and .ps1 files) or
a DSC Resource (.psm1, .psd1 and .ps1 files).

The rules are based on PowerShell best practices identified by the
PowerShell Team and the community. These rules can help you create more
readable, maintainable and reliable scripts. PSScriptAnalyzer generates
DiagnosticResults (errors and warnings) to inform you about potential script
issues, including the reason why there might be an issue, and provide you
with guidance on how to fix the issue.

PSScriptAnalyzer is shipped with a collection of built-in rules that check
various aspects of PowerShell code such as presence of uninitialized
variables, usage of the PSCredential Type, usage of Invoke-Expression, etc.

The following additional functionality is also supported:

* Including and/or excluding specific rules globally
* Suppression of rules within script
* Creation of custom rules
* Creation of loggers

RUNNING SCRIPT ANALYZER

There are two commands provided by the PSScriptAnalyzer module, those are:

Get-ScriptAnalyzerRule [-CustomizedRulePath <string[]>] [-Name <string[]>]
[-Severity <string[]>]
[<CommonParameters>]

Invoke-ScriptAnalyzer [-Path] <string> [-CustomizedRulePath <string[]>]
[-ExcludeRule <string[]>] [-IncludeRule<string[]>]
[-Severity <string[]>] [-Recurse] [-SuppressedOnly]
[<CommonParameters>]

To run the script analyzer against a single script file execute:

PS C:\> Invoke-ScriptAnalyzer -Path myscript.ps1

This will analyze your script against every built-in rule. As you may find
if your script is sufficiently large, that could result in a lot of warnings
and/or errors. See the next section on recommendations for running against
an existing script, module or DSC resource.

To run the script analyzer against a whole directory, specify the folder
containing the script, module and DSC files you want analyzed. Specify
the Recurse parameter if you also want sub-directories searched for files
to analyze.

PS C:\> Invoke-ScriptAnalyzer -Path . -Recurse

To see all the built-in rules execute:

PS C:\> Get-ScriptAnalyzerRule

RUNNING SCRIPT ANALYZER ON A NEW SCRIPT, MODULE OR DSC RESOURCE

If you have the luxury of starting a new script, module or DSC resource, it
is in your best interest to run the script analyzer with all the rules
enabled. Be sure to evaluate your script often to address rule violations as
soon as they occur.

Over time, you may find rules that you don't find value in or have a need to
explicitly violate. Suppress those rules as necessary but try to avoid
"knee jerk" suppression of rules. Analyze the diagnostic output and the part
of your script that violates the rule to be sure you understand the reason for
the warning and that it is indeed OK to suppress the rule. For information on
how to suppress rules see the RULE SUPPRESSION section below.

RUNNING SCRIPT ANALYZER ON AN EXISTING SCRIPT, MODULE OR DSC RESOURCE

If you have existing scripts, they are not likely following all of these best
practices, practices that have just found their way into books, web sites,
blog posts and now the PSScriptAnalyer in the past few years.

For these existing scripts, if you just run the script analyzer without
limiting the set of rules executed, you may get deluged with diagnostics
output in the form of information, warning and error messages. You should
try running the script analyzer with all the rules enabled (the default) and
see if the output is "manageable". If it isn't, then you will want to "ease
into" things by starting with the most serious violations first - errors.

You may be temtped to use the Invoke-ScriptAnalyzer command's Severity
parameter with the argument Error to do this - don't. This will run every
built-in rule and then filter the results during output. The more rules the
script analyzer runs, the longer it will take to analyze a file. You can
easily get Invoke-ScriptAnalyzer to run just the rules that are of severity
Error like so:

PS C:\> $errorRules = Get-ScriptAnalyzer -Severity Error
PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $errorRules

The output should be much shorter (hopefully) and more importantly, these rules
typically indicate serious issues in your script that should be addressed.

Once you have addressed the errors in the script, you are ready to tackle
warnings. This is likely what generated the most output when you ran the
first time with all the rules enabled. Now not all of the warnings generated
by the script analyzer are of equal importance. For the existing script
scenario, try running error and warning rules included but with a few rules
"excluded":

PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning
PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule `
PSAvoidUsingCmdletAliases, PSAvoidUsingPositionalParameters

The PSAvoidUsingCmdletAliases and PSAvoidUsingPositionalParameters warnings
are likely to generate prodigious amounts of output. While these rules have
their reason for being many existing scripts violate these rules over and
over again. It would be a shame if you let a flood of warnings from these two
rules, keep you from addressing more potentially serious warnings.

There may be other rules that generate a lot of output that you don't care
about - at least not yet. As you examine the remaining diagnostics output,
it is often helpful to group output by rule. You may decide that the one or
two rules generating 80% of the output are rules you don't care about. You
can get this view of your output easily:

PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning
PS C:\> $res = Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule `
PSAvoidUsingPositionalParameters, PSAvoidUsingCmdletAliases
PS C:\> $res | Group RuleName | Sort Count -Desc | Format-Table Count, Name

This renders output like the following:

Count Name
----- ----
23 PSAvoidUsingInvokeExpression
8 PSUseDeclaredVarsMoreThanAssigments
8 PSProvideDefaultParameterValue
6 PSAvoidUninitializedVariable
3 PSPossibleIncorrectComparisonWithNull
1 PSAvoidUsingComputerNameHardcoded

You may decide to exclude the PSAvoidUsingInvokeExpression rule for the moment
and focus on the rest, especially the PSUseDeclaredVarsMoreThanAssigments,
PSAvoidUninitializedVariable and PSPossibleIncorrectComparisonWithNull rules.

As you fix rules, go back and enable more rules as you have time to address
the associated issues. In some cases, you may want to suppress a rule at
the function, script or class scope instead of globally excluding the rule.
See the RULE SUPPRESSION section below.

While getting a completely clean run through every rule is a noble goal, it
may not always be feasible. You have to weigh the gain of passing the rule
and eliminating a "potential" issue with changing script and possibly
introducing a new problem. In the end, for existing scripts, it is usually
best to have evaluated the rule violations that you deem the most valuable to
address.

RULE SUPPRESSSION

Rule suppression allows you to turn off rule verification on a function,
scripts or class definition. This allows you to exclude only specified
scripts or functions from verification of a rule instead of globally
excluding the rule.

There are several ways to suppress rules. You can suppress a rule globally
by using the ExcludeRule parameter when invoking the script analyzer e.g.:

PS C:\> Invoke-ScriptAnalyzer -Path . -ExcludeRule `
PSProvideDefaultParameterValue, PSAvoidUsingWMICmdlet

Note that the ExcludeRule parameter takes an array of strings i.e. rule names.

Sometimes you will want to suppress a rule for part of your script but not for
the entire script. PSScriptAnalyzer allows you to suppress rules at the
script, function and class scope. You can use the .NET Framework
System.Diagnoctics.CodeAnalysis.SuppressMesssageAttribute in your script
like so:

function Commit-Change() {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs",
"", Scope="Function",
Target="*")]
param()
}

EXTENSIBILITY

PSScriptAnalyzer has been designed to allow you to create your own rules via
a custom .NET assembly or PowerShell module. PSScriptAnalyzer also allows
you to plug in a custom logger (implemented as a .NET assembly).

CONTRIBUTE

PSScriptAnalyzer is open source on GitHub:

https://github.com/PowerShell/PSScriptAnalyzer

As you run the script analyzer and find what you believe to be are bugs,
please submit them to:

https://github.com/PowerShell/PSScriptAnalyzer/issues

Better yet, fix the bug and submit a pull request.

SEE ALSO
Get-ScriptAnalyzerRule
Invoke-ScriptAnalyzer
Set-StrictMode
about_Pester
2 changes: 1 addition & 1 deletion Rules/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Rules/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@
<value>Avoid Using Get-WMIObject, Remove-WMIObject, Invoke-WmiMethod, Register-WmiEvent, Set-WmiInstance</value>
</data>
<data name="AvoidUsingWMICmdletDescription" xml:space="preserve">
<value>Depricated. Starting in Windows PowerShell 3.0, these cmdlets have been superseded by CIM cmdlets.</value>
<value>Deprecated. Starting in Windows PowerShell 3.0, these cmdlets have been superseded by CIM cmdlets.</value>
</data>
<data name="AvoidUsingWMICmdletError" xml:space="preserve">
<value>File '{0}' uses WMI cmdlet. For PowerShell 3.0 and above, use CIM cmdlet which perform the same tasks as the WMI cmdlets. The CIM cmdlets comply with WS-Management (WSMan) standards and with the Common Information Model (CIM) standard, which enables the cmdlets to use the same techniques to manage Windows computers and those running other operating systems.</value>
Expand Down