Skip to content
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

Backport MSDocs changes #2085

Merged
merged 5 commits into from
Mar 17, 2025
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
4 changes: 2 additions & 2 deletions docs/Cmdlets/Get-ScriptAnalyzerRule.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
external help file: Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml
Module Name: PSScriptAnalyzer
ms.date: 10/07/2021
ms.date: 12/12/2024
online version: https://learn.microsoft.com/powershell/module/psscriptanalyzer/get-scriptanalyzerrule?view=ps-modules&wt.mc_id=ps-gethelp
schema: 2.0.0
---
Expand Down Expand Up @@ -92,7 +92,7 @@ one value, but wildcards are supported. To get rules in subdirectories of the pa
**RecurseCustomRulePath** parameter.

You can create custom rules using a .NET assembly or a PowerShell module, such as the
[Community Analyzer Rules](https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1)
[Community Analyzer Rules](https://github.com/PowerShell/PSScriptAnalyzer/tree/main/Tests/Engine/CommunityAnalyzerRules)
in the GitHub repository.

```yaml
Expand Down
2 changes: 1 addition & 1 deletion docs/Cmdlets/Invoke-ScriptAnalyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ value of the **Profile** parameter is the path to the Script Analyzer profile.
ExcludeRules = '*WriteHost'
}

Invoke-ScriptAnalyzer -Path $pshome\Modules\BitLocker -Profile .\ScriptAnalyzerProfile.txt
Invoke-ScriptAnalyzer -Path $pshome\Modules\BitLocker -Settings .\ScriptAnalyzerProfile.txt
```

If you include a conflicting parameter in the `Invoke-ScriptAnalyzer` command, such as
Expand Down
3 changes: 3 additions & 0 deletions docs/Cmdlets/PSScriptAnalyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ checks the quality of PowerShell code by running a set of rules.
## PSScriptAnalyzer Cmdlets

### [Get-ScriptAnalyzerRule](Get-ScriptAnalyzerRule.md)

Gets the script analyzer rules on the local computer.

### [Invoke-Formatter](Invoke-Formatter.md)

Formats a script text based on the input settings or default settings.

### [Invoke-ScriptAnalyzer](Invoke-ScriptAnalyzer.md)

Evaluates a script or module based on selected best practice rules
5 changes: 5 additions & 0 deletions docs/Rules/AvoidAssignmentToAutomaticVariable.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ only be assigned in certain special cases to achieve a certain effect as a speci

To understand more about automatic variables, see `Get-Help about_Automatic_Variables`.

<!-- TODO
Ability to suppress was added in https://github.com/PowerShell/PSScriptAnalyzer/pull/1896
Need documentation for how to configure suppression of this rule.
-->

Comment on lines +19 to +23
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my original PR I left this out because this comment relates more to work in MSDocs. Maybe a GitHub issue is a better place for it than a comment?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add this information in both repos before release. I couldn't figure out how to configure this. Can you provide an example?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppression is not different that any other rule. For example [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', '')] suppresses the rule and [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidAssignmentToAutomaticVariable', 'PID')] makes the suppression specific to assignment to $PID automatic variable

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you only do this in code? Other rules can be configured using JSON. For example: https://learn.microsoft.com/powershell/utility-modules/psscriptanalyzer/rules/usesingularnouns#configuration

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppression is only possible via annotating code with this attribute unless one decided to not run rule at all via PSSA settings but I wouldn't call that suppression: https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/using-scriptanalyzer?view=ps-modules#suppressing-rules
What you reference is rule configuration as part of PSSA settings, which is not JSON, it's PowerShell's hashtable format: https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/using-scriptanalyzer?view=ps-modules#settings-support-in-scriptanalyzer

## How

Use variable names in functions or their parameters that do not conflict with automatic variables.
Expand Down
30 changes: 26 additions & 4 deletions docs/Rules/AvoidDefaultValueSwitchParameter.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Switch Parameters Should Not Default To True
ms.date: 06/28/2023
ms.date: 12/05/2024
ms.topic: reference
title: AvoidDefaultValueSwitchParameter
---
Expand All @@ -10,11 +10,19 @@ title: AvoidDefaultValueSwitchParameter

## Description

Switch parameters for commands should default to false.
If your parameter takes only `true` and `false`, define the parameter as type `[Switch]`. PowerShell
treats a switch parameter as `true` when it's used with a command. If the parameter isn't included
with the command, PowerShell considers the parameter to be false. Don't define `[Boolean]`
parameters.

You shouldn't define a switch parameter with a default value of `$true` because this isn't the
expected behavior of a switch parameter.

## How

Change the default value of the switch parameter to be false.
Change the default value of the switch parameter to be `$false` or don't provide a default value.
Write the logic of the script to assume that the switch parameter default value is `$false` or not
provided.

## Example

Expand Down Expand Up @@ -48,8 +56,22 @@ function Test-Script
$Param1,

[switch]
$Switch=$False
$Switch
)

begin {
# Ensure that the $Switch is set to false if not provided
if (-not $PSBoundParameters.ContainsKey('Switch')) {
$Switch = $false
}
}
...
}
```

## More information

- [Strongly Encouraged Development Guidelines][01]

<!-- link references -->
[01]: https://learn.microsoft.com/powershell/scripting/developer/cmdlet/strongly-encouraged-development-guidelines#parameters-that-take-true-and-false
1 change: 0 additions & 1 deletion docs/Rules/AvoidGlobalFunctions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ title: AvoidGlobalFunctions
Globally scoped functions override existing functions within the sessions with matching names. This
name collision can cause difficult to debug issues for consumers of modules.


To understand more about scoping, see `Get-Help about_Scopes`.

## How
Expand Down
23 changes: 13 additions & 10 deletions docs/Rules/AvoidOverwritingBuiltInCmdlets.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Avoid overwriting built in cmdlets
ms.date: 06/28/2023
ms.date: 12/12/2024
ms.topic: reference
title: AvoidOverwritingBuiltInCmdlets
---
Expand All @@ -14,7 +14,7 @@ This rule flags cmdlets that are available in a given edition/version of PowerSh
operating system which are overwritten by a function declaration. It works by comparing function
declarations against a set of allowlists that ship with PSScriptAnalyzer. These allowlist files are
used by other PSScriptAnalyzer rules. More information can be found in the documentation for the
[UseCompatibleCmdlets](./UseCompatibleCmdlets.md) rule.
[UseCompatibleCmdlets][01] rule.

## Configuration

Expand All @@ -37,14 +37,17 @@ following your settings file.

The parameter `PowerShellVersion` is a list of allowlists that ship with PSScriptAnalyzer.

**Note**: The default value for `PowerShellVersion` is `core-6.1.0-windows` if PowerShell 6 or
later is installed, and `desktop-5.1.14393.206-windows` if it is not.
> [!NOTE]
> The default value for `PowerShellVersion` is `core-6.1.0-windows` if PowerShell 6 or
> later is installed, and `desktop-5.1.14393.206-windows` if it's not.

Usually, patched versions of PowerShell have the same cmdlet data, therefore only settings of major
and minor versions of PowerShell are supplied. One can also create a custom settings file as well
with the
[New-CommandDataFile.ps1](https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Utils/New-CommandDataFile.ps1)
script and use it by placing the created `JSON` into the `Settings` folder of the `PSScriptAnalyzer`
module installation folder, then the `PowerShellVersion` parameter is just its file name (that can
also be changed if desired). Note that the `core-6.0.2-*` files were removed in PSScriptAnalyzer
1.18 since PowerShell 6.0 reached end of life.
with the [New-CommandDataFile.ps1][02] script and use it by placing the created `JSON` into the
`Settings` folder of the `PSScriptAnalyzer` module installation folder, then the `PowerShellVersion`
parameter is just its filename (that can also be changed if desired). Note that the `core-6.0.2-*`
files were removed in PSScriptAnalyzer 1.18 since PowerShell 6.0 reached end of life.

<!-- link references -->
[01]: ./UseCompatibleCmdlets.md
[02]: https://github.com/PowerShell/PSScriptAnalyzer/blob/main/Utils/New-CommandDataFile.ps1
2 changes: 1 addition & 1 deletion docs/Rules/AvoidUsingCmdletAliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ There are also implicit aliases. When PowerShell cannot find the cmdlet name, it
Every PowerShell author learns the actual command names, but different authors learn and use
different aliases. Aliases can make code difficult to read, understand and impact availability.

Using the full command name makes it eaiser to maintain your scripts in the the future.
Using the full command name makes it easier to maintain your scripts in the the future.

Using the full command names also allows for syntax highlighting in sites and applications like
GitHub and Visual Studio Code.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Avoid Using SecureString With Plain Text
ms.date: 06/28/2023
ms.date: 01/28/2025
ms.topic: reference
title: AvoidUsingConvertToSecureStringWithPlainText
---
Expand Down Expand Up @@ -37,6 +37,4 @@ $EncryptedInput = ConvertTo-SecureString -String $UserInput -AsPlainText -Force

```powershell
$SecureUserInput = Read-Host 'Please enter your secure code' -AsSecureString
$EncryptedInput = ConvertFrom-SecureString -String $SecureUserInput
$SecureString = ConvertTo-SecureString -String $EncryptedInput
```
27 changes: 18 additions & 9 deletions docs/Rules/AvoidUsingWriteHost.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Avoid Using Write-Host
ms.date: 06/28/2023
ms.date: 12/05/2024
ms.topic: reference
title: AvoidUsingWriteHost
---
Expand All @@ -10,10 +10,15 @@ title: AvoidUsingWriteHost

## Description

The use of `Write-Host` is greatly discouraged unless in the use of commands with the `Show` verb.
The `Show` verb explicitly means 'show on the screen, with no other possibilities'.
The primary purpose of the `Write-Host` cmdlet is to produce display-only output in the host. For
example: printing colored text or prompting the user for input when combined with `Read-Host`.
`Write-Host` uses the `ToString()` method to write the output. The particular result depends on the
program that's hosting PowerShell. The output from `Write-Host` isn't sent to the pipeline. To
output data to the pipeline, use `Write-Output` or implicit output.

Commands with the `Show` verb do not have this check applied.
The use of `Write-Host` in a function is discouraged unless the function uses the `Show` verb. The
`Show` verb explicitly means _display information to the user_. This rule doesn't apply to functions
with the `Show` verb.

## How

Expand All @@ -27,22 +32,22 @@ logging or returning one or more objects.
```powershell
function Get-MeaningOfLife
{
...
Write-Host 'Computing the answer to the ultimate question of life, the universe and everything'
...
Write-Host 42
}
```

### Correct

Use `Write-Verbose` for informational messages. The user can decide whether to see the message by
providing the **Verbose** parameter.

```powershell
function Get-MeaningOfLife
{
[CmdletBinding()]Param() # to make it possible to set the VerbosePreference when calling the function
...
[CmdletBinding()]Param() # makes it possible to support Verbose output

Write-Verbose 'Computing the answer to the ultimate question of life, the universe and everything'
...
Write-Output 42
}

Expand All @@ -51,3 +56,7 @@ function Show-Something
Write-Host 'show something on screen'
}
```

## More information

[Write-Host](xref:Microsoft.PowerShell.Utility.Write-Host)
2 changes: 1 addition & 1 deletion docs/Rules/PlaceOpenBrace.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ Enforce a new line character after an open brace. The default value is true.
#### IgnoreOneLineBlock: bool (Default value is `$true`)

Indicates if open braces in a one line block should be ignored or not. For example,
` $x = if ($true) { 'blah' } else { 'blah blah' }`, if the property is set to true then the rule
`$x = if ($true) { 'blah' } else { 'blah blah' }`, if the property is set to true then the rule
doesn't fire a violation.
12 changes: 6 additions & 6 deletions docs/Rules/PossibleIncorrectComparisonWithNull.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Null Comparison
ms.date: 06/28/2023
ms.date: 12/03/2024
ms.topic: reference
title: PossibleIncorrectComparisonWithNull
---
Expand All @@ -18,8 +18,8 @@ There are multiple reasons why this occurs:
- `$null` is a scalar value. When the value on the left side of an operator is a scalar, comparison
operators return a **Boolean** value. When the value is a collection, the comparison operators
return any matching values or an empty array if there are no matches in the collection.
- PowerShell performs type casting left to right, resulting in incorrect comparisons when `$null` is
cast to other scalar types.
- PowerShell performs type casting on the right-hand operand, resulting in incorrect comparisons
when `$null` is cast to other scalar types.

The only way to reliably check if a value is `$null` is to place `$null` on the left side of the
operator so that a scalar comparison is performed.
Expand Down Expand Up @@ -55,10 +55,10 @@ function Test-CompareWithNull
## Try it Yourself

```powershell
# Both expressions below return 'false' because the comparison does not return an
# object and therefore the if statement always falls through:
# This example returns 'false' because the comparison does not return any objects from the array
if (@() -eq $null) { 'true' } else { 'false' }
if (@() -ne $null) { 'true' } else { 'false' }
# This example returns 'true' because the array is empty
if ($null -ne @()) { 'true' } else { 'false' }
```

This is how the comparison operator works by-design. But, as demonstrated, this can lead
Expand Down
2 changes: 1 addition & 1 deletion docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ if ($a = Get-Something) # Only execute action if command returns something and a
}
```

## Implicit suppresion using Clang style
## Implicit suppression using Clang style

There are some rare cases where assignment of variable inside an `if` statement is by design.
Instead of suppressing the rule, one can also signal that assignment was intentional by wrapping the
Expand Down
2 changes: 1 addition & 1 deletion docs/Rules/ProvideCommentHelp.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Rules = @{

### Parameters

- `Enable`: **bool** (Default valus is `$true`)
- `Enable`: **bool** (Default value is `$true`)

Enable or disable the rule during ScriptAnalyzer invocation.

Expand Down
28 changes: 26 additions & 2 deletions docs/Rules/UseBOMForUnicodeEncodedFile.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Use BOM encoding for non-ASCII files
ms.date: 06/28/2023
ms.date: 01/07/2025
ms.topic: reference
title: UseBOMForUnicodeEncodedFile
---
Expand All @@ -13,6 +13,30 @@ title: UseBOMForUnicodeEncodedFile
For a file encoded with a format other than ASCII, ensure Byte Order Mark (BOM) is present to ensure
that any application consuming this file can interpret it correctly.

You can use this rule to test any arbitrary text file, but the intent is to ensure that PowerShell
scripts are saved with a BOM when using a Unicode encoding.

## How

Ensure that the file is encoded with BOM present.
For PowerShell commands that write to files, ensure that you set the encoding parameter to a value
that produces a BOM. In PowerShell 7 and higher, the following values of the **Encoding** parameter
produce a BOM:

- `bigendianunicode`
- `bigendianutf32`
- `oem`
- `unicode`
- `utf32`
- `utf8BOM`

When you create a script file using a text editor, ensure that the editor is configured to save the
file with a BOM. Consult the documentation for your text editor for instructions on how to save
files with a BOM.

## Further reading

For more information, see the following articles:

- [about_Character_Encoding](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_character_encoding)
- [Set-Content](https://learn.microsoft.com/powershell/module/microsoft.powershell.management/set-content)
- [Understanding file encoding in VS Code and PowerShell](https://learn.microsoft.com/powershell/scripting/dev-cross-plat/vscode/understanding-file-encoding)
17 changes: 10 additions & 7 deletions docs/Rules/UseCompatibleCmdlets.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Use compatible cmdlets
ms.date: 06/28/2023
ms.date: 12/12/2024
ms.topic: reference
title: UseCompatibleCmdlets
---
Expand All @@ -10,8 +10,8 @@ title: UseCompatibleCmdlets

## Description

This rule flags cmdlets that are not available in a given Edition/Version of PowerShell on a given
Operating System. It works by comparing a cmdlet against a set of allowlists which ship with
This rule flags cmdlets that aren't available in a given Edition and Version of PowerShell on a
given Operating System. It works by comparing a cmdlet against a set of allowlists which ship with
PSScriptAnalyzer. They can be found at `/path/to/PSScriptAnalyzerModule/Settings`. These files are
of the form, `<psedition>-<psversion>-<os>.json` where `<psedition>` can be either `Core` or
`Desktop`, `<os>` can be either `Windows`, `Linux` or `MacOS`, and `<psversion>` is the PowerShell
Expand Down Expand Up @@ -41,7 +41,10 @@ The parameter `compatibility` is a list that contain any of the following

Usually, patched versions of PowerShell have the same cmdlet data, therefore only settings of major
and minor versions of PowerShell are supplied. You can also create a custom settings file with the
[New-CommandDataFile.ps1](https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Utils/New-CommandDataFile.ps1)
script. Place the created `.json` file in the `Settings` folder of the `PSScriptAnalyzer` module
folder. Then the `compatibility` parameter values is just the filename. Note that the `core-6.0.2-*`
files were removed in PSScriptAnalyzer 1.18 since PowerShell 6.0 reached it's end of life.
[New-CommandDataFile.ps1][01] script. Place the created `.json` file in the `Settings` folder of the
`PSScriptAnalyzer` module folder. Then the `compatibility` parameter values is just the filename.
Note that the `core-6.0.2-*` files were removed in PSScriptAnalyzer 1.18 since PowerShell 6.0
reached it's end of life.

<!-- link references -->
[01]: https://github.com/PowerShell/PSScriptAnalyzer/blob/main/Utils/New-CommandDataFile.ps1
Loading