From 54055c0bb37fe63eb21af9d60c8a118f35f49b42 Mon Sep 17 00:00:00 2001 From: sdwheeler <19415881+sdwheeler@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:06:34 -0500 Subject: [PATCH 1/3] Sync docs updates to source repo --- docs/Rules/AlignAssignmentStatement.md | 101 +++--- .../AvoidAssignmentToAutomaticVariable.md | 24 +- .../AvoidDefaultValueForMandatoryParameter.md | 13 +- .../Rules/AvoidDefaultValueSwitchParameter.md | 33 +- docs/Rules/AvoidExclaimOperator.md | 33 +- docs/Rules/AvoidGlobalAliases.md | 26 +- docs/Rules/AvoidGlobalFunctions.md | 20 +- docs/Rules/AvoidGlobalVars.md | 53 +-- docs/Rules/AvoidInvokingEmptyMembers.md | 21 +- docs/Rules/AvoidLongLines.md | 36 +- docs/Rules/AvoidMultipleTypeAttributes.md | 18 +- .../AvoidNullOrEmptyHelpMessageAttribute.md | 21 +- docs/Rules/AvoidOverwritingBuiltInCmdlets.md | 80 +++-- .../AvoidReservedWordsAsFunctionNames.md | 16 +- .../Rules/AvoidSemicolonsAsLineTerminators.md | 26 +- docs/Rules/AvoidShouldContinueWithoutForce.md | 25 +- docs/Rules/AvoidTrailingWhitespace.md | 47 ++- ...voidUsingAllowUnencryptedAuthentication.md | 25 +- docs/Rules/AvoidUsingBrokenHashAlgorithms.md | 33 +- docs/Rules/AvoidUsingCmdletAliases.md | 59 ++-- docs/Rules/AvoidUsingComputerNameHardcoded.md | 43 +-- ...UsingConvertToSecureStringWithPlainText.md | 27 +- .../AvoidUsingDeprecatedManifestFields.md | 20 +- ...AvoidUsingDoubleQuotesForConstantString.md | 27 +- docs/Rules/AvoidUsingEmptyCatchBlock.md | 18 +- docs/Rules/AvoidUsingInvokeExpression.md | 22 +- docs/Rules/AvoidUsingPlainTextForPassword.md | 27 +- docs/Rules/AvoidUsingPositionalParameters.md | 66 ++-- .../AvoidUsingUsernameAndPasswordParams.md | 17 +- docs/Rules/AvoidUsingWMICmdlet.md | 32 +- docs/Rules/AvoidUsingWriteHost.md | 44 ++- docs/Rules/DSCDscExamplesPresent.md | 24 +- docs/Rules/DSCDscTestsPresent.md | 27 +- .../DSCReturnCorrectTypesForDSCFunctions.md | 34 +- .../DSCStandardDSCFunctionsInResource.md | 31 +- ...SCUseIdenticalMandatoryParametersForDSC.md | 27 +- docs/Rules/DSCUseIdenticalParametersForDSC.md | 18 +- .../DSCUseVerboseMessageInDSCResource.md | 21 +- docs/Rules/MisleadingBacktick.md | 26 +- docs/Rules/MissingModuleManifestField.md | 26 +- docs/Rules/PlaceCloseBrace.md | 56 ++- docs/Rules/PlaceOpenBrace.md | 53 ++- .../PossibleIncorrectComparisonWithNull.md | 71 ++-- ...sibleIncorrectUsageOfAssignmentOperator.md | 56 +-- ...ibleIncorrectUsageOfRedirectionOperator.md | 20 +- docs/Rules/ProvideCommentHelp.md | 119 ++++--- docs/Rules/README.md | 265 +++++++++----- docs/Rules/ReservedCmdletChar.md | 44 ++- docs/Rules/ReservedParams.md | 20 +- docs/Rules/ReviewUnusedParameter.md | 55 ++- docs/Rules/ShouldProcess.md | 30 +- docs/Rules/UseApprovedVerbs.md | 33 +- docs/Rules/UseBOMForUnicodeEncodedFile.md | 42 ++- docs/Rules/UseCmdletCorrectly.md | 17 +- docs/Rules/UseCompatibleCmdlets.md | 51 ++- docs/Rules/UseCompatibleCommands.md | 111 ++++-- docs/Rules/UseCompatibleSyntax.md | 50 ++- docs/Rules/UseCompatibleTypes.md | 113 ++++-- docs/Rules/UseConsistentIndentation.md | 78 +++-- docs/Rules/UseConsistentParameterSetName.md | 55 ++- docs/Rules/UseConsistentParametersKind.md | 53 +-- docs/Rules/UseConsistentWhitespace.md | 100 ++++-- docs/Rules/UseConstrainedLanguageMode.md | 329 ++++++------------ docs/Rules/UseCorrectCasing.md | 83 +++-- .../UseDeclaredVarsMoreThanAssignments.md | 28 +- .../UseLiteralInitializerForHashtable.md | 28 +- docs/Rules/UseOutputTypeCorrectly.md | 24 +- docs/Rules/UsePSCredentialType.md | 18 +- .../UseProcessBlockForPipelineCommand.md | 34 +- ...eShouldProcessForStateChangingFunctions.md | 36 +- .../UseSingleValueFromPipelineParameter.md | 35 +- docs/Rules/UseSingularNouns.md | 68 ++-- docs/Rules/UseSupportsShouldProcess.md | 18 +- docs/Rules/UseToExportFieldsInManifest.md | 44 +-- docs/Rules/UseUTF8EncodingForHelpFile.md | 52 ++- .../UseUsingScopeModifierInNewRunspaces.md | 55 +-- 76 files changed, 1926 insertions(+), 1705 deletions(-) diff --git a/docs/Rules/AlignAssignmentStatement.md b/docs/Rules/AlignAssignmentStatement.md index 573b54b68..c12847e86 100644 --- a/docs/Rules/AlignAssignmentStatement.md +++ b/docs/Rules/AlignAssignmentStatement.md @@ -1,6 +1,6 @@ --- description: Align assignment statement -ms.date: 03/20/2026 +ms.date: 06/12/2026 ms.topic: reference title: AlignAssignmentStatement --- @@ -10,13 +10,20 @@ title: AlignAssignmentStatement ## Description -Consecutive assignment statements are more readable when they're aligned. Assignments are considered -aligned when their `equals` signs line up vertically. +This rule detects misaligned assignment operators in hashtables and enum definitions. Consecutive +assignment statements are easier to read and maintain when their assignment operators align +vertically. -This rule looks at the key-value pairs in hashtables (including DSC configurations) as well as enum +This rule checks key-value pairs in hashtables and enum member definitions to ensure that the `=` +signs line up. Use this rule to enforce consistent formatting in multiline hashtables and enum definitions. -Consider the following example with a hashtable and enum that isn't aligned. +The rule ignores assignments within hashtables and enums that appear on the same line as other +assignments. For example, the rule ignores `$h = @{ a = 1; b = 2 }`. + +## Example + +### Noncompliant ```powershell $hashtable = @{ @@ -30,7 +37,7 @@ enum Enum { } ``` -Alignment in this case would look like the following. +### Compliant ```powershell $hashtable = @{ @@ -44,9 +51,6 @@ enum Enum { } ``` -The rule ignores any assignments within hashtables and enums which are on the same line as others. -For example, the rule ignores `$h = @{a = 1; b = 2}`. - ## Configuration ```powershell @@ -62,22 +66,24 @@ Rules = @{ } ``` -### Parameters +## Parameters -#### Enable: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -#### CheckHashtable: bool (Default value is `$true`) +### CheckHashtable -Enforce alignment of assignment statements in a hashtable and in a DSC Configuration. There is only -one setting for hashtable and DSC configuration because the property value pairs in a DSC -configuration are parsed as key-value pairs of a hashtable. +This parameter controls whether ScriptAnalyzer checks assignment alignment in hashtables and Desired +State Configuration (DSC) configurations. It accepts a boolean value. To disable this check, set +this parameter to `$false`. The default value is `$true`. -#### AlignHashtableKvpWithInterveningComment: bool (Default value is `$true`) +### AlignHashtableKvpWithInterveningComment -Include key-value pairs in the alignment that have an intervening comment - that is to say a comment -between the key name and the equals sign. +This parameter controls whether ScriptAnalyzer includes hashtable key-value pairs that contain an +intervening comment when determining alignment. It accepts a boolean value. To exclude these lines, +set this parameter to `$false`. The default value is `$true`. Consider the following: @@ -89,7 +95,8 @@ $hashtable = @{ } ``` -With this setting disabled, the line with the comment is ignored, and it would be aligned like so: +With this setting disabled, the line with the comment is ignored. The equal signs are aligned for +the remaining lines: ```powershell $hashtable = @{ @@ -99,7 +106,7 @@ $hashtable = @{ } ``` -With it enabled, the comment line is included in alignment: +With this setting enabled, the equal signs are aligned for all lines: ```powershell $hashtable = @{ @@ -109,49 +116,23 @@ $hashtable = @{ } ``` -#### CheckEnum: bool (Default value is `$true`) - -Enforce alignment of assignment statements of an Enum definition. - -#### AlignEnumMemberWithInterveningComment: bool (Default value is `$true`) - -Include enum members in the alignment that have an intervening comment - that is to say a comment -between the member name and the equals sign. - -Consider the following: - -```powershell -enum Enum { - member = 1 - anotherMember <#A Comment#> = 2 - anotherDifferentMember = 3 -} -``` - -With this setting disabled, the line with the comment is ignored, and it would be aligned like so: +### CheckEnum -```powershell -enum Enum { - member = 1 - anotherMember <#A Comment#> = 2 - anotherDifferentMember = 3 -} -``` +This parameter controls whether ScriptAnalyzer checks assignment alignment in enum member +definitions. It accepts a boolean value. To disable this check, set this parameter to `$false`. The +default value is `$true`. -With it enabled, the comment line is included in alignment: +### AlignEnumMemberWithInterveningComment -```powershell -enum Enum { - member = 1 - anotherMember <#A Comment#> = 2 - anotherDifferentMember = 3 -} -``` +This parameter controls whether ScriptAnalyzer includes enum members that contain an intervening +comment when determining alignment. It accepts a boolean value. To exclude these lines, set this +parameter to `$false`. The default value is `$true`. -#### IncludeValuelessEnumMembers: bool (Default value is `$true`) +### IncludeValuelessEnumMembers -Include enum members in the alignment that don't have an explicitly assigned value. Enums don't -need to be given a value when they're defined. +This parameter controls whether ScriptAnalyzer includes enum members without explicitly assigned +values when determining alignment. It accepts a boolean value. To exclude valueless members, set +this parameter to `$false`. The default value is `$true`. Consider the following: @@ -164,7 +145,7 @@ enum Enum { ``` With this setting disabled, the third line, which has no value, isn't considered when choosing where -to align assignments. It would be aligned like so: +to align assignments. ```powershell enum Enum { diff --git a/docs/Rules/AvoidAssignmentToAutomaticVariable.md b/docs/Rules/AvoidAssignmentToAutomaticVariable.md index 60d520d07..0d83b261a 100644 --- a/docs/Rules/AvoidAssignmentToAutomaticVariable.md +++ b/docs/Rules/AvoidAssignmentToAutomaticVariable.md @@ -1,6 +1,6 @@ --- description: Changing automatic variables might have undesired side effects -ms.date: 06/28/2023 +ms.date: 06/12/2026 ms.topic: reference title: AvoidAssignmentToAutomaticVariable --- @@ -10,11 +10,15 @@ title: AvoidAssignmentToAutomaticVariable ## Description -PowerShell has built-in variables known as automatic variables. Many of them are read-only and -PowerShell throws an error when trying to assign an value on those. Other automatic variables should -only be assigned in certain special cases to achieve a certain effect as a special technique. +This rule detects assignments to automatic variables and parameter names that use automatic variable +names. PowerShell automatically defines variables that store internal state information and manages +them on its own. Even though you _can_ override many automatic variables, doing so can have +unexpected effects for users and make your code harder to maintain and debug. -To understand more about automatic variables, see `Get-Help about_Automatic_Variables`. +Avoid using automatic variable names in your functions and parameters. Reserve automatic variables +for PowerShell's internal use only, and rely on them only to read state information. + +To learn more, see [about_Automatic_Variables][01]. + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables diff --git a/docs/Rules/AvoidDefaultValueForMandatoryParameter.md b/docs/Rules/AvoidDefaultValueForMandatoryParameter.md index 19c9aa732..a43791fa7 100644 --- a/docs/Rules/AvoidDefaultValueForMandatoryParameter.md +++ b/docs/Rules/AvoidDefaultValueForMandatoryParameter.md @@ -1,6 +1,6 @@ --- description: Avoid Default Value For Mandatory Parameter -ms.date: 06/28/2023 +ms.date: 06/12/2026 ms.topic: reference title: AvoidDefaultValueForMandatoryParameter --- @@ -10,13 +10,14 @@ title: AvoidDefaultValueForMandatoryParameter ## Description -Mandatory parameters should not have a default values because there is no scenario where the default -can be used. PowerShell prompts for a value if the parameter value is not specified when calling the -function. +This rule detects when mandatory parameters have default values assigned. Mandatory parameters +shouldn't have default values because they can't be used. When a parameter is marked as mandatory, +PowerShell always prompts the user for a value if one isn't supplied when calling the function. Any +default value assigned to a mandatory parameter is unreachable and serves no purpose. ## Example -### Wrong +### Noncompliant ```powershell function Test @@ -31,7 +32,7 @@ function Test } ``` -### Correct +### Compliant ```powershell function Test diff --git a/docs/Rules/AvoidDefaultValueSwitchParameter.md b/docs/Rules/AvoidDefaultValueSwitchParameter.md index 9cc1ba855..311724af1 100644 --- a/docs/Rules/AvoidDefaultValueSwitchParameter.md +++ b/docs/Rules/AvoidDefaultValueSwitchParameter.md @@ -1,6 +1,6 @@ --- -description: Switch Parameters Should Not Default To True -ms.date: 12/05/2024 +description: Switch parameters should not default to $true +ms.date: 06/12/2026 ms.topic: reference title: AvoidDefaultValueSwitchParameter --- @@ -10,23 +10,24 @@ title: AvoidDefaultValueSwitchParameter ## Description -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. +This rule detects switch parameters that are assigned a default value of `$true`. Switch parameters +shouldn't have default values. By design, a switch parameter is `$false` when not specified and +`$true` when included in the command. Assigning a default value of `$true` to a switch parameter +violates this design principle and can cause unexpected behavior. -You shouldn't define a switch parameter with a default value of `$true` because this isn't the -expected behavior of a switch parameter. +If your parameter needs to accept only `true` and `false` values, use the `[Switch]` type instead of +`[Boolean]`. PowerShell automatically handles switch parameters correctly without requiring a +default value. -## How +To fix this issue, remove the default value from the switch parameter declaration. The switch +naturally defaults to `$false` when not specified, allowing your logic to respond appropriately to +the caller's input. -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. +To learn more, see [Strongly Encouraged Development Guidelines][01]. ## Example -### Wrong +### Noncompliant ```powershell function Test-Script @@ -44,7 +45,7 @@ function Test-Script } ``` -### Correct +### Compliant ```powershell function Test-Script @@ -69,9 +70,5 @@ function Test-Script } ``` -## More information - -- [Strongly Encouraged Development Guidelines][01] - [01]: https://learn.microsoft.com/powershell/scripting/developer/cmdlet/strongly-encouraged-development-guidelines#parameters-that-take-true-and-false diff --git a/docs/Rules/AvoidExclaimOperator.md b/docs/Rules/AvoidExclaimOperator.md index 11d078d6b..939ee7622 100644 --- a/docs/Rules/AvoidExclaimOperator.md +++ b/docs/Rules/AvoidExclaimOperator.md @@ -1,6 +1,6 @@ --- description: Avoid exclaim operator -ms.date: 03/26/2024 +ms.date: 05/28/2026 ms.topic: reference title: AvoidExclaimOperator --- @@ -10,39 +10,32 @@ title: AvoidExclaimOperator ## Description -Avoid using the negation operator (`!`). Use `-not` for improved readability. +This rule detects the use of the negation operator (an exclamation mark, `!`) and recommends using +the `-not` operator instead for improved readability and consistency with PowerShell conventions. -> [!NOTE] -> This rule is not enabled by default. The user needs to enable it through settings. +The `-not` operator is more explicit and aligns with PowerShell's verbose style, making code +easier to understand at a glance. -## How to Fix +This rule is **disabled** by default. Enable it explicitly during ScriptAnalyzer invocation if +desired. ## Example -### Wrong +### Noncompliant ```powershell $MyVar = !$true ``` -### Correct +### Compliant ```powershell $MyVar = -not $true ``` -## Configuration +## Parameters -```powershell -Rules = @{ - PSAvoidExclaimOperator = @{ - Enable = $true - } -} -``` - -### Parameters - -- `Enable`: **bool** (Default value is `$false`) +### Enable - Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. diff --git a/docs/Rules/AvoidGlobalAliases.md b/docs/Rules/AvoidGlobalAliases.md index 5157ec6f1..46d43506a 100644 --- a/docs/Rules/AvoidGlobalAliases.md +++ b/docs/Rules/AvoidGlobalAliases.md @@ -1,6 +1,6 @@ --- description: Avoid global aliases. -ms.date: 06/28/2023 +ms.date: 05/28/2026 ms.topic: reference title: AvoidGlobalAliases --- @@ -10,28 +10,28 @@ title: AvoidGlobalAliases ## Description -Globally scoped aliases override existing aliases within the sessions with matching names. This name -collision can cause difficult to debug issues for consumers of modules and scripts. +This rule detects the use of the `New-Alias` command to create aliases in the global scope. Global +aliases can unintentionally override existing aliases in the session, leading to unexpected behavior +and name collisions. Name collisions make it difficult for module consumers to diagnose issues and +maintain code reliability. -To understand more about scoping, see `Get-Help about_Scopes`. - -**NOTE** This rule is not available in PowerShell version 3 or 4 because it uses the -`StaticParameterBinder.BindCommand` API. - -## How - -Use other scope modifiers for new aliases. +To avoid this issue, define aliases without the **Scope** parameter, or use other appropriate scope +modifiers. To learn more, see [about_Scopes][01]. ## Example -### Wrong +### Noncompliant ```powershell New-Alias -Name Name -Value Value -Scope Global ``` -### Correct +### Compliant ```powershell New-Alias -Name Name1 -Value Value ``` + + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes diff --git a/docs/Rules/AvoidGlobalFunctions.md b/docs/Rules/AvoidGlobalFunctions.md index 929466cb6..b9e24c7c0 100644 --- a/docs/Rules/AvoidGlobalFunctions.md +++ b/docs/Rules/AvoidGlobalFunctions.md @@ -10,25 +10,27 @@ title: AvoidGlobalFunctions ## Description -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. +This rule detects function definitions that use the `global:` scope modifier on the function name to +define a function in the global scope. Global functions can unintentionally override existing +functions in the session, leading to unexpected behavior and name collisions. Name collisions make +it difficult for module consumers to diagnose issues and maintain code reliability. -To understand more about scoping, see `Get-Help about_Scopes`. - -## How - -Use other scope modifiers for functions. +To avoid this issue, define functions without the global scope modifier, or use other appropriate +scope modifiers. To learn more, see [about_Scopes][01]. ## Example -### Wrong +### Noncompliant ```powershell function global:functionName {} ``` -### Correct +### Compliant ```powershell function functionName {} ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes diff --git a/docs/Rules/AvoidGlobalVars.md b/docs/Rules/AvoidGlobalVars.md index 7fa0f6d2f..a8c55e729 100644 --- a/docs/Rules/AvoidGlobalVars.md +++ b/docs/Rules/AvoidGlobalVars.md @@ -1,6 +1,6 @@ --- -description: No Global Variables -ms.date: 06/28/2023 +description: Avoid global variables. +ms.date: 06/23/2026 ms.topic: reference title: AvoidGlobalVars --- @@ -10,40 +10,53 @@ title: AvoidGlobalVars ## Description -A variable is a unit of memory in which values are stored. PowerShell controls access to variables, -functions, aliases, and drives through a mechanism known as scoping. Variables and functions that -are present when PowerShell starts have been created in the global scope. +You should avoid modifying global variables in your scripts and functions because other scripts or +functions that run in the same session can depend on them. This can lead to unexpected behavior and +make it difficult to debug your code. -Globally scoped variables include: +This rule detects usage of variables with the global scope modifier. PowerShell controls access to +variables, functions, aliases, and drives through a mechanism known as scoping. Variables and +functions that are present when PowerShell starts were created in the global scope. Globally scoped +variables include: - Automatic variables - Preference variables -- Variables, aliases, and functions that are in your PowerShell profiles -To understand more about scoping, see `Get-Help about_Scopes`. +This rule doesn't detect use of the `New-Variable` cmdlet to create variables in the global scope or +the other `*-Variable` cmdlets to work with variables in the global scope. It only detects variable +expressions with the global scope modifier, like `$global:example`. -## How +This rule doesn't apply to variable expressions that use the global scope modifier where the +variable name is for an [automatic variable][01] or a [preference variable][02]. -Use other scope modifiers for variables. +Use local or script scope for variables instead of the global scope. To learn more, see +[about_Scopes][03]. ## Example -### Wrong +### Noncompliant ```powershell -$Global:var1 = $null -function Test-NotGlobal ($var) -{ - $a = $var + $var1 +$var1 = 'foo' +function Test-NotGlobal ($var) { + $Global:var1 = $var } +Test-NotGlobal 'bar' +$var1 ``` -### Correct +### Compliant ```powershell -$var1 = $null -function Test-NotGlobal ($var1, $var2) -{ - $a = $var1 + $var2 +$var1 = 'foo' +function Test-NotGlobal ($var) { + $var1 = $var } +Test-NotGlobal 'bar' +$var1 ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_preference_variables +[03]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes diff --git a/docs/Rules/AvoidInvokingEmptyMembers.md b/docs/Rules/AvoidInvokingEmptyMembers.md index 6049e869b..802df72b1 100644 --- a/docs/Rules/AvoidInvokingEmptyMembers.md +++ b/docs/Rules/AvoidInvokingEmptyMembers.md @@ -1,6 +1,6 @@ --- -description: Avoid Invoking Empty Members -ms.date: 06/28/2023 +description: Avoid invoking empty members. +ms.date: 05/28/2026 ms.topic: reference title: AvoidInvokingEmptyMembers --- @@ -10,25 +10,28 @@ title: AvoidInvokingEmptyMembers ## Description -Invoking non-constant members can cause potential bugs. Please double check the syntax to make sure -that invoked members are constants. +This rule detects expressions where the code uses the [member-access operator][01] (`.`) where the +member name is dynamically constructed. Invoking dynamically constructed member names can introduce +unexpected behavior and runtime errors. Ensure that member invocations use constant, literal member +names rather than expressions that are evaluated at runtime. -## How - -Provide the requested members for a given type or class. +Replace dynamic member name expressions with constant member names for the target type or class. ## Example -### Wrong +### Noncompliant ```powershell $MyString = 'abc' $MyString.('len'+'gth') ``` -### Correct +### Compliant ```powershell $MyString = 'abc' $MyString.('length') ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_operators#member-access-operator- diff --git a/docs/Rules/AvoidLongLines.md b/docs/Rules/AvoidLongLines.md index 89474c8b8..6df5f194d 100644 --- a/docs/Rules/AvoidLongLines.md +++ b/docs/Rules/AvoidLongLines.md @@ -1,6 +1,6 @@ --- description: Avoid long lines -ms.date: 03/20/2026 +ms.date: 06/01/2026 ms.topic: reference title: AvoidLongLines --- @@ -10,13 +10,27 @@ title: AvoidLongLines ## Description -The length of lines, including leading spaces (indentation), should be less than the configured -number of characters. The default length is 120 characters. +This rule detects lines that exceed the configured maximum length, including leading spaces +(indentation). The default maximum line length is 120 characters. This rule is **disabled** by +default and must be explicitly enabled through rule configuration settings. -> [!NOTE] -> This rule isn't enabled by default. The user needs to enable it through settings. +## Example -## Configuration +### Noncompliant + +``` +In this example of sample text, the maximum line length is using the default setting of not exceeding more than 120 +characters. +``` + +### Compliant + +``` +In this example of sample text, the maximum line length is set to not exceed +more than 80 characters. +``` + +## Configure rule ```powershell Rules = @{ @@ -29,10 +43,12 @@ Rules = @{ ## Parameters -### `Enable`: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -### `MaximumLineLength`: int (Default value is 120) +### MaximumLineLength -Optional parameter to override the default maximum line length. +This parameter is optional and defines the maximum length for a line before it violates the rule. It +accepts an integer value. The default value is `120`. diff --git a/docs/Rules/AvoidMultipleTypeAttributes.md b/docs/Rules/AvoidMultipleTypeAttributes.md index 9ccd478c5..d4fd2fdac 100644 --- a/docs/Rules/AvoidMultipleTypeAttributes.md +++ b/docs/Rules/AvoidMultipleTypeAttributes.md @@ -1,6 +1,6 @@ --- -description: Avoid multiple type specifiers on parameters. -ms.date: 06/28/2023 +description: Avoid multiple type specifiers on parameters +ms.date: 06/01/2026 ms.topic: reference title: AvoidMultipleTypeAttributes --- @@ -10,16 +10,16 @@ title: AvoidMultipleTypeAttributes ## Description -Parameters should not have more than one type specifier. Multiple type specifiers on parameters -can cause runtime errors. +This rule detects parameters that have multiple type specifiers applied to them. Parameters +shouldn't have multiple type specifiers. When you apply more than one type attribute to a parameter, +it can lead to unexpected type coercion or runtime errors. -## How - -Ensure each parameter has only 1 type specifier. +Each parameter should have exactly one type specifier to ensure predictable behavior and type +safety. ## Example -### Wrong +### Noncompliant ```powershell function Test-Script @@ -34,7 +34,7 @@ function Test-Script } ``` -### Correct +### Compliant ```powershell function Test-Script diff --git a/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md b/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md index 386c96050..f1b9beea2 100644 --- a/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md +++ b/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md @@ -1,6 +1,6 @@ --- -description: Avoid using null or empty HelpMessage parameter attribute. -ms.date: 06/28/2023 +description: Avoid using null or empty HelpMessage parameter attribute +ms.date: 06/01/2026 ms.topic: reference title: AvoidNullOrEmptyHelpMessageAttribute --- @@ -10,16 +10,16 @@ title: AvoidNullOrEmptyHelpMessageAttribute ## Description -The value of the `HelpMessage` attribute should not be an empty string or a null value as this -causes PowerShell's interpreter to throw an error when executing the function or cmdlet. +This rule detects [HelpMessage][01] attributes that contain null values, empty strings, or no value +assignment. The `HelpMessage` attribute must contain a meaningful, non-empty string value. Omitting +the value altogether causes a parse-time syntax error. -## How - -Specify a value for the `HelpMessage` attribute. +Using an empty string or null value causes PowerShell to raise an error at runtime. Always provide a +descriptive help message that explains the parameter's purpose and expected input to users. ## Example -### Wrong +### Noncompliant ```powershell Function BadFuncEmptyHelpMessageEmpty @@ -56,7 +56,7 @@ Function BadFuncEmptyHelpMessageNoAssignment } ``` -### Correct +### Compliant ```powershell Function GoodFuncHelpMessage @@ -70,3 +70,6 @@ Function GoodFuncHelpMessage $Param } ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters#helpmessage-argument diff --git a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md index 10e1ad30a..a60ef410d 100644 --- a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md +++ b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md @@ -1,6 +1,6 @@ --- -description: Avoid overwriting built in cmdlets -ms.date: 12/12/2024 +description: Avoid overwriting built-in cmdlets +ms.date: 06/01/2026 ms.topic: reference title: AvoidOverwritingBuiltInCmdlets --- @@ -10,44 +10,78 @@ title: AvoidOverwritingBuiltInCmdlets ## Description -This rule flags cmdlets that are available in a given edition/version of PowerShell on a given -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][01] rule. +This rule detects and warns when a script defines a function that uses the name of a built-in cmdlet +available for a target PowerShell version and operating system. Overwriting built-in cmdlet names +can cause confusing behavior because callers might run your function when they expected the platform +cmdlet. -## Configuration +The rule compares function declarations in your script against command allow lists that ship with +PSScriptAnalyzer. The allow lists are also used by other compatibility rules. To learn more, see +[UseCompatibleCmdlets][01]. -To enable the rule to check if your script is compatible on PowerShell Core on Windows, put the -following your settings file. +## Example + +### Noncompliant + +```powershell +function Get-ChildItem { + param( + [string]$Path = '.' + ) + + "Custom listing for: $Path" +} +``` + +### Compliant + +```powershell +function Get-CustomChildItem { + param( + [string]$Path = '.' + ) + + "Custom listing for: $Path" +} +``` + +## Configure rule + +To enable the rule to check if your script is compatible on PowerShell Core on Windows, add the +following lines in your settings file. ```powershell @{ 'Rules' = @{ 'PSAvoidOverwritingBuiltInCmdlets' = @{ - 'PowerShellVersion' = @('core-6.1.0-windows') + 'PowerShellVersion' = @('core-7.0.0-windows') } } } ``` -### Parameters +## Parameters -#### PowerShellVersion +### PowerShellVersion -The parameter `PowerShellVersion` is a list of allowlists that ship with PSScriptAnalyzer. +The `PowerShellVersion` parameter accepts one or more command allow list names that ship with +PSScriptAnalyzer. Set this value to the PowerShell version and platform you want to validate +against. > [!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. +> The default value for `PowerShellVersion` is `core-7.0.0-windows` if PowerShell 7 or later is +installed, and `desktop-5.1.17763.316-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][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. +Patched PowerShell releases usually share the same cmdlet metadata, so the built-in allow lists are +provided by major and minor version. You can also generate a custom allow list with +[New-CommandDataFile.ps1][02]. To use a custom allow list, place the generated JSON file in the +`Settings` folder of the PSScriptAnalyzer module installation path, then set `PowerShellVersion` to +that filename. + +The `core-6.0.2-*` files were removed in PSScriptAnalyzer 1.18 because PowerShell 6.0 reached end of +life. -[01]: ./UseCompatibleCmdlets.md + +[01]: UseCompatibleCmdlets.md [02]: https://github.com/PowerShell/PSScriptAnalyzer/blob/main/Utils/New-CommandDataFile.ps1 diff --git a/docs/Rules/AvoidReservedWordsAsFunctionNames.md b/docs/Rules/AvoidReservedWordsAsFunctionNames.md index 769cbb85f..22efa7a1a 100644 --- a/docs/Rules/AvoidReservedWordsAsFunctionNames.md +++ b/docs/Rules/AvoidReservedWordsAsFunctionNames.md @@ -1,6 +1,6 @@ --- description: Avoid reserved words as function names -ms.date: 08/31/2025 +ms.date: 06/01/2026 ms.topic: reference title: AvoidReservedWordsAsFunctionNames --- @@ -10,19 +10,15 @@ title: AvoidReservedWordsAsFunctionNames ## Description -Avoid using reserved words as function names. Using reserved words as function names can cause -errors or unexpected behavior in scripts. - -## How to Fix - -Avoid using any of the reserved words as function names. Choose a different name that's not a -reserved word. +This rule detects function names that use PowerShell reserved words. Using reserved words as +function names causes errors or unexpected behavior in PowerShell scripts. Choose function names +that don't conflict with any PowerShell reserved words. See [about_Reserved_Words][01] for a list of reserved words in PowerShell. ## Example -### Wrong +### Noncompliant ```powershell # Function is a reserved word @@ -31,7 +27,7 @@ function function { } ``` -### Correct +### Compliant ```powershell # myFunction is not a reserved word diff --git a/docs/Rules/AvoidSemicolonsAsLineTerminators.md b/docs/Rules/AvoidSemicolonsAsLineTerminators.md index 4716238ce..e9d757fe6 100644 --- a/docs/Rules/AvoidSemicolonsAsLineTerminators.md +++ b/docs/Rules/AvoidSemicolonsAsLineTerminators.md @@ -1,6 +1,6 @@ --- description: Avoid semicolons as line terminators -ms.date: 06/28/2023 +ms.date: 06/01/2026 ms.topic: reference title: AvoidSemicolonsAsLineTerminators --- @@ -10,14 +10,17 @@ title: AvoidSemicolonsAsLineTerminators ## Description -Lines should not end with a semicolon. +This rule detects semicolons used as line terminators at the end of statements. In PowerShell, +line-ending semicolons are redundant and detract from code readability. Although semicolons serve as +statement separators on a single line, using them as line terminators is discouraged. Avoid using +semicolons at the end of lines. -> [!NOTE] -> This rule is not enabled by default. The user needs to enable it through settings. +This rule promotes cleaner, more maintainable code by removing unnecessary semicolons. This rule +isn't enabled by default. ## Example -### Wrong +### Noncompliant ```powershell Install-Module -Name PSScriptAnalyzer; $a = 1 + $b; @@ -28,7 +31,7 @@ Install-Module -Name PSScriptAnalyzer; $a = 1 + $b ``` -### Correct +### Compliant ```powershell Install-Module -Name PSScriptAnalyzer; $a = 1 + $b @@ -43,14 +46,15 @@ $a = 1 + $b ```powershell Rules = @{ - PSAvoidSemicolonsAsLineTerminators = @{ - Enable = $true + PSAvoidSemicolonsAsLineTerminators = @{ + Enable = $true } } ``` -### Parameters +## Parameters -#### Enable: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. diff --git a/docs/Rules/AvoidShouldContinueWithoutForce.md b/docs/Rules/AvoidShouldContinueWithoutForce.md index 189989a89..c8085f17a 100644 --- a/docs/Rules/AvoidShouldContinueWithoutForce.md +++ b/docs/Rules/AvoidShouldContinueWithoutForce.md @@ -1,6 +1,6 @@ --- -description: Avoid Using ShouldContinue Without Boolean Force Parameter -ms.date: 06/28/2023 +description: Avoid using ShouldContinue without boolean Force parameter +ms.date: 06/01/2026 ms.topic: reference title: AvoidShouldContinueWithoutForce --- @@ -10,18 +10,19 @@ title: AvoidShouldContinueWithoutForce ## Description -Functions that use ShouldContinue should have a boolean force parameter to allow user to bypass it. +This rule detects functions that use `ShouldContinue` without a **Force** parameter. Functions that +use `ShouldContinue` should have a boolean `Force` parameter to allow users to bypass the +confirmation prompt. -You can get more details by running `Get-Help about_Functions_CmdletBindingAttribute` and -`Get-Help about_Functions_Advanced_Methods` command in PowerShell. +When using `ShouldContinue` in advanced functions, call it after the +`ShouldProcess` method returns `$true`. -## How - -Call the `ShouldContinue` method in advanced functions when `ShouldProcess` method returns `$true`. +To learn more, see [about_Functions_CmdletBindingAttribute][01] and +[about_Functions_Advanced_Methods][02]. ## Example -### Wrong +### Noncompliant ```powershell Function Test-ShouldContinue @@ -39,7 +40,7 @@ Function Test-ShouldContinue } ``` -### Correct +### Compliant ```powershell Function Test-ShouldContinue @@ -57,3 +58,7 @@ Function Test-ShouldContinue } } ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_cmdletbindingattribute +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods diff --git a/docs/Rules/AvoidTrailingWhitespace.md b/docs/Rules/AvoidTrailingWhitespace.md index 416948c3b..393cbaa25 100644 --- a/docs/Rules/AvoidTrailingWhitespace.md +++ b/docs/Rules/AvoidTrailingWhitespace.md @@ -1,6 +1,6 @@ --- description: Avoid trailing whitespace -ms.date: 06/28/2023 +ms.date: 06/01/2026 ms.topic: reference title: AvoidTrailingWhitespace --- @@ -10,5 +10,46 @@ title: AvoidTrailingWhitespace ## Description -Lines should not end with whitespace characters. This can cause problems with the line-continuation -backtick, and also clutters up future commits to source control. +This rule detects lines that end with trailing whitespace characters. Lines shouldn't end with +trailing whitespace characters. Trailing whitespace makes diffs harder to review and can introduce +subtle problems when line continuation uses a backtick (`), because the backtick must be the last +character on the line. + +Keeping lines free of trailing whitespace improves readability and helps keep source control history +clean. + +To learn more, see [about_Parsing][01]. + +## Example + +### Noncompliant + +```powershell +# The next line ends with a trailing space after the backtick. +Get-Process ` +| Where-Object { $_.CPU -gt 100 } +``` + +When you run this script, PowerShell throws a parser error because the trailing space prevents line +continuation. For example: + +```output +PS C:\WINDOWS\system32> Get-Process ` +| Where-Object { $_.CPU -gt 100 } +At line:2 char:1 ++ | Where-Object { $_.CPU -gt 100 } ++ ~ +An empty pipe element is not allowed. + + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + + FullyQualifiedErrorId : EmptyPipeElement +``` + +### Compliant + +```powershell +Get-Process ` +| Where-Object { $_.CPU -gt 100 } +``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parsing diff --git a/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md b/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md index 20451e66f..67cbff41e 100644 --- a/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md +++ b/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md @@ -1,6 +1,6 @@ --- description: Avoid sending credentials and secrets over unencrypted connections -ms.date: 02/28/2024 +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingAllowUnencryptedAuthentication --- @@ -10,26 +10,29 @@ title: AvoidUsingAllowUnencryptedAuthentication ## Description -Avoid using the **AllowUnencryptedAuthentication** parameter of `Invoke-WebRequest` and -`Invoke-RestMethod`. When using this parameter, the cmdlets send credentials and secrets over -unencrypted connections. This should be avoided except for compatibility with legacy systems. +This rule detects the **AllowUnencryptedAuthentication** parameter used with `Invoke-WebRequest` and +`Invoke-RestMethod` cmdlets. When **AllowUnencryptedAuthentication** is used, it permits credentials +and secrets to be transmitted over unencrypted connections, creating a security risk. -For more details, see [Invoke-RestMethod](xref:Microsoft.PowerShell.Utility.Invoke-RestMethod). +Avoid using this parameter unless you must maintain compatibility with legacy systems that require +unencrypted authentication. -## How +To learn more, see [Invoke-WebRequest][01] and [Invoke-RestMethod][02]. -Avoid using the **AllowUnencryptedAuthentication** parameter. +## Example -## Example 1 - -### Wrong +### Noncompliant ```powershell Invoke-WebRequest foo -AllowUnencryptedAuthentication ``` -### Correct +### Compliant ```powershell Invoke-WebRequest foo ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/invoke-webrequest +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/invoke-restmethod diff --git a/docs/Rules/AvoidUsingBrokenHashAlgorithms.md b/docs/Rules/AvoidUsingBrokenHashAlgorithms.md index 32bb464af..8371c93a0 100644 --- a/docs/Rules/AvoidUsingBrokenHashAlgorithms.md +++ b/docs/Rules/AvoidUsingBrokenHashAlgorithms.md @@ -1,6 +1,6 @@ --- description: Avoid using broken hash algorithms -ms.date: 06/28/2023 +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingBrokenHashAlgorithms --- @@ -10,38 +10,23 @@ title: AvoidUsingBrokenHashAlgorithms ## Description -Avoid using the broken algorithms MD5 or SHA-1. +This rule detects the use of cryptographically broken hash algorithms `MD5` and `SHA-1`. Avoid using +hash algorithms `MD5` and `SHA-1`. These algorithms are vulnerable to collision attacks and are no +longer considered secure for cryptographic purposes. -## How +Replace `MD5` and `SHA-1` with secure alternatives such as `SHA256`, `SHA384`, or `SHA512`. Use +broken algorithms only when strictly necessary for backwards compatibility with legacy systems. -Replace broken algorithms with secure alternatives. MD5 and SHA-1 should be replaced with SHA256, -SHA384, SHA512, or other safer algorithms when possible, with MD5 and SHA-1 only being utilized by -necessity for backwards compatibility. +## Example -## Example 1 - -### Wrong +### Noncompliant ```powershell Get-FileHash foo.txt -Algorithm MD5 ``` -### Correct +### Compliant ```powershell Get-FileHash foo.txt -Algorithm SHA256 ``` - -## Example 2 - -### Wrong - -```powershell -Get-FileHash foo.txt -Algorithm SHA1 -``` - -### Correct - -```powershell -Get-FileHash foo.txt -``` diff --git a/docs/Rules/AvoidUsingCmdletAliases.md b/docs/Rules/AvoidUsingCmdletAliases.md index 9a33149ad..e0569d643 100644 --- a/docs/Rules/AvoidUsingCmdletAliases.md +++ b/docs/Rules/AvoidUsingCmdletAliases.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Cmdlet Aliases or omitting the 'Get-' prefix. -ms.date: 06/28/2023 +description: Avoid using cmdlet aliases or omitting the Get- prefix +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingCmdletAliases --- @@ -10,35 +10,44 @@ title: AvoidUsingCmdletAliases ## Description -An alias is an alternate name or nickname for a cmdlet or for a command element, such as a function, -script, file, or executable file. You can use the alias instead of the command name in any -PowerShell commands. +This rule detects the use of cmdlet aliases and omission of the `Get-` prefix in implicit alias +scenarios. An alias is an alternate name or nickname for a cmdlet or command element, such as a +function, script, file, or executable file. While you can use aliases instead of the full command +name, doing so reduces code readability and maintainability. -There are also implicit aliases. When PowerShell cannot find the cmdlet name, it will try to append -`Get-` to the command as a last resort. Therefore using the command `verb` will execute `Get-Verb`. +PowerShell also supports implicit aliases. When a cmdlet name isn't found, PowerShell appends +`Get-` to the command as a fallback. For example, typing `verb` executes `Get-Verb`. -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. +Aliases create inconsistency across codebases because different authors learn and use different +aliases. Aliases can potentially make code difficult to read and understand in collaborative +environments. It can also cause issues with script portability and availability. -Using the full command name makes it easier to maintain your scripts in the the future. +Using full cmdlet names improves code clarity, makes scripts easier to maintain, and enables proper +syntax highlighting in code editors and platforms like GitHub and Visual Studio Code. Always use the +full cmdlet name instead of aliases. -Using the full command names also allows for syntax highlighting in sites and applications like -GitHub and Visual Studio Code. +## Example -## How to Fix +### Noncompliant -Use the full cmdlet name and not an alias. +```powershell +gps | Where-Object {$_.WorkingSet -gt 20000000} +``` -## Alias Allowlist +### Compliant -To prevent `PSScriptAnalyzer` from flagging your preferred aliases, create an allowlist of the +```powershell +Get-Process | Where-Object {$_.WorkingSet -gt 20000000} +``` + +## Configure rule + +To prevent `PSScriptAnalyzer` from flagging your preferred aliases, create an allow list of the aliases in your settings file and point `PSScriptAnalyzer` to use the settings file. For example, to disable `PSScriptAnalyzer` from flagging `cd`, which is an alias of `Set-Location`, set the settings file content to the following. ```powershell -# PSScriptAnalyzerSettings.psd1 - @{ 'Rules' = @{ 'PSAvoidUsingCmdletAliases' = @{ @@ -47,17 +56,3 @@ file content to the following. } } ``` - -## Example - -### Wrong - -```powershell -gps | Where-Object {$_.WorkingSet -gt 20000000} -``` - -### Correct - -```powershell -Get-Process | Where-Object {$_.WorkingSet -gt 20000000} -``` diff --git a/docs/Rules/AvoidUsingComputerNameHardcoded.md b/docs/Rules/AvoidUsingComputerNameHardcoded.md index 83a60c950..73ac31f20 100644 --- a/docs/Rules/AvoidUsingComputerNameHardcoded.md +++ b/docs/Rules/AvoidUsingComputerNameHardcoded.md @@ -1,6 +1,6 @@ --- -description: Avoid Using ComputerName Hardcoded -ms.date: 06/28/2023 +description: Avoid using hardcoded computer names +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingComputerNameHardcoded --- @@ -10,25 +10,26 @@ title: AvoidUsingComputerNameHardcoded ## Description -The names of computers should never be hard coded as this will expose sensitive information. The -`ComputerName` parameter should never have a hard coded value. +This rule detects hard-coded computer names in the `ComputerName` parameter of cmdlets. Hard-coded +computer names can expose sensitive information and reduce script portability. The `ComputerName` +parameter should always be parameterized or dynamically assigned to ensure scripts are flexible and +secure. -## How +Use parameters, environment variables, or dynamic values instead of hard-coded computer +names. -Remove hard coded computer names. +## Example -## Example 1 - -### Wrong +### Noncompliant ```powershell Function Invoke-MyRemoteCommand () { - Invoke-Command -Port 343 -ComputerName hardcoderemotehostname + Invoke-Command -Port 343 -ComputerName HardcodedRemoteHostname } ``` -### Correct +### Compliant ```powershell Function Invoke-MyCommand ($ComputerName) @@ -36,23 +37,3 @@ Function Invoke-MyCommand ($ComputerName) Invoke-Command -Port 343 -ComputerName $ComputerName } ``` - -## Example 2 - -### Wrong - -```powershell -Function Invoke-MyLocalCommand () -{ - Invoke-Command -Port 343 -ComputerName hardcodelocalhostname -} -``` - -### Correct - -```powershell -Function Invoke-MyLocalCommand () -{ - Invoke-Command -Port 343 -ComputerName $env:COMPUTERNAME -} -``` diff --git a/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md b/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md index d25fce124..bf48a896d 100644 --- a/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md +++ b/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md @@ -1,6 +1,6 @@ --- description: Avoid Using SecureString With Plain Text -ms.date: 01/28/2025 +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingConvertToSecureStringWithPlainText --- @@ -10,31 +10,34 @@ title: AvoidUsingConvertToSecureStringWithPlainText ## Description -The use of the `AsPlainText` parameter with the `ConvertTo-SecureString` command can expose secure -information. +This rule detects the use of the `AsPlainText` parameter with the `ConvertTo-SecureString` command, +which bypasses encryption and exposes sensitive information in memory as plain text, defeating the +purpose of [SecureString][01]. -## How - -Use a standard encrypted variable to perform any SecureString conversions. +Instead, retrieve secure credentials through encrypted channels or use secure input methods like +`Read-Host -AsSecureString` to ensure sensitive data remains encrypted throughout its lifecycle. ## Recommendations -If you do need an ability to retrieve the password from somewhere without prompting the user, -consider using the -[SecretStore](https://www.powershellgallery.com/packages/Microsoft.PowerShell.SecretStore) -module from the PowerShell Gallery. +If you need to retrieve passwords programmatically without user interaction, consider using the +[SecretStore][02] module from the PowerShell Gallery, which provides encrypted credential storage +and retrieval. ## Example -### Wrong +### Noncompliant ```powershell $UserInput = Read-Host 'Please enter your secure code' $EncryptedInput = ConvertTo-SecureString -String $UserInput -AsPlainText -Force ``` -### Correct +### Compliant ```powershell $SecureUserInput = Read-Host 'Please enter your secure code' -AsSecureString ``` + + +[01]: https://learn.microsoft.com/dotnet/api/system.security.securestring +[02]: https://www.powershellgallery.com/packages/Microsoft.PowerShell.SecretStore diff --git a/docs/Rules/AvoidUsingDeprecatedManifestFields.md b/docs/Rules/AvoidUsingDeprecatedManifestFields.md index 802304dfc..fd83bea24 100644 --- a/docs/Rules/AvoidUsingDeprecatedManifestFields.md +++ b/docs/Rules/AvoidUsingDeprecatedManifestFields.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Deprecated Manifest Fields -ms.date: 06/28/2023 +description: Avoid using deprecated manifest fields +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingDeprecatedManifestFields --- @@ -10,17 +10,17 @@ title: AvoidUsingDeprecatedManifestFields ## Description -In PowerShell 5.0, a number of fields in module manifest files (`.psd1`) have been changed. +This rule detects the usage of deprecated manifest fields in module manifest files (`.psd1`) that +should be replaced with their modern equivalents. PowerShell 5.0 deprecated several fields in module +manifest files (`.psd1`) in favor of new alternatives. -The field `ModuleToProcess` has been replaced with the `RootModule` field. - -## How - -Replace `ModuleToProcess` with `RootModule` in the module manifest. +The `ModuleToProcess` field, which was used to specify the module script file to load, is replaced +with the `RootModule` field. The `RootModule` field provides the same functionality and is the +recommended approach for new modules. ## Example -### Wrong +### Noncompliant ```powershell ModuleToProcess ='psscriptanalyzer' @@ -28,7 +28,7 @@ ModuleToProcess ='psscriptanalyzer' ModuleVersion = '1.0' ``` -### Correct +### Compliant ```powershell RootModule ='psscriptanalyzer' diff --git a/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md b/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md index 19c83fad7..bc51d463c 100644 --- a/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md +++ b/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md @@ -1,6 +1,6 @@ --- -description: Avoid using double quotes if the string is constant. -ms.date: 06/28/2023 +description: Avoid using double quotes if the string is constant +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingDoubleQuotesForConstantString --- @@ -10,26 +10,29 @@ title: AvoidUsingDoubleQuotesForConstantString ## Description -Single quotes should be used when the value of a string is constant. A constant string doesn't -contain variables or expressions intended to insert values into the string, such as -`"$PID-$(hostname)"`). +This rule detects static strings enclosed with double quotes (`""`) with text that doesn't +contain variables, expressions, or special characters that require escaping. -This makes the intent clearer that the string is a constant and makes it easier to use some special -characters such as `$` within that string expression without needing to escape them. +Enclose text with single quotes (`''`) when the value of a string is constant. A constant +string doesn't contain variables or expressions intended to insert values into the string, such as +`"$PID-$(hostname)"`. Using single quotes makes the intent clearer that the string is constant and +allows you to use special characters such as `$` without needing to escape them. -There are exceptions to that when double quoted strings are more readable. For example, when the -string value itself must contain a single quote or other special characters, such as newline -(`` "`n" ``), are already being escaped. The rule does not warn in these cases. +However, there are exceptions where this rule doesn't flag violations: + +- Double-quoted strings are preferred when the string contains single quotes +- Embedded escape sequences like newline (``"`n"``) +- Other special characters that require escaping ## Example -### Wrong +### Noncompliant ```powershell $constantValue = "I Love PowerShell" ``` -### Correct +### Compliant ```powershell $constantValue = 'I Love PowerShell' diff --git a/docs/Rules/AvoidUsingEmptyCatchBlock.md b/docs/Rules/AvoidUsingEmptyCatchBlock.md index 198341758..329d94e8b 100644 --- a/docs/Rules/AvoidUsingEmptyCatchBlock.md +++ b/docs/Rules/AvoidUsingEmptyCatchBlock.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Empty Catch Block -ms.date: 06/28/2023 +description: Avoid using empty catch block +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingEmptyCatchBlock --- @@ -10,16 +10,14 @@ title: AvoidUsingEmptyCatchBlock ## Description -Empty catch blocks are considered a poor design choice because any errors occurring in a -`try` block cannot be handled. - -## How - -Use `Write-Error` or `throw` statements within the catch block. +This rule detects empty `catch` blocks. Empty catch blocks are problematic because they silently +suppress exceptions without any error handling, logging, or recovery action. This can mask bugs and +make troubleshooting difficult. Always handle exceptions explicitly by using `Write-Error` to log +the error, `throw` to propagate it, or provide appropriate recovery logic within the catch block. ## Example -### Wrong +### Noncompliant ```powershell try @@ -31,7 +29,7 @@ catch [DivideByZeroException] } ``` -### Correct +### Compliant ```powershell try diff --git a/docs/Rules/AvoidUsingInvokeExpression.md b/docs/Rules/AvoidUsingInvokeExpression.md index 7779008ec..19e1c377b 100644 --- a/docs/Rules/AvoidUsingInvokeExpression.md +++ b/docs/Rules/AvoidUsingInvokeExpression.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Invoke-Expression -ms.date: 06/28/2023 +description: Avoid using Invoke-Expression +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingInvokeExpression --- @@ -10,25 +10,23 @@ title: AvoidUsingInvokeExpression ## Description -Care must be taken when using the `Invoke-Expression` command. The `Invoke-Expression` executes the -specified string and returns the results. +This rule detects the use of the `Invoke-Expression` command, which poses security risks in your +scripts and applications. You must be careful when using the `Invoke-Expression` command. It +executes the specified string and returns the results. -Code injection into your application or script can occur if the expression passed as a string -includes any data provided from the user. - -## How - -Remove the use of `Invoke-Expression`. +Code injection vulnerabilities can occur if the expression passed as a string includes user-provided +data, making your application susceptible to malicious attacks. Avoid using `Invoke-Expression` +whenever possible. ## Example -### Wrong +### Noncompliant ```powershell Invoke-Expression 'Get-Process' ``` -### Correct +### Compliant ```powershell Get-Process diff --git a/docs/Rules/AvoidUsingPlainTextForPassword.md b/docs/Rules/AvoidUsingPlainTextForPassword.md index c25123ec1..662590f85 100644 --- a/docs/Rules/AvoidUsingPlainTextForPassword.md +++ b/docs/Rules/AvoidUsingPlainTextForPassword.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Plain Text For Password Parameter -ms.date: 06/28/2023 +description: Avoid using plain text for Password parameter +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingPlainTextForPassword --- @@ -10,10 +10,12 @@ title: AvoidUsingPlainTextForPassword ## Description -Password parameters that take in plaintext will expose passwords and compromise the security of your -system. Passwords should be stored in the **SecureString** type. +This rule detects function or script parameters with password-related names that are declared with a +`string` type instead of the `SecureString` type. Password parameters that accept plaintext expose +passwords and can compromise your system's security. You shouldn't accept passwords as plain text. +Instead, use the [SecureString][01] type to store passwords securely. -The following parameters are considered password parameters (this is not case sensitive): +The following parameters are considered password parameters and aren't case sensitive: - Password - Pass @@ -22,16 +24,12 @@ The following parameters are considered password parameters (this is not case se - Passphrases - PasswordParam -If a parameter is defined with a name in the above list, it should be declared with type -**SecureString**. - -## How - -Change the type to **SecureString**. +If you define a parameter with a name from the provided list, declare it with the **SecureString** +type. ## Example -### Wrong +### Noncompliant ```powershell function Test-Script @@ -46,7 +44,7 @@ function Test-Script } ``` -### Correct +### Compliant ```powershell function Test-Script @@ -60,3 +58,6 @@ function Test-Script ... } ``` + + +[01]: https://learn.microsoft.com/dotnet/api/system.security.securestring diff --git a/docs/Rules/AvoidUsingPositionalParameters.md b/docs/Rules/AvoidUsingPositionalParameters.md index 1a1b77d01..4bd6a78b2 100644 --- a/docs/Rules/AvoidUsingPositionalParameters.md +++ b/docs/Rules/AvoidUsingPositionalParameters.md @@ -1,25 +1,41 @@ --- -description: Avoid Using Positional Parameters -ms.date: 02/13/2024 +description: Avoid using positional parameters +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingPositionalParameters --- # AvoidUsingPositionalParameters -** Severity Level: Information ** +**Severity Level: Information** ## Description -Using positional parameters reduces the readability of code and can introduce errors. It is possible -that a future version of the cmdlet could change in a way that would break existing scripts if calls -to the cmdlet rely on the position of the parameters. +This rule detects when commands are called with three or more positional parameters instead of using +named parameters. Using positional parameters reduces code readability and can introduce errors. +It's possible that a future version of the cmdlet could change in a way that'll break existing +scripts if they rely on parameter position. For simple cmdlets with only a few positional parameters, the risk is much smaller. To prevent this -rule from being too noisy, this rule gets only triggered when there are 3 or more parameters -supplied. A simple example where the risk of using positional parameters is negligible, is -`Test-Path $Path`. +rule from being too noisy, don't supply three or more parameters. A simple example where the risk of +using positional parameters is negligible is `Test-Path $Path`. -## Configuration +Use full parameter names when calling commands. + +## Example + +### Noncompliant + +```powershell +Get-Command ChildItem Microsoft.PowerShell.Management +``` + +### Compliant + +```powershell +Get-Command -Noun ChildItem -Module Microsoft.PowerShell.Management +``` + +## Configure rule ```powershell Rules = @{ @@ -30,30 +46,14 @@ Rules = @{ } ``` -### Parameters - -#### CommandAllowList: string[] (Default value is @()') +## Parameters -Commands or scripts to be excluded from this rule. +### CommandAllowList -#### Enable: bool (Default value is `$true`) +This parameter specifies commands or scripts to be excluded from this rule. It accepts a string +array. The default value is `@()`. -Enable or disable the rule during ScriptAnalyzer invocation. +### Enable -## How - -Use full parameter names when calling commands. - -## Example - -### Wrong - -```powershell -Get-Command ChildItem Microsoft.PowerShell.Management -``` - -### Correct - -```powershell -Get-Command -Noun ChildItem -Module Microsoft.PowerShell.Management -``` +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To disable this rule, set this parameter to `$false`. The default value is `$true`. diff --git a/docs/Rules/AvoidUsingUsernameAndPasswordParams.md b/docs/Rules/AvoidUsingUsernameAndPasswordParams.md index 32fbac3c7..1d7c0301b 100644 --- a/docs/Rules/AvoidUsingUsernameAndPasswordParams.md +++ b/docs/Rules/AvoidUsingUsernameAndPasswordParams.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Username and Password Parameters -ms.date: 06/28/2023 +description: Avoid using username and password parameters +ms.date: 06/01/2026 ms.topic: reference title: AvoidUsingUsernameAndPasswordParams --- @@ -10,16 +10,13 @@ title: AvoidUsingUsernameAndPasswordParams ## Description -To standardize command parameters, credentials should be accepted as objects of type -**PSCredential**. Functions should not make use of username or password parameters. - -## How - -Change the parameter to type **PSCredential**. +This rule detects functions that use separate username and password parameters instead of a single +**PSCredential** object. Functions shouldn't use separate username or password parameters. To +standardize command parameters, credentials should be accepted as objects of type **PSCredential**. ## Example -### Wrong +### Noncompliant ```powershell function Test-Script @@ -36,7 +33,7 @@ function Test-Script } ``` -### Correct +### Compliant ```powershell function Test-Script diff --git a/docs/Rules/AvoidUsingWMICmdlet.md b/docs/Rules/AvoidUsingWMICmdlet.md index 96e716718..d26b4aa79 100644 --- a/docs/Rules/AvoidUsingWMICmdlet.md +++ b/docs/Rules/AvoidUsingWMICmdlet.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Get-WMIObject, Remove-WMIObject, Invoke-WmiMethod, Register-WmiEvent, Set-WmiInstance -ms.date: 06/28/2023 +description: Avoid using WMI cmdlets +ms.date: 06/02/2026 ms.topic: reference title: AvoidUsingWMICmdlet --- @@ -10,9 +10,12 @@ title: AvoidUsingWMICmdlet ## Description -As of PowerShell 3.0, the CIM cmdlets should be used over the WMI cmdlets. +This rule detects the use of Windows Management Instrumentation (WMI) cmdlets. Since PowerShell 3.0, +you should use Common Information Model (CIM) cmdlets instead of WMI cmdlets. CIM cmdlets comply +with WS-Management (WSMan) standards and the CIM standard, which enables management of Windows and +non-Windows operating systems. -The following cmdlets should not be used: +Don't use these WMI cmdlets: - `Get-WmiObject` - `Remove-WmiObject` @@ -20,7 +23,7 @@ The following cmdlets should not be used: - `Register-WmiEvent` - `Set-WmiInstance` -Use the following cmdlets instead: +Use these CIM cmdlets instead: - `Get-CimInstance` - `Remove-CimInstance` @@ -28,31 +31,18 @@ Use the following cmdlets instead: - `Register-CimIndicationEvent` - `Set-CimInstance` -The CIM cmdlets comply with WS-Management (WSMan) standards and with the Common Information Model -(CIM) standard, allowing for the management of Windows and non-Windows operating systems. - -## How - -Change to the equivalent CIM based cmdlet. - -- `Get-WmiObject` -> `Get-CimInstance` -- `Remove-WmiObject` -> `Remove-CimInstance` -- `Invoke-WmiMethod` -> `Invoke-CimMethod` -- `Register-WmiEvent` -> `Register-CimIndicationEvent` -- `Set-WmiInstance` -> `Set-CimInstance` - ## Example -### Wrong +### Noncompliant ```powershell Get-WmiObject -Query 'Select * from Win32_Process where name LIKE "myprocess%"' | Remove-WmiObject Invoke-WmiMethod -Class Win32_Process -Name 'Create' -ArgumentList @{ CommandLine = 'notepad.exe' } ``` -### Correct +### Compliant ```powershell -Get-CimInstance -Query 'Select * from Win32_Process where name LIKE "myprocess%"' | Remove-CIMInstance +Get-CimInstance -Query 'Select * from Win32_Process where name LIKE "myprocess%"' | Remove-CimInstance Invoke-CimMethod -ClassName Win32_Process -MethodName 'Create' -Arguments @{ CommandLine = 'notepad.exe' } ``` diff --git a/docs/Rules/AvoidUsingWriteHost.md b/docs/Rules/AvoidUsingWriteHost.md index a02571c79..09eef7b6d 100644 --- a/docs/Rules/AvoidUsingWriteHost.md +++ b/docs/Rules/AvoidUsingWriteHost.md @@ -1,6 +1,6 @@ --- -description: Avoid Using Write-Host -ms.date: 12/05/2024 +description: Avoid using Write-Host cmdlet +ms.date: 06/02/2026 ms.topic: reference title: AvoidUsingWriteHost --- @@ -10,24 +10,23 @@ title: AvoidUsingWriteHost ## Description -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. +This rule detects usage of `Write-Host` in functions that don't use the `Show` verb. `Write-Host` is +designed to produce display-only output in the host, like printing colored text or prompting users +for input with `Read-Host`. It uses the `ToString()` method to write output, with results depending +on the PowerShell host program. -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. +Since `Write-Host` doesn't send output to the pipeline, you'll need `Write-Output` or implicit +output to pass data down the pipeline. -## How +Avoid using `Write-Host` in functions unless they use the `Show` verb, which explicitly means +_display information to the user_. This rule doesn't apply to functions with the `Show` verb. -Replace `Write-Host` with `Write-Output` or `Write-Verbose` depending on whether the intention is -logging or returning one or more objects. +Replace [Write-Host][01] with [Write-Output][02] or [Write-Verbose][03] based on your intention. Use +`Write-Verbose` for logging and `Write-Output` for returning objects. ## Example -### Wrong +### Noncompliant ```powershell function Get-MeaningOfLife @@ -37,26 +36,25 @@ function Get-MeaningOfLife } ``` -### Correct +### Compliant Use `Write-Verbose` for informational messages. The user can decide whether to see the message by providing the **Verbose** parameter. ```powershell -function Get-MeaningOfLife -{ +function Get-MeaningOfLife { [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 } -function Show-Something -{ - Write-Host 'show something on screen' +function Show-Something { + Write-Host 'Show something on screen' } ``` -## More information - -[Write-Host](xref:Microsoft.PowerShell.Utility.Write-Host) + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/write-host +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/write-output +[03]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/write-verbose diff --git a/docs/Rules/DSCDscExamplesPresent.md b/docs/Rules/DSCDscExamplesPresent.md index b2b1cf608..cd15788fb 100644 --- a/docs/Rules/DSCDscExamplesPresent.md +++ b/docs/Rules/DSCDscExamplesPresent.md @@ -1,6 +1,6 @@ --- description: DSC examples are present -ms.date: 06/28/2023 +ms.date: 06/03/2026 ms.topic: reference title: DSCDscExamplesPresent --- @@ -10,23 +10,21 @@ title: DSCDscExamplesPresent ## Description -Checks that DSC examples for given resource are present. +This rule detects if Desired State Configuration (DSC) examples for a given resource are present. -## How +To fix a violation of this rule, you must ensure that the `Examples` directory exists for: -To fix a violation of this rule, please make sure `Examples` directory is present: +- Non-class based resources, it should be at the same folder level as the `DSCResources` folder. +- Class based resources, it should be at the same folder level as the resource's `.psm1` file. -- For non-class based resources it should exist at the same folder level as `DSCResources` folder. -- For class based resources it should be present at the same folder level as resource `.psm1` file. - -The `Examples` folder should contain a sample configuration for given resource. The filename should -contain the resource's name. +The `Examples` folder must contain a sample configuration for the resource. The filename should +include the resource's name. ## Example ### Non-class based resource -Let's assume we have non-class based resource with a following file structure: +Let's assume we have non-class based resource with the following file structure: - xAzure - DSCResources @@ -34,7 +32,7 @@ Let's assume we have non-class based resource with a following file structure: - MSFT_xAzureSubscription.psm1 - MSFT_xAzureSubscription.schema.mof -In this case, to fix this warning, we should add examples in a following way: +In this case, to fix this warning, add examples in the following way: - xAzure - DSCResources @@ -47,13 +45,13 @@ In this case, to fix this warning, we should add examples in a following way: ### Class based resource -Let's assume we have class based resource with a following file structure: +Let's assume we have class based resource with the following file structure: - MyDscResource - MyDscResource.psm1 - MyDscResource.psd1 -In this case, to fix this warning, we should add examples in a following way: +In this case, to fix this warning, add examples in the following way: - MyDscResource - MyDscResource.psm1 diff --git a/docs/Rules/DSCDscTestsPresent.md b/docs/Rules/DSCDscTestsPresent.md index f8fe31983..663a6aa3c 100644 --- a/docs/Rules/DSCDscTestsPresent.md +++ b/docs/Rules/DSCDscTestsPresent.md @@ -1,6 +1,6 @@ --- -description: Dsc tests are present -ms.date: 06/28/2023 +description: DSC tests are present +ms.date: 06/03/2026 ms.topic: reference title: DSCDscTestsPresent --- @@ -10,23 +10,22 @@ title: DSCDscTestsPresent ## Description -Checks that DSC tests for given resource are present. +This rule detects if Desired State Configuration (DSC) tests for a given resource are present. -## How +To fix a violation of this rule, you must ensure that the `Tests` directory is present for: -To fix a violation of this rule, please make sure `Tests` directory is present: +- Non-class based resources, it should exist at the same folder level as the `DSCResources` + folder. +- Class based resources, it should be at the same folder level as the resource's `.psm1` file. -- For non-class based resources it should exist at the same folder level as `DSCResources` folder. -- For class based resources it should be present at the same folder level as resource `.psm1` file. - -The `Tests` folder should contain test script for given resource. The filename should contain the -resource's name. +The `Tests` folder must contain a test script for the given resource. The filename should include +the resource's name. ## Example ### Non-class based resource -Let's assume we have non-class based resource with a following file structure: +Let's assume we have non-class based resource with the following file structure: - xAzure - DSCResources @@ -34,7 +33,7 @@ Let's assume we have non-class based resource with a following file structure: - MSFT_xAzureSubscription.psm1 - MSFT_xAzureSubscription.schema.mof -In this case, to fix this warning, we should add tests in a following way: +In this case, to fix this warning, add tests in the following way: - xAzure - DSCResources @@ -46,13 +45,13 @@ In this case, to fix this warning, we should add tests in a following way: ### Class based resource -Let's assume we have class based resource with a following file structure: +Let's assume we have class based resource with the following file structure: - MyDscResource - MyDscResource.psm1 - MyDscResource.psd1 -In this case, to fix this warning, we should add tests in a following way: +In this case, to fix this warning, add tests in the following way: - MyDscResource - MyDscResource.psm1 diff --git a/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md b/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md index 168185280..99dc1a4b0 100644 --- a/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md +++ b/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md @@ -1,6 +1,6 @@ --- -description: Return Correct Types For DSC Functions -ms.date: 06/28/2023 +description: Return correct types for DSC functions +ms.date: 06/03/2026 ms.topic: reference title: DSCReturnCorrectTypesForDSCFunctions --- @@ -10,27 +10,24 @@ title: DSCReturnCorrectTypesForDSCFunctions ## Description -The functions in DSC resources have specific return objects. +This rule detects if functions in Desired State Configuration (DSC) resources have specific return +objects. You'll need to ensure that each function returns the correct type. For non-class based resources: +- `Get-TargetResource` must return a hash table. - `Set-TargetResource` must not return any value. - `Test-TargetResource` must return a boolean. -- `Get-TargetResource` must return a hash table. For class based resources: +- `Get` must return an instance of the DSC class. - `Set` must not return any value. - `Test` must return a boolean. -- `Get` must return an instance of the DSC class. - -## How - -Ensure that each function returns the correct type. -## Example 1 +## Example -### Wrong +### Noncompliant MOF-based resource ```powershell function Get-TargetResource @@ -67,7 +64,7 @@ function Test-TargetResource } ``` -### Correct +### Compliant MOF-based resource ```powershell function Get-TargetResource @@ -106,9 +103,7 @@ function Test-TargetResource } ``` -## Example 2 - -### Wrong +### Noncompliant class-based resource ```powershell [DscResource()] @@ -117,12 +112,7 @@ class MyDSCResource [DscProperty(Key)] [string] $Name - [String] Get() - { - ... - } - - [String] Set() + [void] Set() { ... } @@ -134,7 +124,7 @@ class MyDSCResource } ``` -### Correct +### Compliant class-based resource ```powershell [DscResource()] diff --git a/docs/Rules/DSCStandardDSCFunctionsInResource.md b/docs/Rules/DSCStandardDSCFunctionsInResource.md index f455d7437..96a8125ac 100644 --- a/docs/Rules/DSCStandardDSCFunctionsInResource.md +++ b/docs/Rules/DSCStandardDSCFunctionsInResource.md @@ -1,6 +1,6 @@ --- -description: Use Standard Get/Set/Test TargetResource functions in DSC Resource -ms.date: 06/28/2023 +description: Use standard DSC Get, Set, and Test TargetResource functions in a resource +ms.date: 06/03/2026 ms.topic: reference title: DSCStandardDSCFunctionsInResource --- @@ -10,27 +10,24 @@ title: DSCStandardDSCFunctionsInResource ## Description -All DSC resources are required to implement the correct functions. +This rule detects if all Desired State Configuration (DSC) resources implement the correct +functions. Add the missing functions to the resource. For non-class based resources: +- `Get-TargetResource` - `Set-TargetResource` - `Test-TargetResource` -- `Get-TargetResource` For class based resources: +- `Get` - `Set` - `Test` -- `Get` - -## How - -Add the missing functions to the resource. -## Example 1 +## Example -### Wrong +### Noncompliant MOF-based resource ```powershell function Get-TargetResource @@ -45,8 +42,9 @@ function Get-TargetResource ... } -function Set-TargetResource +function Test-TargetResource { + [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] @@ -57,7 +55,7 @@ function Set-TargetResource } ``` -### Correct +### Compliant MOF-based resource ```powershell function Get-TargetResource @@ -96,9 +94,7 @@ function Test-TargetResource } ``` -## Example 2 - -### Wrong +### Noncompliant class-based resource ```powershell [DscResource()] @@ -117,8 +113,9 @@ class MyDSCResource ... } } +``` -### Correct +### Compliant class-based resource ```powershell [DscResource()] diff --git a/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md b/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md index dc8e9e918..00d45f299 100644 --- a/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md +++ b/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md @@ -1,6 +1,6 @@ --- -description: Use identical mandatory parameters for DSC Get/Test/Set TargetResource functions -ms.date: 06/28/2023 +description: Use identical mandatory parameters for DSC Get, Set, and Test TargetResource functions in a resource +ms.date: 06/03/2026 ms.topic: reference title: DSCUseIdenticalMandatoryParametersForDSC --- @@ -10,20 +10,19 @@ title: DSCUseIdenticalMandatoryParametersForDSC ## Description -For script based DSC resources, if a property is declared with attributes `Key` of `Required` in a -mof file, then is should be present as a mandatory parameter in the corresponding -`Get-TargetResource`, `Set-TargetResource` and `Test-TargetResource` functions. +This rule detects if MOF-based Desired State Configuration (DSC) resources have properties +declared with `Key` or `Required` attributes in a `.mof` file that aren't present as mandatory +parameters in the corresponding functions. These properties must be declared as mandatory +parameters in the `Get-TargetResource`, `Set-TargetResource`, and `Test-TargetResource` functions. -## How - -Make sure all the properties with `Key` and `Required` attributes have equivalent mandatory -parameters in the `Get/Set/Test` functions. +All properties with `Key` and `Required` attributes should have matching mandatory +parameters in the **Get**, **Set**, and **Test** functions. ## Example -Consider the following `mof` file. +Consider the following MOF schema file. -```powershell +```mof class WaitForAny : OMI_BaseResource { [key, Description("Name of Resource on remote machine")] @@ -34,7 +33,7 @@ class WaitForAny : OMI_BaseResource }; ``` -### Wrong +### Noncompliant ```powershell function Get-TargetResource @@ -74,7 +73,7 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] - $Message, + $Message [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -84,7 +83,7 @@ function Test-TargetResource } ``` -### Correct +### Compliant ```powershell function Get-TargetResource diff --git a/docs/Rules/DSCUseIdenticalParametersForDSC.md b/docs/Rules/DSCUseIdenticalParametersForDSC.md index 8f8e98e55..98e3e33e6 100644 --- a/docs/Rules/DSCUseIdenticalParametersForDSC.md +++ b/docs/Rules/DSCUseIdenticalParametersForDSC.md @@ -1,6 +1,6 @@ --- -description: Use Identical Parameters For DSC Test and Set Functions -ms.date: 06/28/2023 +description: Use identical parameters for DSC Get, Set, and Test TargetResource functions in a resource +ms.date: 06/03/2026 ms.topic: reference title: DSCUseIdenticalParametersForDSC --- @@ -10,16 +10,14 @@ title: DSCUseIdenticalParametersForDSC ## Description -The `Get-TargetResource`, `Test-TargetResource` and `Set-TargetResource` functions of DSC Resource -must have the same parameters. - -## How - -Correct the parameters for the functions in DSC resource. +This rule detects if the `Get-TargetResource`, `Set-TargetResource`, and `Test-TargetResource` +functions in a Desired State Configuration (DSC) resource all have identical parameters. If they +don't match, you'll need to update the function parameters to be consistent across all three +functions. ## Example -### Wrong +### Noncompliant ```powershell function Get-TargetResource @@ -61,7 +59,7 @@ function Test-TargetResource } ``` -### Correct +### Compliant ```powershell function Get-TargetResource diff --git a/docs/Rules/DSCUseVerboseMessageInDSCResource.md b/docs/Rules/DSCUseVerboseMessageInDSCResource.md index bb5abacef..2491abc38 100644 --- a/docs/Rules/DSCUseVerboseMessageInDSCResource.md +++ b/docs/Rules/DSCUseVerboseMessageInDSCResource.md @@ -1,6 +1,6 @@ --- -description: Use verbose message in DSC resource -ms.date: 06/28/2023 +description: Use verbose message in DSC resources +ms.date: 06/03/2026 ms.topic: reference title: DSCUseVerboseMessageInDSCResource --- @@ -10,16 +10,14 @@ title: DSCUseVerboseMessageInDSCResource ## Description -Best practice recommends that additional user information is provided within commands, functions and -scripts using `Write-Verbose`. - -## How - -Make use of the `Write-Verbose` command. +This rule detects DSC resources that don't include `Write-Verbose` messages in their functions or +scripts. It's a best practice to provide additional user information within commands, functions, and +scripts using [Write-Verbose][01]. This helps users understand what's happening during execution. +You should include `Write-Verbose` messages to make your code more informative and easier to debug. ## Example -### Wrong +### Noncompliant ```powershell Function Test-Function @@ -30,7 +28,7 @@ Function Test-Function } ``` -### Correct +### Compliant ```powershell Function Test-Function @@ -41,3 +39,6 @@ Function Test-Function ... } ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/write-verbose diff --git a/docs/Rules/MisleadingBacktick.md b/docs/Rules/MisleadingBacktick.md index e140b8e9d..3ea4ebce9 100644 --- a/docs/Rules/MisleadingBacktick.md +++ b/docs/Rules/MisleadingBacktick.md @@ -1,6 +1,6 @@ --- -description: Misleading Backtick -ms.date: 06/28/2023 +description: Misleading backtick +ms.date: 06/04/2026 ms.topic: reference title: MisleadingBacktick --- @@ -10,4 +10,24 @@ title: MisleadingBacktick ## Description -Checks that lines don't end with a backtick followed by whitespace. +This rule detects lines where a trailing backtick is followed by one or more whitespace characters. +A trailing backtick is used for line continuation only when it's the last character on the line. If +whitespace follows the backtick on the same line the continuation doesn't work as intended, which +can make the code look valid but behave unexpectedly. + +## Example + +### Noncompliant + +```powershell +# The line in this example ends with a backtick and trailing whitespace +Get-Process ` +| Where-Object CPU -gt 100 +``` + +### Compliant + +```powershell +Get-Process ` +| Where-Object CPU -gt 100 +``` diff --git a/docs/Rules/MissingModuleManifestField.md b/docs/Rules/MissingModuleManifestField.md index c19d53454..fb00328da 100644 --- a/docs/Rules/MissingModuleManifestField.md +++ b/docs/Rules/MissingModuleManifestField.md @@ -1,6 +1,6 @@ --- -description: Module Manifest Fields -ms.date: 06/28/2023 +description: Module manifest fields +ms.date: 06/04/2026 ms.topic: reference title: MissingModuleManifestField --- @@ -10,23 +10,20 @@ title: MissingModuleManifestField ## Description -A module manifest is a `.psd1` file that contains a hash table. The keys and values in the hash -table describe the contents and attributes of the module, define the prerequisites, and determine -how the components are processed. +This rule detects when a module manifest is missing required fields. A module manifest is a `.psd1` +file that contains a hash table. The keys and values in the hash table describe the contents and +attributes of the module, define the prerequisites, and determine how the components are processed. -Module manifests must contain the following keys (and a corresponding value) to be considered valid: +A module manifest must contain the following key (and a corresponding value) to be considered valid: - `ModuleVersion` -All other keys are optional. The order of the entries is not important. - -## How - -Please consider adding the missing fields to the manifest. +All other keys are optional and the order you place them doesn't matter. To learn more, see +[about_Module_Manifests][01]. ## Example -### Wrong +### Noncompliant ```powershell @{ @@ -38,7 +35,7 @@ Please consider adding the missing fields to the manifest. } ``` -### Correct +### Compliant ```powershell @{ @@ -50,3 +47,6 @@ Please consider adding the missing fields to the manifest. VariablesToExport = '*' } ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_module_manifests diff --git a/docs/Rules/PlaceCloseBrace.md b/docs/Rules/PlaceCloseBrace.md index 6e14acc74..aa249b046 100644 --- a/docs/Rules/PlaceCloseBrace.md +++ b/docs/Rules/PlaceCloseBrace.md @@ -1,6 +1,6 @@ --- -description: Place close braces -ms.date: 06/28/2023 +description: Place close braces consistently +ms.date: 06/05/2026 ms.topic: reference title: PlaceCloseBrace --- @@ -10,10 +10,28 @@ title: PlaceCloseBrace ## Description -Close brace placement should follow a consistent style. It should be on a new line by itself and -should not be followed by an empty line. +This rule detects closing braces (`}`) that aren't placed on a new line by themselves or that are +followed by empty lines. Close brace placement should follow a consistent style. It should be on a +new line by itself and shouldn't be followed by an empty line. This rule is **disabled** by default. -**Note**: This rule is not enabled by default. The user needs to enable it through settings. +## Example + +### Noncompliant + +```powershell +if ($true) { + 'example' } +Get-Process +``` + +### Compliant + +```powershell +if ($true) { + 'example' +} +Get-Process +``` ## Configuration @@ -28,23 +46,27 @@ Rules = @{ } ``` -### Parameters +## Parameters -#### Enable: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -#### NoEmptyLineBefore: bool (Default value is `$false`) +### NoEmptyLineBefore -Create violation if there is an empty line before a close brace. +This parameter controls whether ScriptAnalyzer checks the code for an empty line before a close +brace. It accepts a boolean value. To enable this check, set this parameter to `$true`. The default +value is `$false`. -#### IgnoreOneLineBlock: bool (Default value is `$true`) +### IgnoreOneLineBlock -Indicates if closed brace pairs 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 -doesn't fire a violation. +This parameter controls whether ScriptAnalyzer skips one-line blocks when checking the code against +this rule. It accepts a boolean value. To disable skipping one-line blocks, set this parameter to +`$false`. The default value is `$true`. -#### NewLineAfter: bool (Default value is `$true`) +### NewLineAfter -Indicates if a new line should follow a close brace. If set to true a close brace should be followed -by a new line. +This parameter controls whether ScriptAnalyzer checks that a new line follows a closing brace. It +accepts a boolean value. To disable this check, set this parameter to `$false`. The default value is +`$true`. diff --git a/docs/Rules/PlaceOpenBrace.md b/docs/Rules/PlaceOpenBrace.md index a523ec4e8..9b74c571c 100644 --- a/docs/Rules/PlaceOpenBrace.md +++ b/docs/Rules/PlaceOpenBrace.md @@ -1,6 +1,6 @@ --- description: Place open braces consistently -ms.date: 06/28/2023 +ms.date: 06/05/2026 ms.topic: reference title: PlaceOpenBrace --- @@ -10,10 +10,28 @@ title: PlaceOpenBrace ## Description -Open brace placement should follow a consistent style. It can either follow K&R style (on same line) -or the Allman style (not on same line). +This rule detects opening braces (`{`) that don't follow a consistent style. Opening braces can be +required on the same line as the preceding keyword or on the next line, based on configuration. You +can also require a new line after the opening brace. This rule is **disabled** by default. -**Note**: This rule is not enabled by default. The user needs to enable it through settings. +## Example + +### Noncompliant + +```powershell +if ($true) +{ + 'example' +} +``` + +### Compliant + +```powershell +if ($true) { + 'example' +} +``` ## Configuration @@ -28,22 +46,27 @@ Rules = @{ } ``` -### Parameters +## Parameters -#### Enable: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -#### OnSameLine: bool (Default value is `$true`) +### OnSameLine -Enforce open brace to be on the same line as that of its preceding keyword. +This parameter controls whether ScriptAnalyzer checks that an open brace is on the same line as the +preceding keyword. It accepts a boolean value. To disable this check, set this parameter to +`$false`. The default value is `$true`. -#### NewLineAfter: bool (Default value is `$true`) +### NewLineAfter -Enforce a new line character after an open brace. The default value is true. +This parameter controls whether ScriptAnalyzer checks that a new line follows an opening brace. It +accepts a boolean value. To disable this check, set this parameter to `$false`. The default value is +`$true`. -#### IgnoreOneLineBlock: bool (Default value is `$true`) +### IgnoreOneLineBlock -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 -doesn't fire a violation. +This parameter controls whether ScriptAnalyzer skips one-line blocks when checking the code against +this rule. It accepts a boolean value. To disable skipping one-line blocks, set this parameter to +`$false`. The default value is `$true`. diff --git a/docs/Rules/PossibleIncorrectComparisonWithNull.md b/docs/Rules/PossibleIncorrectComparisonWithNull.md index 9a28646f4..8b0f37518 100644 --- a/docs/Rules/PossibleIncorrectComparisonWithNull.md +++ b/docs/Rules/PossibleIncorrectComparisonWithNull.md @@ -1,6 +1,6 @@ --- -description: Null Comparison -ms.date: 12/03/2024 +description: Comparison with null +ms.date: 06/05/2026 ms.topic: reference title: PossibleIncorrectComparisonWithNull --- @@ -10,27 +10,53 @@ title: PossibleIncorrectComparisonWithNull ## Description -To ensure that PowerShell performs comparisons correctly, the `$null` element should be on the left +This rule detects comparisons where `$null` isn't on the left side of the comparison operator. To +ensure that PowerShell performs comparisons correctly, the `$null` element should be on the left side of the operator. -There are multiple reasons why this occurs: +There are multiple reasons why this placement matters: - `$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. + return any matching values or an empty array if there aren't any matches in the collection. - 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. -## How +### Comparison operator behavior -Move `$null` to the left side of the comparison. +The comparison operator works by design in the following way. + +```powershell +# This example returns 'false' because the comparison doesn't return any objects from the array +if (@() -eq $null) { 'true' } else { 'false' } + +# This example returns 'true' because the array is empty +if ($null -ne @()) { 'true' } else { 'false' } +``` + +This behavior can produce unexpected results, especially when you intend to perform a null check. + +The following example demonstrates how comparison operators behave when the left-hand side is a +collection. The operator compares each element in the collection to the right-hand side value and +returns only the matching elements from the collection. + +```powershell +PS> 1,2,3,1,2 -eq $null +PS> 1,2,3,1,2 -eq 1 +1 +1 +PS> (1,2,3,1,2 -eq $null).count +0 +PS> (1,2,$null,3,$null,1,2 -eq $null).count +2 +``` ## Example -### Wrong +### Noncompliant ```powershell function Test-CompareWithNull @@ -41,7 +67,7 @@ function Test-CompareWithNull } ``` -### Correct +### Compliant ```powershell function Test-CompareWithNull @@ -51,30 +77,3 @@ function Test-CompareWithNull } } ``` - -## Try it Yourself - -```powershell -# This example returns 'false' because the comparison does not return any objects from the array -if (@() -eq $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 -to non-intuitive behavior, especially when the intent is simple test for null. - -The following example demonstrates the designed behavior of the comparison operator when the -left-hand side is a collection. Each element in the collection is compared to the right-hand side -value. When true, that element of the collection is returned. - -```powershell -PS> 1,2,3,1,2 -eq $null -PS> 1,2,3,1,2 -eq 1 -1 -1 -PS> (1,2,3,1,2 -eq $null).count -0 -PS> (1,2,$null,3,$null,1,2 -eq $null).count -2 -``` diff --git a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md index 11c5d23f1..94b322d9f 100644 --- a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md +++ b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md @@ -1,6 +1,6 @@ --- -description: Equal sign is not an assignment operator. Did you mean the equality operator \'-eq\'? -ms.date: 06/28/2023 +description: Use equality operator (==) instead of an equal sign (=) as an assignment operator +ms.date: 06/05/2026 ms.topic: reference title: PossibleIncorrectUsageOfAssignmentOperator --- @@ -10,17 +10,37 @@ title: PossibleIncorrectUsageOfAssignmentOperator ## Description -In many programming languages, the equality operator is denoted as `==` or `=`, but `PowerShell` -uses `-eq`. Therefore, it can easily happen that the wrong operator is used unintentionally. This -rule catches a few special cases where the likelihood of that is quite high. +This rule detects when conditional statements use `=` or `==` instead of the PowerShell equality +operator (`-eq`). The rule looks for usages of `==` and `=` operators inside `if`, `elseif`, +`while`, and `do-while` statements. In PowerShell, `=` represents the [assignment operator][01] and +`-eq` represents the [equality comparison operator][02]. -The rule looks for usages of `==` and `=` operators inside `if`, `else if`, `while` and `do-while` -statements but it does not warn if any kind of command or expression is used at the right hand side -as this is probably by design. +In many programming languages, `==` represents the equality comparison operator. When you define +`==` in a PowerShell expression, including conditional statements, PowerShell raises an error +because `==` isn't valid PowerShell syntax. This rule _always_ flags uses of `==` in conditional +statements. However, it doesn't flag uses of `=` when the right hand side of the conditional uses +any commands or expressions. + +In these cases, it's likely that the use of the assignment operator is intentional. This +construction is often used to concisely assign a value to the variable or property on the left hand +side _and_ check whether the assigned value evaluates as true. + +### Implicit suppression using Clang style + +There are some rare cases where assigning a variable inside an `if` statement is intentional. +Instead of suppressing the rule, you can signal that the assignment's intentional by wrapping the +expression in extra parentheses. An exception applies when `$null` is used on the left-hand side +because there's no use case for it. For example: + +```powershell +if (($shortVariableName = $SuperLongVariableName['SpecialItem']['AnotherItem'])) { + ... +} +``` ## Example -### Wrong +### Noncompliant ```powershell if ($a = $b) @@ -36,7 +56,7 @@ if ($a == $b) } ``` -### Correct +### Compliant ```powershell if ($a -eq $b) # Compare $a with $b @@ -52,16 +72,6 @@ if ($a = Get-Something) # Only execute action if command returns something and a } ``` -## 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 -expression in extra parenthesis. An exception for this is when `$null` is used on the LHS because -there is no use case for this. - -```powershell -if (($shortVariableName = $SuperLongVariableName['SpecialItem']['AnotherItem'])) -{ - ... -} -``` + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_assignment_operators +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comparison_operators#-eq-and--ne \ No newline at end of file diff --git a/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md b/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md index 871d1340f..7ceb1526d 100644 --- a/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md +++ b/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md @@ -1,6 +1,6 @@ --- -description: \'>\' is not a comparison operator. Use \'-gt\' (greater than) or \'-ge\' (greater or equal). -ms.date: 06/28/2023 +description: Use -gt or -ge comparison operators instead of redirection operators +ms.date: 06/05/2026 ms.topic: reference title: PossibleIncorrectUsageOfRedirectionOperator --- @@ -10,17 +10,17 @@ title: PossibleIncorrectUsageOfRedirectionOperator ## Description -In many programming languages, the comparison operator for 'greater than' is `>` but `PowerShell` -uses `-gt` for it and `-ge` (greater or equal) for `>=`. Therefore, it can easily happen that the -wrong operator is used unintentionally. This rule catches a few special cases where the likelihood -of that is quite high. +This rule detects the use of the sequences `>` and `>=` in conditional statements where comparison +operators are intended. This rule catches instances where `>` or `>=` appears inside `if`, `elseif`, +`while`, and `do-while` statements, which are almost always unintentional. -The rule looks for usages of `>` or `>=` operators inside `if`, `elseif`, `while` and `do-while` -statements because this is likely going to be unintentional usage. +In many programming languages, `>` is the comparison operator for _greater than_, but PowerShell +uses `-gt` (greater than) and `-ge` (greater or equal) instead. It's easy to accidentally use the +wrong operator, especially if you're familiar with other languages. ## Example -### Wrong +### Noncompliant ```powershell if ($a > $b) @@ -29,7 +29,7 @@ if ($a > $b) } ``` -### Correct +### Compliant ```powershell if ($a -gt $b) diff --git a/docs/Rules/ProvideCommentHelp.md b/docs/Rules/ProvideCommentHelp.md index 19e83681a..2773b841a 100644 --- a/docs/Rules/ProvideCommentHelp.md +++ b/docs/Rules/ProvideCommentHelp.md @@ -1,6 +1,6 @@ --- -description: Basic Comment Help -ms.date: 06/28/2023 +description: Basic comment help +ms.date: 06/05/2026 ms.topic: reference title: ProvideCommentHelp --- @@ -10,65 +10,20 @@ title: ProvideCommentHelp ## Description -Comment based help should be provided for all PowerShell commands. This test only checks for the -presence of comment based help and not on the validity or format. +This rule detects functions and cmdlets that don't have comment-based help. Every PowerShell command +should include comment-based help to document its purpose, parameters, and usage. PSScriptAnalyzer +checks for the presence of comment-based help but doesn't validate its content or format. -For assistance on comment based help, use the command `Get-Help about_comment_based_help` or the -following articles: +For assistance on comment-based help, use the command `Get-Help about_comment_based_help` or refer +to these resources: -- [Writing Comment-based Help][01] -- [Writing Help for PowerShell Cmdlets][02] +- [Writing comment-based help][01] +- [Writing help for PowerShell cmdlets][02] - [Create XML-based help using PlatyPS][03] -## Configuration - -```powershell -Rules = @{ - PSProvideCommentHelp = @{ - Enable = $true - ExportedOnly = $false - BlockComment = $true - VSCodeSnippetCorrection = $false - Placement = 'before' - } -} -``` - -### Parameters - -- `Enable`: **bool** (Default value is `$true`) - - Enable or disable the rule during ScriptAnalyzer invocation. - -- `ExportedOnly`: **bool** (Default value is `$true`) - - If enabled, throw violation only on functions/cmdlets that are exported using the - `Export-ModuleMember` cmdlet. - -- `BlockComment`: **bool** (Default value is `$true`) - - If enabled, returns comment help in block comment style (`<#...#>`). Otherwise returns - comment help in line comment style where each comment line starts with `#`. - -- `VSCodeSnippetCorrection`: **bool** (Default value is `$false`) - - If enabled, returns comment help in vscode snippet format. - -- `Placement`: **string** (Default value is `before`) - - Represents the position of comment help with respect to the function definition. - - Possible values are: - - - `before`: means the help is placed before the function definition - - `begin` means the help is placed at the beginning of the function definition body - - `end` means the help is places the end of the function definition body - - If any invalid value is given, the property defaults to `before`. - ## Example -### Wrong +### Noncompliant ```powershell function Get-File @@ -82,7 +37,7 @@ function Get-File } ``` -### Correct +### Compliant ```powershell <# @@ -118,6 +73,58 @@ function Get-File } ``` + +## Configuration + +```powershell +Rules = @{ + PSProvideCommentHelp = @{ + Enable = $true + ExportedOnly = $false + BlockComment = $true + VSCodeSnippetCorrection = $false + Placement = 'before' + } +} +``` + +## Parameters + +### Enable + +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. The default value is `$true`. + +### ExportedOnly + +This parameter controls whether violations are reported only for functions and cmdlets that are +exported using the `Export-ModuleMember` cmdlet. It accepts a boolean value. The default value +is `$true`. + +### BlockComment + +This parameter controls the style of comment help returned by the rule. It accepts a boolean +value. When set to `$true`, comment help is returned in block comment style (`<#...#>`). +When set to `$false`, comment help is returned in line comment style where each comment line +starts with `#`. The default value is `$true`. + +### VSCodeSnippetCorrection + +This parameter controls whether comment help is returned in Visual Studio Code snippet format. It +accepts a boolean value. The default value is `$false`. + +### Placement + +This parameter controls the position of comment help with respect to the function definition. It +accepts a string value. If any invalid value is given, the property defaults to `before`. The +default value is `before`. + +The possible values are: + +- `before`: The comment is placed before the function definition +- `begin`: The comment is placed at the beginning of the function definition body +- `end`: The comment is placed at the end of the function definition body + [01]: https://learn.microsoft.com/powershell/scripting/developer/help/writing-comment-based-help-topics [02]: https://learn.microsoft.com/powershell/scripting/developer/help/writing-help-for-windows-powershell-cmdlets diff --git a/docs/Rules/README.md b/docs/Rules/README.md index fac3c7d40..dad6a755f 100644 --- a/docs/Rules/README.md +++ b/docs/Rules/README.md @@ -1,96 +1,187 @@ --- description: List of PSScriptAnalyzer rules -ms.date: 03/20/2026 +ms.date: 06/25/2026 ms.topic: reference title: List of PSScriptAnalyzer rules --- # PSScriptAnalyzer Rules -The PSScriptAnalyzer contains the following rule definitions. +The PSScriptAnalyzer module includes the following built-in rule definitions. You can disable most +configurable rules by setting the `Enable` property to `$false` in a custom rule configuration file. +Rules listed as _Always enabled_ can't be disabled using configuration. However, there are two ways +to avoid rules you don't want to use: -| Rule | Severity | Enabled by default | Configurable | -| ------------------------------------------------------------------------------------------------- | ----------- | :----------------: | :-------------: | -| [AlignAssignmentStatement](./AlignAssignmentStatement.md) | Warning | No | Yes | -| [AvoidAssignmentToAutomaticVariable](./AvoidAssignmentToAutomaticVariable.md) | Warning | Yes | | -| [AvoidDefaultValueForMandatoryParameter](./AvoidDefaultValueForMandatoryParameter.md) | Warning | Yes | | -| [AvoidDefaultValueSwitchParameter](./AvoidDefaultValueSwitchParameter.md) | Warning | Yes | | -| [AvoidDynamicallyCreatingVariableNames](./AvoidDynamicallyCreatingVariableNames.md) | Information | No | Yes | -| [AvoidExclaimOperator](./AvoidExclaimOperator.md) | Warning | No | | -| [AvoidGlobalAliases1](./AvoidGlobalAliases.md) | Warning | Yes | | -| [AvoidGlobalFunctions](./AvoidGlobalFunctions.md) | Warning | Yes | | -| [AvoidGlobalVars](./AvoidGlobalVars.md) | Warning | Yes | | -| [AvoidInvokingEmptyMembers](./AvoidInvokingEmptyMembers.md) | Warning | Yes | | -| [AvoidLongLines](./AvoidLongLines.md) | Warning | No | Yes | -| [AvoidMultipleTypeAttributes1](./AvoidMultipleTypeAttributes.md) | Warning | Yes | | -| [AvoidNullOrEmptyHelpMessageAttribute](./AvoidNullOrEmptyHelpMessageAttribute.md) | Warning | Yes | | -| [AvoidOverwritingBuiltInCmdlets](./AvoidOverwritingBuiltInCmdlets.md) | Warning | Yes | Yes | -| [AvoidReservedWordsAsFunctionNames](./AvoidReservedWordsAsFunctionNames.md) | Warning | Yes | | -| [AvoidSemicolonsAsLineTerminators](./AvoidSemicolonsAsLineTerminators.md) | Warning | No | | -| [AvoidShouldContinueWithoutForce](./AvoidShouldContinueWithoutForce.md) | Warning | Yes | | -| [AvoidTrailingWhitespace](./AvoidTrailingWhitespace.md) | Warning | Yes | | -| [AvoidUsingAllowUnencryptedAuthentication](./AvoidUsingAllowUnencryptedAuthentication.md) | Warning | Yes | | -| [AvoidUsingArrayList](./AvoidUsingArrayList.md) | Warning | No | Yes | -| [AvoidUsingBrokenHashAlgorithms](./AvoidUsingBrokenHashAlgorithms.md) | Warning | Yes | | -| [AvoidUsingCmdletAliases](./AvoidUsingCmdletAliases.md) | Warning | Yes | Yes2 | -| [AvoidUsingComputerNameHardcoded](./AvoidUsingComputerNameHardcoded.md) | Error | Yes | | -| [AvoidUsingConvertToSecureStringWithPlainText](./AvoidUsingConvertToSecureStringWithPlainText.md) | Error | Yes | | -| [AvoidUsingDeprecatedManifestFields](./AvoidUsingDeprecatedManifestFields.md) | Warning | Yes | | -| [AvoidUsingDoubleQuotesForConstantString](./AvoidUsingDoubleQuotesForConstantString.md) | Information | No | | -| [AvoidUsingEmptyCatchBlock](./AvoidUsingEmptyCatchBlock.md) | Warning | Yes | | -| [AvoidUsingInvokeExpression](./AvoidUsingInvokeExpression.md) | Warning | Yes | | -| [AvoidUsingPlainTextForPassword](./AvoidUsingPlainTextForPassword.md) | Warning | Yes | | -| [AvoidUsingPositionalParameters](./AvoidUsingPositionalParameters.md) | Warning | Yes | | -| [AvoidUsingUsernameAndPasswordParams](./AvoidUsingUsernameAndPasswordParams.md) | Error | Yes | | -| [AvoidUsingWMICmdlet](./AvoidUsingWMICmdlet.md) | Warning | Yes | | -| [AvoidUsingWriteHost](./AvoidUsingWriteHost.md) | Warning | Yes | | -| [DSCDscExamplesPresent](./DSCDscExamplesPresent.md) | Information | Yes | | -| [DSCDscTestsPresent](./DSCDscTestsPresent.md) | Information | Yes | | -| [DSCReturnCorrectTypesForDSCFunctions](./DSCReturnCorrectTypesForDSCFunctions.md) | Information | Yes | | -| [DSCStandardDSCFunctionsInResource](./DSCStandardDSCFunctionsInResource.md) | Error | Yes | | -| [DSCUseIdenticalMandatoryParametersForDSC](./DSCUseIdenticalMandatoryParametersForDSC.md) | Error | Yes | | -| [DSCUseIdenticalParametersForDSC](./DSCUseIdenticalParametersForDSC.md) | Error | Yes | | -| [DSCUseVerboseMessageInDSCResource](./DSCUseVerboseMessageInDSCResource.md) | Error | Yes | | -| [InvalidMultiDotValue](./InvalidMultiDotValue.md) | Error | No | Yes | -| [MisleadingBacktick](./MisleadingBacktick.md) | Warning | Yes | | -| [MissingModuleManifestField](./MissingModuleManifestField.md) | Warning | Yes | | -| [MissingTryBlock](./MissingTryBlock.md) | Warning | No | Yes | -| [PlaceCloseBrace](./PlaceCloseBrace.md) | Warning | No | Yes | -| [PlaceOpenBrace](./PlaceOpenBrace.md) | Warning | No | Yes | -| [PossibleIncorrectComparisonWithNull](./PossibleIncorrectComparisonWithNull.md) | Warning | Yes | | -| [PossibleIncorrectUsageOfAssignmentOperator](./PossibleIncorrectUsageOfAssignmentOperator.md) | Warning | Yes | | -| [PossibleIncorrectUsageOfRedirectionOperator](./PossibleIncorrectUsageOfRedirectionOperator.md) | Warning | Yes | | -| [ProvideCommentHelp](./ProvideCommentHelp.md) | Information | Yes | Yes | -| [ReservedCmdletChar](./ReservedCmdletChar.md) | Error | Yes | | -| [ReservedParams](./ReservedParams.md) | Error | Yes | | -| [ReviewUnusedParameter](./ReviewUnusedParameter.md) | Warning | Yes | Yes2 | -| [ShouldProcess](./ShouldProcess.md) | Warning | Yes | | -| [UseApprovedVerbs](./UseApprovedVerbs.md) | Warning | Yes | | -| [UseBOMForUnicodeEncodedFile](./UseBOMForUnicodeEncodedFile.md) | Warning | Yes | | -| [UseCmdletCorrectly](./UseCmdletCorrectly.md) | Warning | Yes | | -| [UseCompatibleCmdlets](./UseCompatibleCmdlets.md) | Warning | Yes | Yes2 | -| [UseCompatibleCommands](./UseCompatibleCommands.md) | Warning | No | Yes | -| [UseCompatibleSyntax](./UseCompatibleSyntax.md) | Warning | No | Yes | -| [UseCompatibleTypes](./UseCompatibleTypes.md) | Warning | No | Yes | -| [UseConsistentIndentation](./UseConsistentIndentation.md) | Warning | No | Yes | -| [UseConsistentParameterSetName](./UseConsistentParameterSetName.md) | Warning | No | | -| [UseConsistentParametersKind](./UseConsistentParametersKind.md) | Warning | No | Yes | -| [UseConsistentWhitespace](./UseConsistentWhitespace.md) | Warning | No | Yes | -| [UseConstrainedLanguageMode](./UseConstrainedLanguageMode.md) | Warning | No | Yes | -| [UseCorrectCasing](./UseCorrectCasing.md) | Information | No | Yes | -| [UseDeclaredVarsMoreThanAssignments](./UseDeclaredVarsMoreThanAssignments.md) | Warning | Yes | | -| [UseLiteralInitializerForHashtable](./UseLiteralInitializerForHashtable.md) | Warning | Yes | | -| [UseOutputTypeCorrectly](./UseOutputTypeCorrectly.md) | Information | Yes | | -| [UseProcessBlockForPipelineCommand](./UseProcessBlockForPipelineCommand.md) | Warning | Yes | | -| [UsePSCredentialType](./UsePSCredentialType.md) | Warning | Yes | | -| [UseShouldProcessForStateChangingFunctions](./UseShouldProcessForStateChangingFunctions.md) | Warning | Yes | | -| [UseSingleValueFromPipelineParameter](./UseSingleValueFromPipelineParameter.md) | Warning | No | | -| [UseSingularNouns](./UseSingularNouns.md) | Warning | Yes | Yes | -| [UseSupportsShouldProcess](./UseSupportsShouldProcess.md) | Warning | Yes | | -| [UseToExportFieldsInManifest](./UseToExportFieldsInManifest.md) | Warning | Yes | | -| [UseUsingScopeModifierInNewRunspaces](./UseUsingScopeModifierInNewRunspaces.md) | Warning | Yes | | -| [UseUTF8EncodingForHelpFile](./UseUTF8EncodingForHelpFile.md) | Warning | Yes | | + The PSScriptAnalyzer module includes the following built-in rule definitions. For rules that + support settings, you can enable or disable them by setting the `Enable` configuration property in + a custom settings file. Rules listed as _Always enabled_ don't expose a per-rule `Enable` property. + There are two way to avoid using these rules: -- 1 Rule is not available on all PowerShell versions, editions, or OS platforms. See the - rule's documentation for details. -- 2 The rule has a configurable property, but the rule can't be disabled like other - configurable rules. +- Create a custom rule configuration file to include only the rules you want or exclude the rules + you don't want. +- Add the appropriate rule suppression attributes to your code to suppress the rule for specific + code blocks. For more information, see the _Suppressing rules_ section of + [Using PSScriptAnalyzer][01]. + +| Rule | Severity | Default state | Configurable | +| -------------------------------------------------- | ----------- | :------------: | :----------: | +| [AlignAssignmentStatement][02] | Warning | Disabled | Yes | +| [AvoidAssignmentToAutomaticVariable][03] | Warning | Always enabled | | +| [AvoidDefaultValueForMandatoryParameter][04] | Warning | Always enabled | | +| [AvoidDefaultValueSwitchParameter][05] | Warning | Always enabled | | +| [AvoidDynamicallyCreatingVariableNames][06] | Information | Disabled | Yes | +| [AvoidExclaimOperator][07] | Warning | Disabled | Yes | +| [AvoidGlobalAliases][08] | Warning | Always enabled | | +| [AvoidGlobalFunctions][09] | Warning | Always enabled | | +| [AvoidGlobalVars][10] | Warning | Always enabled | | +| [AvoidInvokingEmptyMembers][11] | Warning | Always enabled | | +| [AvoidLongLines][12] | Warning | Disabled | Yes | +| [AvoidMultipleTypeAttributes][13] | Warning | Always enabled | | +| [AvoidNullOrEmptyHelpMessageAttribute][14] | Warning | Always enabled | | +| [AvoidOverwritingBuiltInCmdlets][15] | Warning | Enabled | Yes | +| [AvoidReservedWordsAsFunctionNames][16] | Warning | Always enabled | | +| [AvoidSemicolonsAsLineTerminators][17] | Warning | Disabled | Yes | +| [AvoidShouldContinueWithoutForce][18] | Warning | Always enabled | | +| [AvoidTrailingWhitespace][19] | Warning | Always enabled | | +| [AvoidUsingAllowUnencryptedAuthentication][20] | Warning | Always enabled | | +| [AvoidUsingArrayList][21] | Warning | Disabled | Yes | +| [AvoidUsingBrokenHashAlgorithms][22] | Warning | Always enabled | | +| [AvoidUsingCmdletAliases][23] | Warning | Always enabled | Yes | +| [AvoidUsingComputerNameHardcoded][24] | Error | Always enabled | | +| [AvoidUsingConvertToSecureStringWithPlainText][25] | Error | Always enabled | | +| [AvoidUsingDeprecatedManifestFields][26] | Warning | Always enabled | | +| [AvoidUsingDoubleQuotesForConstantString][27] | Information | Disabled | Yes | +| [AvoidUsingEmptyCatchBlock][28] | Warning | Always enabled | | +| [AvoidUsingInvokeExpression][29] | Warning | Always enabled | | +| [AvoidUsingPlainTextForPassword][30] | Warning | Always enabled | | +| [AvoidUsingPositionalParameters][31] | Warning | Always enabled | | +| [AvoidUsingUsernameAndPasswordParams][32] | Error | Always enabled | | +| [AvoidUsingWMICmdlet][33] | Warning | Always enabled | | +| [AvoidUsingWriteHost][34] | Warning | Always enabled | | +| [DSCDscExamplesPresent][35] | Information | Always enabled | | +| [DSCDscTestsPresent][36] | Information | Always enabled | | +| [DSCReturnCorrectTypesForDSCFunctions][37] | Information | Always enabled | | +| [DSCStandardDSCFunctionsInResource][38] | Error | Always enabled | | +| [DSCUseIdenticalMandatoryParametersForDSC][39] | Error | Always enabled | | +| [DSCUseIdenticalParametersForDSC][40] | Error | Always enabled | | +| [DSCUseVerboseMessageInDSCResource][41] | Error | Always enabled | | +| [InvalidMultiDotValue][42] | Error | Disabled | Yes | +| [MisleadingBacktick][43] | Warning | Always enabled | | +| [MissingModuleManifestField][44] | Warning | Always enabled | | +| [MissingTryBlock][45] | Warning | Disabled | Yes | +| [PlaceCloseBrace][46] | Warning | Disabled | Yes | +| [PlaceOpenBrace][47] | Warning | Disabled | Yes | +| [PossibleIncorrectComparisonWithNull][48] | Warning | Always enabled | | +| [PossibleIncorrectUsageOfAssignmentOperator][49] | Warning | Always enabled | | +| [PossibleIncorrectUsageOfRedirectionOperator][50] | Warning | Always enabled | | +| [ProvideCommentHelp][51] | Information | Enabled | Yes | +| [ReservedCmdletChar][52] | Error | Always enabled | | +| [ReservedParams][53] | Error | Always enabled | | +| [ReviewUnusedParameter][54] | Warning | Always enabled | Yes | +| [ShouldProcess][55] | Warning | Always enabled | | +| [UseApprovedVerbs][56] | Warning | Always enabled | | +| [UseBOMForUnicodeEncodedFile][57] | Warning | Always enabled | | +| [UseCmdletCorrectly][58] | Warning | Always enabled | | +| [UseCompatibleCmdlets][59] | Warning | Always enabled | Yes | +| [UseCompatibleCommands][60] | Warning | Disabled | Yes | +| [UseCompatibleSyntax][61] | Warning | Disabled | Yes | +| [UseCompatibleTypes][62] | Warning | Disabled | Yes | +| [UseConsistentIndentation][63] | Warning | Disabled | Yes | +| [UseConsistentParameterSetName][64] | Warning | Disabled | Yes | +| [UseConsistentParametersKind][65] | Warning | Disabled | Yes | +| [UseConsistentWhitespace][66] | Warning | Disabled | Yes | +| [UseConstrainedLanguageMode][67] | Warning | Disabled | Yes | +| [UseCorrectCasing][68] | Information | Disabled | Yes | +| [UseDeclaredVarsMoreThanAssignments][69] | Warning | Always enabled | | +| [UseLiteralInitializerForHashtable][70] | Warning | Always enabled | | +| [UseOutputTypeCorrectly][71] | Information | Always enabled | | +| [UseProcessBlockForPipelineCommand][72] | Warning | Always enabled | | +| [UsePSCredentialType][73] | Warning | Always enabled | | +| [UseShouldProcessForStateChangingFunctions][74] | Warning | Always enabled | | +| [UseSingleValueFromPipelineParameter][75] | Warning | Disabled | Yes | +| [UseSingularNouns][76] | Warning | Enabled | Yes | +| [UseSupportsShouldProcess][77] | Warning | Always enabled | | +| [UseToExportFieldsInManifest][78] | Warning | Always enabled | | +| [UseUsingScopeModifierInNewRunspaces][79] | Warning | Always enabled | | +| [UseUTF8EncodingForHelpFile][80] | Warning | Always enabled | | + + +[01]: ../using-scriptanalyzer.md#suppressing-rules +[02]: AlignAssignmentStatement.md +[03]: AvoidAssignmentToAutomaticVariable.md +[04]: AvoidDefaultValueForMandatoryParameter.md +[05]: AvoidDefaultValueSwitchParameter.md +[06]: AvoidDynamicallyCreatingVariableNames.md +[07]: AvoidExclaimOperator.md +[08]: AvoidGlobalAliases.md +[09]: AvoidGlobalFunctions.md +[10]: AvoidGlobalVars.md +[11]: AvoidInvokingEmptyMembers.md +[12]: AvoidLongLines.md +[13]: AvoidMultipleTypeAttributes.md +[14]: AvoidNullOrEmptyHelpMessageAttribute.md +[15]: AvoidOverwritingBuiltInCmdlets.md +[16]: AvoidReservedWordsAsFunctionNames.md +[17]: AvoidSemicolonsAsLineTerminators.md +[18]: AvoidShouldContinueWithoutForce.md +[19]: AvoidTrailingWhitespace.md +[20]: AvoidUsingAllowUnencryptedAuthentication.md +[21]: AvoidUsingArrayList.md +[22]: AvoidUsingBrokenHashAlgorithms.md +[23]: AvoidUsingCmdletAliases.md +[24]: AvoidUsingComputerNameHardcoded.md +[25]: AvoidUsingConvertToSecureStringWithPlainText.md +[26]: AvoidUsingDeprecatedManifestFields.md +[27]: AvoidUsingDoubleQuotesForConstantString.md +[28]: AvoidUsingEmptyCatchBlock.md +[29]: AvoidUsingInvokeExpression.md +[30]: AvoidUsingPlainTextForPassword.md +[31]: AvoidUsingPositionalParameters.md +[32]: AvoidUsingUsernameAndPasswordParams.md +[33]: AvoidUsingWMICmdlet.md +[34]: AvoidUsingWriteHost.md +[35]: DSCDscExamplesPresent.md +[36]: DSCDscTestsPresent.md +[37]: DSCReturnCorrectTypesForDSCFunctions.md +[38]: DSCStandardDSCFunctionsInResource.md +[39]: DSCUseIdenticalMandatoryParametersForDSC.md +[40]: DSCUseIdenticalParametersForDSC.md +[41]: DSCUseVerboseMessageInDSCResource.md +[42]: InvalidMultiDotValue.md +[43]: MisleadingBacktick.md +[44]: MissingModuleManifestField.md +[45]: MissingTryBlock.md +[46]: PlaceCloseBrace.md +[47]: PlaceOpenBrace.md +[48]: PossibleIncorrectComparisonWithNull.md +[49]: PossibleIncorrectUsageOfAssignmentOperator.md +[50]: PossibleIncorrectUsageOfRedirectionOperator.md +[51]: ProvideCommentHelp.md +[52]: ReservedCmdletChar.md +[53]: ReservedParams.md +[54]: ReviewUnusedParameter.md +[55]: ShouldProcess.md +[56]: UseApprovedVerbs.md +[57]: UseBOMForUnicodeEncodedFile.md +[58]: UseCmdletCorrectly.md +[59]: UseCompatibleCmdlets.md +[60]: UseCompatibleCommands.md +[61]: UseCompatibleSyntax.md +[62]: UseCompatibleTypes.md +[63]: UseConsistentIndentation.md +[64]: UseConsistentParameterSetName.md +[65]: UseConsistentParametersKind.md +[66]: UseConsistentWhitespace.md +[67]: UseConstrainedLanguageMode.md +[68]: UseCorrectCasing.md +[69]: UseDeclaredVarsMoreThanAssignments.md +[70]: UseLiteralInitializerForHashtable.md +[71]: UseOutputTypeCorrectly.md +[72]: UseProcessBlockForPipelineCommand.md +[73]: UsePSCredentialType.md +[74]: UseShouldProcessForStateChangingFunctions.md +[75]: UseSingleValueFromPipelineParameter.md +[76]: UseSingularNouns.md +[77]: UseSupportsShouldProcess.md +[78]: UseToExportFieldsInManifest.md +[79]: UseUsingScopeModifierInNewRunspaces.md +[80]: UseUTF8EncodingForHelpFile.md diff --git a/docs/Rules/ReservedCmdletChar.md b/docs/Rules/ReservedCmdletChar.md index 55acfc707..9e781eb3a 100644 --- a/docs/Rules/ReservedCmdletChar.md +++ b/docs/Rules/ReservedCmdletChar.md @@ -1,6 +1,6 @@ --- -description: Reserved Cmdlet Chars -ms.date: 06/28/2023 +description: Reserved cmdlet characters +ms.date: 06/08/2026 ms.topic: reference title: ReservedCmdletChar --- @@ -10,25 +10,45 @@ title: ReservedCmdletChar ## Description -You cannot use following reserved characters in a function or cmdlet name as these can cause parsing -or runtime errors. - -Reserved Characters include: ``#,(){}[]&/\\$^;:\"'<>|?@`*%+=~`` - -## How - -Remove reserved characters from names. +This rule detects when reserved characters are used in function or cmdlet names. You can't use +reserved characters in a function or cmdlet name as they cause parsing or runtime errors. Remove +reserved characters from your names. + +Reserved characters include: + +| Character | Meaning | +|:---------:|:---------------------------------------------| +| `` ` `` | Escape character (backtick) | +| `$` | Variable expansion | +| `"` | String delimiter (allows variable expansion) | +| `'` | String delimiter (literal string) | +| `( )` | Grouping expressions / method calls | +| `{ }` | Script blocks / hash tables | +| `[ ]` | Type literals / array indexing | +| `,` | Array element separator | +| `;` | Statement separator | +| `&` | Call operator | +| `?` | Alias for Where-Object in some contexts | +| `*` | Wildcard | +| `< >` | Redirection operators | +| `@` | Array or hash table literal | +| `:` | Scope modifier / drive separator | +| `#` | Comment | +| `=` | Assignment operator | +| `+` | String concatenation operator | +| `~` | Expands to the value of the $HOME variable | +| `\|` | Pipe operator | ## Example -### Wrong +### Noncompliant ```powershell function MyFunction[1] {...} ``` -### Correct +### Compliant ```powershell function MyFunction diff --git a/docs/Rules/ReservedParams.md b/docs/Rules/ReservedParams.md index 0e433e0e4..c1e10a4bb 100644 --- a/docs/Rules/ReservedParams.md +++ b/docs/Rules/ReservedParams.md @@ -1,6 +1,6 @@ --- -description: Reserved Parameters -ms.date: 03/06/2024 +description: Reserved parameters +ms.date: 06/08/2026 ms.topic: reference title: ReservedParams --- @@ -10,17 +10,15 @@ title: ReservedParams ## Description -You can't redefine [common parameters][01] in an advanced function. Using the `CmdletBinding` or -`Parameter` attributes creates an advanced function. The common parameters are are automatically -available in advanced functions, so you can't redefine them. - -## How - -Change the name of the parameter. +This rule detects when you attempt to redefine [common parameters][01] in an advanced function. When +you use the `CmdletBinding` or `Parameter` attributes, you're creating an advanced function. Common +parameters are automatically available in advanced functions, so you can't redefine them. If you're +trying to use a parameter name that conflicts with a common parameter, you need to change the name +of your parameter to something else. ## Example -### Wrong +### Noncompliant ```powershell function Test @@ -34,7 +32,7 @@ function Test } ``` -### Correct +### Compliant ```powershell function Test diff --git a/docs/Rules/ReviewUnusedParameter.md b/docs/Rules/ReviewUnusedParameter.md index 4732b8aba..abc535729 100644 --- a/docs/Rules/ReviewUnusedParameter.md +++ b/docs/Rules/ReviewUnusedParameter.md @@ -1,6 +1,6 @@ --- description: ReviewUnusedParameter -ms.date: 03/26/2024 +ms.date: 06/08/2026 ms.topic: reference title: ReviewUnusedParameter --- @@ -10,34 +10,13 @@ title: ReviewUnusedParameter ## Description -This rule identifies parameters declared in a script, scriptblock, or function scope that have not -been used in that scope. - -## Configuration settings - -By default, this rule doesn't consider child scopes other than scriptblocks provided to -`Where-Object` or `ForEach-Object`. The `CommandsToTraverse` setting is an string array allows you -to add additional commands that accept scriptblocks that this rule should examine. - -```powershell -@{ - Rules = @{ - PSReviewUnusedParameter = @{ - CommandsToTraverse = @( - 'Invoke-PSFProtectedCommand' - ) - } - } -} -``` - -## How - -Consider removing the unused parameter. +This rule detects parameters that are declared but not used a script, scriptblock, or function +scope. You should consider removing unused parameters to improve code clarity and reduce confusion +about your function's dependencies. ## Example -### Wrong +### Noncompliant ```powershell function Test-Parameter @@ -45,7 +24,7 @@ function Test-Parameter Param ( $Parameter1, - # this parameter is never called in the function + # This parameter is never called in the function $Parameter2 ) @@ -53,7 +32,7 @@ function Test-Parameter } ``` -### Correct +### Compliant ```powershell function Test-Parameter @@ -61,10 +40,28 @@ function Test-Parameter Param ( $Parameter1, - # now this parameter is being called in the same scope + # Now this parameter is being called in the same scope $Parameter2 ) Get-Something $Parameter1 $Parameter2 } ``` + +## Configure rule + +By default, this rule doesn't consider child scopes other than scriptblocks provided to either +`Where-Object` or `ForEach-Object`. The `CommandsToTraverse` setting is a string array that allows +you to add extra commands that accept scriptblocks that this rule should examine. + +```powershell +@{ + Rules = @{ + PSReviewUnusedParameter = @{ + CommandsToTraverse = @( + 'Invoke-PSFProtectedCommand' + ) + } + } +} +``` diff --git a/docs/Rules/ShouldProcess.md b/docs/Rules/ShouldProcess.md index 40dcedec4..0929185f5 100644 --- a/docs/Rules/ShouldProcess.md +++ b/docs/Rules/ShouldProcess.md @@ -1,6 +1,6 @@ --- -description: Should Process -ms.date: 06/28/2023 +description: Pair ShouldProcess with SupportsShouldProcess +ms.date: 06/08/2026 ms.topic: reference title: ShouldProcess --- @@ -10,10 +10,17 @@ title: ShouldProcess ## Description -If a cmdlet declares the `SupportsShouldProcess` attribute, then it should also call -`ShouldProcess`. A violation is any function which either declares `SupportsShouldProcess` attribute -but makes no calls to `ShouldProcess` or it calls `ShouldProcess` but does not declare -`SupportsShouldProcess`. +This rule detects mismatches between `SupportsShouldProcess` declarations and `ShouldProcess` calls. +When a cmdlet declares the `SupportsShouldProcess` attribute, it should also call the +`ShouldProcess` method. + +Violations occur when: + +- A function declares `SupportsShouldProcess` but doesn't call `ShouldProcess` +- A function calls `ShouldProcess` but doesn't declare `SupportsShouldProcess` + +To fix this violation, ensure that `ShouldProcess` calls are paired with the `SupportsShouldProcess` +attribute declaration. For more information, see the following articles: @@ -21,15 +28,9 @@ For more information, see the following articles: - [about_Functions_CmdletBindingAttribute][02] - [Everything you wanted to know about ShouldProcess][03] -## How - -To fix a violation of this rule, please call `ShouldProcess` method when a cmdlet declares -`SupportsShouldProcess` attribute. Or please add `SupportsShouldProcess` attribute argument when -calling `ShouldProcess`. - ## Example -### Wrong +### Noncompliant ```powershell function Set-File @@ -45,7 +46,7 @@ function Set-File } ``` -### Correct +### Compliant ```powershell function Set-File @@ -72,6 +73,7 @@ function Set-File } } ``` + [01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods [02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_Functions_CmdletBindingAttribute diff --git a/docs/Rules/UseApprovedVerbs.md b/docs/Rules/UseApprovedVerbs.md index c1bcaa0c7..4cd5bcebe 100644 --- a/docs/Rules/UseApprovedVerbs.md +++ b/docs/Rules/UseApprovedVerbs.md @@ -1,6 +1,6 @@ --- -description: Cmdlet Verbs -ms.date: 03/26/2024 +description: Approved cmdlet verbs +ms.date: 06/08/2026 ms.topic: reference title: UseApprovedVerbs --- @@ -10,38 +10,33 @@ title: UseApprovedVerbs ## Description -All cmdlets must used approved verbs. +This rule detects cmdlets that use unapproved verbs in their names. All cmdlets must use approved +verbs. You can find approved verbs by running the `Get-Verb` command. If your cmdlet uses an +unapproved verb, change it to an approved alternative. -Approved verbs can be found by running the command `Get-Verb`. +Some unapproved verbs are documented on the approved verbs page with suggested alternatives. Try +searching for the verb you're using to find its approved form. For example, `Read`, `Open`, or +`Search` should be replaced with `Get`. -For a more information about approved verbs, see [Approved Verbs for PowerShell Commands][01]. Some -unapproved verbs are documented on the approved verbs page and point to approved alternatives. Try -searching for the verb you used to find its approved form. For example, searching for `Read`, -`Open`, or `Search` leads you to `Get`. - -## How - -Change the verb in the cmdlet's name to an approved verb. +To learn more, see [Approved Verbs for PowerShell Commands][01]. ## Example -### Wrong +### Noncompliant ```powershell -function Change-Item -{ +function Change-Item { ... } ``` -### Correct +### Compliant ```powershell -function Update-Item -{ +function Update-Item { ... } ``` -[01]: /powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands +[01]: https://learn.microsoft.com/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands diff --git a/docs/Rules/UseBOMForUnicodeEncodedFile.md b/docs/Rules/UseBOMForUnicodeEncodedFile.md index e0a46b1e2..0f71bc501 100644 --- a/docs/Rules/UseBOMForUnicodeEncodedFile.md +++ b/docs/Rules/UseBOMForUnicodeEncodedFile.md @@ -1,6 +1,6 @@ --- description: Use BOM encoding for non-ASCII files -ms.date: 01/07/2025 +ms.date: 06/08/2026 ms.topic: reference title: UseBOMForUnicodeEncodedFile --- @@ -10,17 +10,18 @@ title: UseBOMForUnicodeEncodedFile ## Description -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. +This rule detects files that are encoded with Unicode or other non-ASCII formats but don't include a +Byte Order Mark (BOM). -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. +When you save files with Unicode encoding, it's important to include a BOM so that applications can +properly interpret the file's encoding. This rule helps ensure that your PowerShell scripts and +other text files are saved with the appropriate BOM when using Unicode or similar non-ASCII +encodings. -## How +### Using the Encoding parameter -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: +When you use PowerShell commands that write to files, set the **Encoding** parameter to a value that +produces a BOM. In PowerShell 7 and later, these encoding values produce a BOM: - `bigendianunicode` - `bigendianutf32` @@ -29,13 +30,26 @@ produce a BOM: - `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. +When you create a script file using a text editor, configure the editor to save the file with a BOM. +Consult your editor's documentation for instructions on how to save files with a BOM. -## Further reading +## Example -For more information, see the following articles: +### Noncompliant + +```powershell +# Writes non-ASCII text without a BOM. +Set-Content -Path .\script.ps1 -Value "Write-Output 'café'" -Encoding utf8NoBOM +``` + +### Compliant + +```powershell +# Writes non-ASCII text with a BOM. +Set-Content -Path .\script.ps1 -Value "Write-Output 'café'" -Encoding utf8BOM +``` + +## See also - [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) diff --git a/docs/Rules/UseCmdletCorrectly.md b/docs/Rules/UseCmdletCorrectly.md index 81ec42e4e..ddc24f532 100644 --- a/docs/Rules/UseCmdletCorrectly.md +++ b/docs/Rules/UseCmdletCorrectly.md @@ -1,6 +1,6 @@ --- -description: Use Cmdlet Correctly -ms.date: 06/28/2023 +description: Use cmdlets correctly +ms.date: 06/08/2026 ms.topic: reference title: UseCmdletCorrectly --- @@ -10,16 +10,13 @@ title: UseCmdletCorrectly ## Description -Whenever we call a command, care should be taken that it is invoked with the correct syntax and -parameters. - -## How - -Specify all mandatory parameters when calling commands. +This rule detects commands that are invoked without their required mandatory parameters. When you +call a command, it must be invoked with the correct syntax and all mandatory parameters specified. +Missing required parameters can cause commands to fail or behave unexpectedly. ## Example -### Wrong +### Noncompliant ```powershell Function Set-TodaysDate () @@ -29,7 +26,7 @@ Function Set-TodaysDate () } ``` -### Correct +### Compliant ```powershell Function Set-TodaysDate () diff --git a/docs/Rules/UseCompatibleCmdlets.md b/docs/Rules/UseCompatibleCmdlets.md index 4cd52340e..cc339f06d 100644 --- a/docs/Rules/UseCompatibleCmdlets.md +++ b/docs/Rules/UseCompatibleCmdlets.md @@ -1,6 +1,6 @@ --- description: Use compatible cmdlets -ms.date: 12/12/2024 +ms.date: 06/08/2026 ms.topic: reference title: UseCompatibleCmdlets --- @@ -10,41 +10,56 @@ title: UseCompatibleCmdlets ## Description -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, `--.json` where `` can be either `Core` or -`Desktop`, `` can be either `Windows`, `Linux` or `MacOS`, and `` is the PowerShell -version. To enable the rule to check if your script is compatible on PowerShell Core on windows, put -the following your settings file: +This rule detects cmdlets that aren't available for the PowerShell edition, version, and operating +system you target. The rule compares each cmdlet in your script against a compatibility allow list +that ships with PSScriptAnalyzer. These files are in the following location: +`/path/to/PSScriptAnalyzerModule/Settings`. + +Each file uses this naming format: + +`--.json` + +Where: + +- `` is `Core` or `Desktop` +- `` is the PowerShell version +- `` is `Windows`, `Linux`, `Linux-Arm`, or `MacOS` + +## Example + +To check whether your script is compatible with PowerShell Core 6.1 on Windows, add this +configuration: ```powershell @{ 'Rules' = @{ 'PSUseCompatibleCmdlets' = @{ - 'compatibility' = @('core-6.1.0-windows') + 'Compatibility' = @('core-6.1.0-windows') } } } ``` -The parameter `compatibility` is a list that contain any of the following +The **Compatibility** parameter accepts a list of one or more target identifiers, such as: - desktop-2.0-windows - desktop-3.0-windows -- desktop-4.0-windows (taken from Windows Server 2012R2) +- desktop-4.0-windows (taken from Windows Server 2012 R2) - desktop-5.1.14393.206-windows -- core-6.1.0-windows (taken from Windows 10 - 1803) +- core-6.1.0-windows (taken from Windows 10, version 1803) - core-6.1.0-linux (taken from Ubuntu 18.04) - core-6.1.0-linux-arm (taken from Raspbian) - core-6.1.0-macos -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][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. +Patched PowerShell versions usually have the same cmdlet data, so this rule mainly ships major and +minor version profiles. + +You can also create a custom profile with [New-CommandDataFile.ps1][01]. Place the generated JSON +file in the `Settings` folder of the `PSScriptAnalyzer` module. Then you can reference that file by +name under `Compatibility`. + +The `core-6.0.2-*` files were removed in PSScriptAnalyzer 1.18 because PowerShell 6.0 reached its +end of life. [01]: https://github.com/PowerShell/PSScriptAnalyzer/blob/main/Utils/New-CommandDataFile.ps1 diff --git a/docs/Rules/UseCompatibleCommands.md b/docs/Rules/UseCompatibleCommands.md index ae74862ba..e5c72b6a2 100644 --- a/docs/Rules/UseCompatibleCommands.md +++ b/docs/Rules/UseCompatibleCommands.md @@ -1,6 +1,6 @@ --- description: Use compatible commands -ms.date: 12/12/2024 +ms.date: 06/09/2026 ms.topic: reference title: UseCompatibleCommands --- @@ -10,9 +10,9 @@ title: UseCompatibleCommands ## Description -This rule identifies commands that are not available on a targeted PowerShell platform. +This rule detects commands that aren't available on your targeted PowerShell platform. -A PowerShell platform is identified by a name in the following format: +A name in the PowerShell platform is identified in the following format: ``` ______ @@ -20,12 +20,11 @@ A PowerShell platform is identified by a name in the following format: Where: -- ``: The name of the operating system PowerShell is running on. - On Windows, this includes the SKU number. - On Linux, this is the name of the distribution. -- ``: The machine architecture the operating system is running on (this is usually `x64`). -- ``: The self-reported version of the operating system (on Linux, this is the - distribution version). +- ``: The name of the operating system PowerShell is running on. On Windows, the SKU number + is included. On Linux, the value is the name of the distribution. +- ``: The machine architecture the operating system is running on (usually `x64`). +- ``: The self-reported version of the operating system (the distribution version on + Linux). - ``: The PowerShell version (from `$PSVersionTable.PSVersion`). - ``: The machine architecture of the PowerShell process. - ``: The reported version of the .NET runtime PowerShell is running on (from @@ -41,8 +40,8 @@ For example: operating system. - `ubuntu_x64_18.04_6.2.0_x64_4.0.30319.42000_core` is PowerShell 6.2.0 running on Ubuntu 18.04. -Some platforms come bundled with PSScriptAnalyzer as JSON files, named in this way for targeting in -your configuration. +PSScriptAnalyzer includes some platform profiles as JSON files. You can target these built-in +profiles directly in your configuration. Platforms bundled by default are: @@ -64,37 +63,53 @@ Platforms bundled by default are: Other profiles can be found in the [GitHub repo][02]. -You can also generate your own platform profile using the [PSCompatibilityCollector module][01]. +You can also generate your own platform profile with the [PSCompatibilityCollector module][01]. -The compatibility profile settings takes a list of platforms to target under `TargetProfiles`. A -platform can be specified as: +Compatibility settings take a list of platforms under `TargetProfiles`. You can specify each target +platform as: -- A platform name (like `ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core`), which will have `.json` - added to the end and is searched for in the default profile directory. -- A filename (like `my_custom_platform.json`), which will be searched for the in the default profile - directory. +- A platform name (for example, `ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core`). + PSScriptAnalyzer appends `.json` and searches for it in the default profile directory. +- A filename (for example, `my_custom_platform.json`), which PSScriptAnalyzer searches for in the + default profile directory. - An absolute path to a file (like `D:\PowerShellProfiles\TargetMachine.json`). -The default profile directory is under the PSScriptAnalzyer module at +The default profile directory is under the PSScriptAnalyzer module at `$PSScriptRoot/compatibility_profiles` (where `$PSScriptRoot` here refers to the directory containing `PSScriptAnalyzer.psd1`). -The compatibility analysis compares a command used to both a target profile and a 'union' profile -(containing all commands available in _any_ profile in the profile dir). If a command is not present -in the union profile, it is assumed to be locally created and ignored. Otherwise, if a command is -present in the union profile but not present in a target, it is deemed to be incompatible with that -target. +The compatibility analysis compares each command you use against both a target profile and a union +profile. The union profile contains every command available in any profile in the profile +directory. -## Configuration settings +If a command isn't in the union profile, the rule assumes it's local to your environment and ignores +it. If a command is in the union profile but missing from a target profile, the rule flags it as +incompatible with that target. -| Configuration key | Meaning | Accepted values | Mandatory | Example | -| ----------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `Enable` | Activates the rule | bool (`$true`/`$false`) | No (default: `$false`) | `$true` | -| `TargetProfiles` | The list of PowerShell profiles to target | string[]: absolute paths to profile files or names of profiles in the profile directory | No (default: `@()`) | `@('ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core', 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')` | -| `ProfileDirPath` | The location to search for profiles by name and use for union profile generation | string: absolute path to new profile dir | No (defaults to `compatibility_profiles` directory in PSScriptAnalyzer module | `C:\Users\me\Documents\pssaCompatProfiles` | -| `IgnoreCommands` | Commands to ignore compatibility of in scripts | string[]: names of commands to ignore | No (default: `@()`) | `@('Get-ChildItem','Import-Module')` | +## Example -An example configuration might look like: +The following examples assume `TargetProfiles` includes +`ubuntu_x64_18.04_6.2.4_x64_4.0.30319.42000_core` (Ubuntu 18.04, PowerShell 6.2). + +### Noncompliant + +```powershell +function Get-OsInfo { + $os = Get-WmiObject -Class Win32_OperatingSystem + return $os.Caption +} +``` + +### Compliant + +```powershell +function Get-OsInfo { + $os = Get-CimInstance -ClassName Win32_OperatingSystem + return $os.Caption +} +``` + +## Configure rule ```powershell @{ @@ -119,27 +134,51 @@ An example configuration might look like: ## Suppression -Command compatibility diagnostics can be suppressed with an attribute on the `param` block of a -scriptblock as with other rules. +As with other rules, you can suppress command compatibility diagnostics by adding a suppression +attribute to the `param` block of a scriptblock. ```powershell [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', '')] ``` -The rule can also be suppressed only for particular commands: +You can also suppress the rule for specific commands: ```powershell [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Start-Service')] ``` -And also suppressed only for parameters: +You can also suppress it for specific parameters: ```powershell [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', 'Import-Module/FullyQualifiedName')] ``` +## Parameters + +### Enable + +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. + +### TargetProfiles + +This parameter specifies the list of platform profiles to check compatibility against. It accepts +an array of strings. Each value can be a platform name, a filename, or an absolute path to a +profile file. The default value is `@()`. + +### ProfileDirPath + +This parameter controls the directory that ScriptAnalyzer searches for profiles by name and uses +to generate the union profile. It accepts a string containing an absolute path. The default +location is the `compatibility_profiles` directory in the PSScriptAnalyzer module. + +### IgnoreCommands + +This parameter specifies commands to exclude from compatibility checks. It accepts an array of +command-name strings. The default value is `@()`. + [01]: https://github.com/PowerShell/PSScriptAnalyzer/tree/main/PSCompatibilityCollector [02]: https://github.com/PowerShell/PSScriptAnalyzer/tree/main/PSCompatibilityCollector/optional_profiles diff --git a/docs/Rules/UseCompatibleSyntax.md b/docs/Rules/UseCompatibleSyntax.md index a2adbbbb6..aa1f24508 100644 --- a/docs/Rules/UseCompatibleSyntax.md +++ b/docs/Rules/UseCompatibleSyntax.md @@ -1,6 +1,6 @@ --- description: Use compatible syntax -ms.date: 06/28/2023 +ms.date: 06/09/2026 ms.topic: reference title: UseCompatibleSyntax --- @@ -10,10 +10,39 @@ title: UseCompatibleSyntax ## Description -This rule identifies syntax elements that are incompatible with targeted PowerShell versions. +This rule detects syntax elements that aren't compatible with your specified PowerShell target +versions. When you run this rule from PowerShell 3 or 4, it can't detect syntax that's incompatible +with those versions because those versions can't parse newer syntax constructs. -It cannot identify syntax elements incompatible with PowerShell 3 or 4 when run from those -PowerShell versions because they aren't able to parse the incompatible syntaxes. +## Example + +### Noncompliant + +The following example uses PowerShell 7 syntax. If `TargetVersions` includes `5.1` or earlier, this +rule flags these statements. + +```powershell +$message = $IsReady ? 'Ready' : 'Not ready' +$displayName = $name ?? 'Unknown' +``` + +### Compliant + +```powershell +if ($IsReady) { + $message = 'Ready' +} else { + $message = 'Not ready' +} + +if ($name -ne $null) { + $displayName = $name +} else { + $displayName = 'Unknown' +} +``` + +## Configure rule ```powershell @{ @@ -29,3 +58,16 @@ PowerShell versions because they aren't able to parse the incompatible syntaxes. } } ``` + +## Parameters + +### Enable + +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. + +### TargetVersions + +This parameter specifies the PowerShell versions your code must be compatible with. It accepts an +array of version strings, such as `'7.0'`, `'5.1'`, or `'4.0'`. ScriptAnalyzer flags syntax that's +not supported in any version you target. diff --git a/docs/Rules/UseCompatibleTypes.md b/docs/Rules/UseCompatibleTypes.md index 9bff5fa76..dc98ecdd3 100644 --- a/docs/Rules/UseCompatibleTypes.md +++ b/docs/Rules/UseCompatibleTypes.md @@ -1,6 +1,6 @@ --- description: Use compatible types -ms.date: 12/12/2024 +ms.date: 06/09/2026 ms.topic: reference title: UseCompatibleTypes --- @@ -10,10 +10,9 @@ title: UseCompatibleTypes ## Description -This rule identifies types that are not available (loaded by default) in targeted PowerShell -platforms. +This rule detects types that aren't available by default on your targeted PowerShell platforms. -A PowerShell platform is identified by a name in the following format: +A name in the PowerShell platform is identified in the following format: ``` ______ @@ -21,12 +20,11 @@ A PowerShell platform is identified by a name in the following format: Where: -- ``: The name of the operating system PowerShell is running on. - On Windows, this includes the SKU number. - On Linux, this is the name of the distribution. -- ``: The machine architecture the operating system is running on (this is usually `x64`). -- ``: The self-reported version of the operating system (on Linux, this is the - distribution version). +- ``: The name of the operating system PowerShell is running on. On Windows, the SKU number + is included. On Linux, the value is the name of the distribution. +- ``: The machine architecture the operating system is running on (usually `x64`). +- ``: The self-reported version of the operating system (the distribution version on + Linux). - ``: The PowerShell version (from `$PSVersionTable.PSVersion`). - ``: The machine architecture of the PowerShell process. - ``: The reported version of the .NET runtime PowerShell is running on (from @@ -42,8 +40,8 @@ For example: operating system. - `ubuntu_x64_18.04_6.2.0_x64_4.0.30319.42000_core` is PowerShell 6.2.0 running on Ubuntu 18.04. -Some platforms come bundled with PSScriptAnalyzer as JSON files, named in this way for targeting in -your configuration. +PSScriptAnalyzer includes some platform profiles as JSON files. You can target these built-in +profiles directly in your configuration. Platforms bundled by default are: @@ -65,34 +63,53 @@ Platforms bundled by default are: Other profiles can be found in the [GitHub repo][02]. -You can also generate your own platform profile using the [PSCompatibilityCollector module][01]. +You can also generate your own platform profile with the [PSCompatibilityCollector module][01]. -The compatibility profile settings takes a list of platforms to target under `TargetProfiles`. A -platform can be specified as: +Compatibility settings take a list of platforms under `TargetProfiles`. You can specify each target +platform as: -- A platform name (like `ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core`), which will have `.json` - added to the end and is searched for in the default profile directory. -- A filename (like `my_custom_platform.json`), which will be searched for the in the default profile - directory. +- A platform name (for example, `ubuntu_x64_18.04_6.1.1_x64_4.0.30319.42000_core`). + PSScriptAnalyzer appends `.json` and searches for it in the default profile directory. +- A filename (for example, `my_custom_platform.json`), which PSScriptAnalyzer searches for in the + default profile directory. - An absolute path to a file (like `D:\PowerShellProfiles\TargetMachine.json`). -The default profile directory is under the PSScriptAnalzyer module at +The default profile directory is under the PSScriptAnalyzer module at `$PSScriptRoot/PSCompatibilityCollector/profiles` (where `$PSScriptRoot` here refers to the directory containing `PSScriptAnalyzer.psd1`). -The compatibility analysis compares a type used to both a target profile and a 'union' profile -(containing all types available in _any_ profile in the profile dir). If a type is not present in -the union profile, it is assumed to be locally created and ignored. Otherwise, if a type is present -in the union profile but not present in a target, it is deemed to be incompatible with that target. +The compatibility analysis compares each type you use against both a target profile and a union +profile. The union profile contains every type available in any profile in the profile directory. -## Configuration settings +If a type isn't in the union profile, the rule assumes it's local to your environment and ignores +it. If a type is in the union profile but missing from a target profile, the rule flags it as +incompatible with that target. -| Configuration key | Meaning | Accepted values | Mandatory | Example | -| ----------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `Enable` | Activates the rule | bool (`$true`/`$false`) | No (default: `$false`) | `$true` | -| `TargetProfiles` | The list of PowerShell profiles to target | string[]: absolute paths to profile files or names of profiles in the profile directory | No (default: `@()`) | `@('ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core', 'win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework')` | -| `ProfileDirPath` | The location to search for profiles by name and use for union profile generation | string: absolute path to new profile dir | No (defaults to `compatibility_profiles` directory in PSScriptAnalyzer module | `C:\Users\me\Documents\pssaCompatProfiles` | -| `IgnoreTypes` | Full names of types or type accelerators to ignore compatibility of in scripts | string[]: names of types to ignore | No (default: `@()`) | `@('System.Collections.ArrayList','string')` | +## Example + +The following examples assume `TargetProfiles` includes +`win-48_x64_10.0.17763.0_5.1.17763.316_x64_4.0.30319.42000_framework` (Windows 10 Pro, +PowerShell 5.1). + +### Noncompliant + +`System.Management.Automation.SemanticVersion` isn't available by default in Windows PowerShell +5.1, so the rule flags this type usage for that target profile. + +```powershell +$version = [System.Management.Automation.SemanticVersion]'1.2.3' +``` + +### Compliant + +`System.Version` is available in Windows PowerShell 5.1 and PowerShell 7, so it passes +compatibility checks across those targets. + +```powershell +$version = [System.Version]'1.2.3.0' +``` + +## Configure rule An example configuration might look like: @@ -139,27 +156,51 @@ PSUseCompatibleTypes Warning 1 The type 'System.Managemen ## Suppression -Command compatibility diagnostics can be suppressed with an attribute on the `param` block of a -scriptblock as with other rules. +As with other rules, you can suppress type compatibility diagnostics by adding a suppression +attribute to the `param` block of a scriptblock. ```powershell [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes', '')] ``` -The rule can also be suppressed only for particular types: +You can also suppress the rule for specific types: ```powershell [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes', 'System.Management.Automation.Security.SystemPolicy')] ``` -And also suppressed only for type members: +You can also suppress it for specific type members: ```powershell -[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleTypes', 'System.Management.Automation.LanguagePrimitives/ConvertTypeNameToPSTypeName')] ``` +## Parameters + +### Enable + +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. + +### TargetProfiles + +This parameter specifies the list of platform profiles to check compatibility against. It accepts an +array of strings. Each value can be a platform name, a filename, or an absolute path to a profile +file. The default value is `@()`. + +### ProfileDirPath + +This parameter controls the directory that ScriptAnalyzer searches for profiles by name and uses to +generate the union profile. It accepts a string containing an absolute path. The default location is +the `compatibility_profiles` directory in the PSScriptAnalyzer module. + +### IgnoreTypes + +This parameter specifies the full names of types or type accelerators to exclude from compatibility +checks. It accepts an array of type-name strings. The default value is `@()`. + [01]: https://github.com/PowerShell/PSScriptAnalyzer/tree/main/PSCompatibilityCollector [02]: https://github.com/PowerShell/PSScriptAnalyzer/tree/main/PSCompatibilityCollector/optional_profiles diff --git a/docs/Rules/UseConsistentIndentation.md b/docs/Rules/UseConsistentIndentation.md index f084d5ac4..1bf186ee4 100644 --- a/docs/Rules/UseConsistentIndentation.md +++ b/docs/Rules/UseConsistentIndentation.md @@ -1,6 +1,6 @@ --- description: Use consistent indentation -ms.date: 06/28/2023 +ms.date: 06/09/2026 ms.topic: reference title: UseConsistentIndentation --- @@ -10,11 +10,42 @@ title: UseConsistentIndentation ## Description -Indentation should be consistent throughout the source file. +This rule detects inconsistent indentation patterns within a source file. Indentation should be +consistent throughout your script. This rule is **disabled** by default. -**Note**: This rule is not enabled by default. The user needs to enable it through settings. +## Example -## Configuration +### Noncompliant + +```powershell +function Get-ItemName { + param( + [string]$Path + ) + + if ($Path) { + Get-Item $Path | + Select-Object -ExpandProperty Name + } +} +``` + +### Compliant + +```powershell +function Get-ItemName { + param( + [string]$Path + ) + + if ($Path) { + Get-Item $Path | + Select-Object -ExpandProperty Name + } +} +``` + +## Configure rule ```powershell Rules = @{ @@ -27,21 +58,27 @@ Indentation should be consistent throughout the source file. } ``` -### Parameters +## Parameters + +### Enable -#### Enable: bool (Default value is `$false`) +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -Enable or disable the rule during ScriptAnalyzer invocation. +### IndentationSize -#### IndentationSize: int (Default value is `4`) +This parameter controls the indentation size when `Kind` is set to `space`. It accepts an integer +value. To use four spaces per indentation level, set this parameter to `4`. The default value is +`4`. -Indentation size in the number of space characters. +### PipelineIndentation -#### PipelineIndentation: string (Default value is `IncreaseIndentationForFirstPipeline`) +This parameter controls pipeline indentation for multi-line statements. It accepts a string value. +The default value is `IncreaseIndentationForFirstPipeline`. -Whether to increase indentation after a pipeline for multi-line statements. The settings are: +Acceptable values are: -- IncreaseIndentationForFirstPipeline (default): Indent once after the first pipeline and keep this +- `IncreaseIndentationForFirstPipeline`: Indent once after the first pipeline and keep this indentation. Example: ```powershell @@ -50,7 +87,7 @@ Whether to increase indentation after a pipeline for multi-line statements. The baz ``` -- IncreaseIndentationAfterEveryPipeline: Indent more after the first pipeline and keep this +- `IncreaseIndentationAfterEveryPipeline`: Indent more after the first pipeline and keep this indentation. Example: ```powershell @@ -59,7 +96,7 @@ Whether to increase indentation after a pipeline for multi-line statements. The baz ``` -- NoIndentation: Do not increase indentation. Example: +- `NoIndentation`: Don't increase indentation. Example: ```powershell foo | @@ -67,12 +104,13 @@ Whether to increase indentation after a pipeline for multi-line statements. The baz ``` -- None: Do not change any existing pipeline indentation. +- `None`: Don't change any existing pipeline indentation. -#### Kind: string (Default value is `space`) +### Kind -Represents the kind of indentation to be used. Possible values are: `space`, `tab`. If any invalid -value is given, the property defaults to `space`. +This parameter controls which indentation character ScriptAnalyzer expects. It accepts a string +value. To use spaces for indentation, set this parameter to `space`. The default value is `space`. -`space` means `IndentationSize` number of `space` characters are used to provide one level of -indentation. `tab` means a tab character, `\t`. +When `Kind` is set to `space`, ScriptAnalyzer uses the value of `IndentationSize` for each +indentation level. When `Kind` is set to `tab`, ScriptAnalyzer uses a tab character (`\t`) per +indentation level. If you provide an invalid value, ScriptAnalyzer uses `space`. diff --git a/docs/Rules/UseConsistentParameterSetName.md b/docs/Rules/UseConsistentParameterSetName.md index 6e9a4598f..d815cf891 100644 --- a/docs/Rules/UseConsistentParameterSetName.md +++ b/docs/Rules/UseConsistentParameterSetName.md @@ -1,6 +1,6 @@ --- -description: Use consistent parameter set names and proper parameter set configuration. -ms.date: 03/20/2026 +description: Use consistent parameter set names and proper parameter set configuration +ms.date: 06/09/2026 ms.topic: reference title: UseConsistentParameterSetName --- @@ -11,37 +11,41 @@ title: UseConsistentParameterSetName ## Description -Parameter set names in PowerShell are case-sensitive, unlike most other PowerShell elements. This -rule ensures consistent casing and proper configuration of parameter sets to avoid runtime errors -and improve code clarity. +This rule detects inconsistent parameter set naming and configuration issues that can cause runtime +errors. Parameter set names in PowerShell are case-sensitive, unlike most other PowerShell elements. +With this rule enabled, it's easier to debug your functions. This rule is **disabled** by default. -The rule performs five different checks: +This rule performs five different checks: 1. **Missing DefaultParameterSetName** - Warns when parameter sets are used but no default is - specified + specified. 1. **Multiple parameter declarations** - Detects when a parameter is declared multiple times in the - same parameter set. This is ultimately a runtime exception - this check helps catch it sooner. + same parameter set. This issue becomes a runtime exception, so this check catches it earlier. 1. **Case mismatch between DefaultParameterSetName and ParameterSetName** - Ensures consistent - casing + casing. 1. **Case mismatch between different ParameterSetName values** - Ensures all references to the same - parameter set use identical casing + parameter set use identical casing. 1. **Parameter set names containing newlines** - Warns against using newline characters in parameter - set names + set names. -> [!NOTE] -> This rule isn't enabled by default. The user needs to enable it through settings. - -## How +## Guidance - Use a `DefaultParameterSetName` when defining multiple parameter sets - Ensure consistent casing between `DefaultParameterSetName` and `ParameterSetName` values - Use identical casing for all references to the same parameter set name - Avoid declaring the same parameter multiple times in a single parameter set -- Do not use newline characters in parameter set names +- Don't use newline characters in parameter set names + +### Notes + +- The first occurrence of a parameter set name in your code is treated as the canonical casing +- Parameters without `[Parameter()]` attributes are automatically part of all parameter sets +- It's a PowerShell best practice to always specify a `DefaultParameterSetName` when you're using + parameter sets ## Example -### Wrong +### Noncompliant ```powershell # Missing DefaultParameterSetName @@ -98,7 +102,7 @@ function Get-Data { } ``` -### Correct +### Compliant ```powershell # Proper parameter set configuration @@ -128,17 +132,10 @@ Rules = @{ } ``` -### Parameters +## Parameters -- `Enable`: **bool** (Default value is `$false`) +### Enable - Enable or disable the rule during ScriptAnalyzer invocation. - -## Notes - -- Parameter set names are case-sensitive in PowerShell, making this different from most other - PowerShell elements -- The first occurrence of a parameter set name in your code is treated as the canonical casing -- Parameters without `[Parameter()]` attributes are automatically part of all parameter sets -- It's a PowerShell best practice to always specify a `DefaultParameterSetName` when using parameter +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To enable this rule, set this parameter to `$true`. The default value is `$false`. sets \ No newline at end of file diff --git a/docs/Rules/UseConsistentParametersKind.md b/docs/Rules/UseConsistentParametersKind.md index 20a470f30..60d36ea14 100644 --- a/docs/Rules/UseConsistentParametersKind.md +++ b/docs/Rules/UseConsistentParametersKind.md @@ -1,6 +1,6 @@ --- -description: Use the same pattern when defining parameters. -ms.date: 03/20/2026 +description: Use the same pattern when defining parameters +ms.date: 06/10/2026 ms.topic: reference title: UseConsistentParametersKind --- @@ -10,60 +10,27 @@ title: UseConsistentParametersKind ## Description -All functions should use the same pattern when defining parameters. Possible pattern types are: - -1. `Inline` - - ```powershell - function f([Parameter()]$FirstParam) { - return - } - ``` - -1. `ParamBlock` - - ```powershell - function f { - param([Parameter()]$FirstParam) - return - } - ``` - -In simple scenarios, both function definitions shown are considered to be equal. The purpose of this -rule is to enforce consistent code style across the codebase. - -## How to Fix - -Rewrite function so it defines parameters as specified in the rule +This rule detects when functions don't consistently use the same pattern for defining parameters. +All functions should use the same parameter definition pattern to enforce consistent code style +across the codebase. Rewrite any function that doesn't match the configured parameter definition +kind. In simple scenarios, both the `Inline` and `ParamBlock` function definition patterns are +functionally equivalent. ## Example -When the rule sets parameters definition kind to `Inline`: +### Noncompliant ```powershell -# Correct function f([Parameter()]$FirstParam) { return } - -# Incorrect -function g { - param([Parameter()]$FirstParam) - return -} ``` -When the rule sets parameters definition kind to `ParamBlock`: +### Compliant ```powershell -# Incorrect -function f([Parameter()]$FirstParam) { - return -} - -# Correct function g { param([Parameter()]$FirstParam) return } -``` \ No newline at end of file +``` diff --git a/docs/Rules/UseConsistentWhitespace.md b/docs/Rules/UseConsistentWhitespace.md index e36c42783..5531d2ebb 100644 --- a/docs/Rules/UseConsistentWhitespace.md +++ b/docs/Rules/UseConsistentWhitespace.md @@ -1,6 +1,6 @@ --- -description: Use whitespaces -ms.date: 06/28/2023 +description: Use consistent whitespace in PowerShell code +ms.date: 06/10/2026 ms.topic: reference title: UseConsistentWhitespace --- @@ -10,9 +10,27 @@ title: UseConsistentWhitespace ## Description -This rule is not enabled by default. The user needs to enable it through settings. +This rule detects inconsistent or redundant whitespace around braces, parentheses, operators, +separators, pipes, and parameter values. Use this rule to keep PowerShell code readable and +consistently formatted. This rule is **disabled** by default. -## Configuration +## Example + +### Noncompliant + +```powershell +if($true) {foo| ForEach-Object{ $_ -eq 1}} +@{a = 1;b = 2} +``` + +### Compliant + +```powershell +if ($true) { foo | ForEach-Object { $_ -eq 1 } } +@{a = 1; b = 2} +``` + +## Configure rule ```powershell Rules = @{ @@ -31,55 +49,63 @@ Rules = @{ } ``` -### Enable: bool (Default value is `$false`) +## Parameters + +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks code against this rule. It accepts a boolean +value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -### CheckInnerBrace: bool (Default value is `$true`) +### CheckInnerBrace -Checks if there is a space after the opening brace and a space before the closing brace. E.g. -`if ($true) { foo }` instead of `if ($true) {bar}`. +This parameter checks whether there's a space after an opening brace and a space before a closing +brace. For example, it prefers `if ($true) { foo }` over `if ($true) {bar}`. The default value is +`$true`. -### CheckOpenBrace: bool (Default value is `$true`) +### CheckOpenBrace -Checks if there is a space between a keyword and its corresponding open brace. E.g. `foo { }` -instead of `foo{ }`. If an open brace is preceded by an open parenthesis, then no space is required. +This parameter checks whether there's a space between a keyword and its corresponding opening brace. +For example, it prefers `foo { }` over `foo{ }`. No space is required if an open brace precedes an +open parenthesis. The default value is `$true`. -### CheckOpenParen: bool (Default value is `$true`) +### CheckOpenParen -Checks if there is space between a keyword and its corresponding open parenthesis. E.g. `if (true)` -instead of `if(true)`. +This parameter checks whether there's a space between a keyword and its corresponding opening +parenthesis. For example, it prefers `if (true)` over `if(true)`. The default value is `$true`. -### CheckOperator: bool (Default value is `$true`) +### CheckOperator -Checks if a binary or unary operator is surrounded on both sides by a space. E.g. `$x = 1` instead -of `$x=1`. +This parameter checks whether binary or unary operators are surrounded by spaces. For example, it +prefers `$x = 1` over `$x=1`. The default value is `$true`. -### CheckSeparator: bool (Default value is `$true`) +### CheckSeparator -Checks if a comma or a semicolon is followed by a space. E.g. `@(1, 2, 3)` or `@{a = 1; b = 2}` -instead of `@(1,2,3)` or `@{a = 1;b = 2}`. +This parameter checks whether commas and semicolons are followed by a space. For example, it prefers +`@(1, 2, 3)` over `@(1,2,3)` and `@{a = 1; b = 2}` over `@{a = 1;b = 2}`. The default value is +`$true`. -### CheckPipe: bool (Default value is `$true`) +### CheckPipe -Checks if a pipe is surrounded on both sides by a space but ignores redundant whitespace. E.g. -`foo | bar` instead of `foo|bar`. +This parameter checks whether a pipe is surrounded by a single space on each side, while ignoring +redundant whitespace. For example, it prefers `foo | bar` over `foo|bar`. The default value is +`$true`. -### CheckPipeForRedundantWhitespace : bool (Default value is `$false`) +### CheckPipeForRedundantWhitespace -Checks if a pipe is surrounded by redundant whitespace (i.e. more than 1 whitespace). E.g. -`foo | bar` instead of `foo | bar`. +This parameter checks whether a pipe is surrounded by redundant whitespace, meaning more than one +space. For example, it prefers `foo | bar` over `foo | bar`. The default value is `$false`. -### CheckParameter: bool (Default value is `$false` at the moment due to the setting being new) +### CheckParameter -Checks if there is more than one space between parameters and values. E.g. `foo -bar $baz -bat` -instead of `foo -bar $baz -bat`. This eliminates redundant whitespace that was probably added -unintentionally. The rule does not check for whitespace between parameter and value when the colon -syntax `-ParameterName:$ParameterValue` is used as some users prefer either 0 or 1 whitespace in -this case. +This parameter checks whether there's more than one space between parameters and values. For +example, it prefers `foo -bar $baz -bat` over `foo -bar $baz -bat`, which helps remove +redundant whitespace that was likely added unintentionally. The rule doesn't check whitespace +between a parameter and value when the colon syntax `-ParameterName:$ParameterValue` is used, +because some users prefer either zero or one space in that case. The default value is `$false`. -### IgnoreAssignmentOperatorInsideHashTable: bool (Default value is `$false`) +### IgnoreAssignmentOperatorInsideHashTable -When `CheckOperator` is set, ignore whitespace around assignment operators within multi-line hash -tables. Set this option to use the `AlignAssignmentStatement` rule and still check whitespace around -operators everywhere else. +When `CheckOperator` is enabled, this parameter ignores whitespace around assignment operators +within multi-line hash tables. Use it with the `AlignAssignmentStatement` rule when you want to +align assignments in hash tables but still check operator whitespace everywhere else. The default +value is `$false`. diff --git a/docs/Rules/UseConstrainedLanguageMode.md b/docs/Rules/UseConstrainedLanguageMode.md index e12476531..81c735481 100644 --- a/docs/Rules/UseConstrainedLanguageMode.md +++ b/docs/Rules/UseConstrainedLanguageMode.md @@ -1,6 +1,6 @@ --- -description: Use patterns compatible with Constrained Language Mode -ms.date: 03/20/2026 +description: Use patterns compatible with Constrained Language Mode (CLM) +ms.date: 06/10/2026 ms.topic: reference title: UseConstrainedLanguageMode --- @@ -10,13 +10,15 @@ title: UseConstrainedLanguageMode ## Description -This rule identifies PowerShell patterns that are restricted or not permitted in Constrained -Language Mode (CLM). +This rule detects PowerShell patterns that are restricted or not permitted in Constrained Language +Mode (CLM). Use it when scripts must remain compatible with restricted PowerShell environments such +as App Control for Business, AppLocker, or Just Enough Administration (JEA) endpoints. This rule is +**disabled** by default. -Constrained Language Mode is a PowerShell security feature that restricts: +CLM is a PowerShell security feature that restricts: - .NET types that can be used -- COM objects that can be instantiated +- Component Object Model (COM) objects that can be instantiated - Commands that can be executed - Language features that can be used @@ -24,144 +26,43 @@ CLM is commonly used in: - Application Control environments (Application Control for Business, AppLocker) - Just Enough Administration (JEA) endpoints -- Secure environments requiring additional PowerShell restrictions +- Secure environments requiring other PowerShell restrictions -Digitally signed scripts from trusted publishers execute in Full Language Mode (FLM) even in CLM -environments. The rule detects signature blocks (`# SIG # Begin signature block`) and adjusts checks -accordingly. Most restrictions don't apply to signed scripts, but certain checks (dot-sourcing, -parameter types, manifest best practices) are always enforced. +Digitally signed scripts from trusted publishers run in Full Language Mode (FLM), even in CLM +environments. The rule detects signature blocks (`# SIG # Begin signature block`) and adjusts its +checks accordingly. Most restrictions don't apply to signed scripts, but some checks are still +enforced. > [!IMPORTANT] -> The rule performs a simple text check for signature blocks and does NOT validate signature -> authenticity or certificate trust. Actual signature validation is performed by PowerShell at -> runtime. - -## Constrained Language Mode Restrictions - -### Unsigned Scripts (Full CLM Checking) - -The following are flagged for unsigned scripts: - -1. **Add-Type** - Code compilation not permitted -1. **Disallowed COM Objects** - Only Scripting.Dictionary, Scripting.FileSystemObject, - VBScript.RegExp allowed -1. **Disallowed .NET Types** - Only ~70 allowed types (string, int, hashtable, pscredential, etc.) -1. **Type Constraints** - On parameters and variables -1. **Type Expressions** - Static type references like `[Type]::Method()` -1. **Type Casts** - Converting to disallowed types -1. **Member Invocations** - Methods/properties on disallowed types -1. **PowerShell Classes** - `class` keyword not permitted -1. **XAML/WPF** - Not permitted -1. **Invoke-Expression** - Restricted -1. **Dot-Sourcing** - May be restricted depending on the file being sourced -1. **Module Manifest Wildcards** - Wildcard exports not recommended -1. **Module Manifest .ps1 Files** - Script modules ending with .ps1 not allowed - -Always enforced, even for signed scripts - -### Signed Scripts (Selective Checking) - -For scripts with signature blocks, only these are checked: - -- Dot-sourcing -- Parameter type constraints -- Module manifest wildcards (.psd1 files) -- Module manifest script modules (.psd1 files) - -## Configuration - -### Basic Configuration - -```powershell -@{ - Rules = @{ - PSUseConstrainedLanguageMode = @{ - Enable = $true - } - } -} -``` - -### Parameters - -#### Enable: bool (Default value is `$false`) - -Enable or disable the rule during ScriptAnalyzer invocation. This rule is disabled by default -because not all scripts need CLM compatibility. - -#### IgnoreSignatures: bool (Default value is `$false`) - -Control signature detection behavior: - -- `$false` (default): Automatically detect signatures. Signed scripts get selective checking, - unsigned get full checking. -- `$true`: Bypass signature detection. ALL scripts get full CLM checking regardless of signature - status. - -```powershell -@{ - Rules = @{ - PSUseConstrainedLanguageMode = @{ - Enable = $true - IgnoreSignatures = $true # Enforce full CLM compliance for all scripts - } - } -} -``` - -Use `IgnoreSignatures = $true` when: - -- Auditing signed scripts for complete CLM compatibility -- Preparing scripts for untrusted environments -- Enforcing strict CLM compliance organization-wide -- Development/testing to see all potential issues - -## How to Fix - -### Replace Add-Type - -Use allowed cmdlets or pre-compile assemblies. - -### Replace Disallowed COM Objects - -Use only allowed COM objects (Scripting.Dictionary, Scripting.FileSystemObject, VBScript.RegExp) or -PowerShell cmdlets. - -### Replace Disallowed Types - -Use allowed type accelerators (`[string]`, `[int]`, `[hashtable]`, etc.) or allowed cmdlets instead -of disallowed .NET types. - -### Replace PowerShell Classes - -Use `New-Object PSObject` with `Add-Member` or hashtables instead of classes. - -> [!IMPORTANT] -> `[PSCustomObject]@{}` syntax is NOT allowed in CLM because it uses type casting. - -### Avoid XAML - -Don't use WPF/XAML in CLM-compatible scripts. - -### Replace Invoke-Expression - -Use direct execution (`&`) or safer alternatives. - -### Replace Dot-Sourcing - -Use modules with Import-Module instead of dot-sourcing when possible. - -### Fix Module Manifests - -- Replace wildcard exports (`*`) with explicit lists. -- Use `.psm1` or `.dll` instead of `.ps1` for RootModule/NestedModules. -- Don't use `ScriptsToProcess`. These scripts are loaded in the caller's scope and are blocked. +> The rule performs a simple text check for signature blocks and doesn't validate signature +> authenticity or certificate trust. PowerShell performs actual signature validation at runtime. + +## CLM restriction and remediation reference + +Use the following table for a consolidated view of each CLM restriction, what it means, the +recommended remediation, and whether checks apply to signed scripts, unsigned scripts, or both. + +| Restriction | What it means | Recommended remediation | Enforced for | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| Add-Type | `Add-Type` compiles arbitrary C# code, which isn't permitted in CLM. | Use allowed cmdlets, or precompile, sign, and load assemblies. | Unsigned scripts only | +| Disallowed COM objects | Only `Scripting.Dictionary`, `Scripting.FileSystemObject`, and `VBScript.RegExp` are allowed. Other COM objects (for example, `Excel.Application`) are flagged. | Use one of the allowed COM objects, or replace COM usage with PowerShell cmdlets. | Unsigned scripts only | +| Disallowed .NET types | Only about 70 .NET and type-accelerator types are allowed. These types include common primitives, selected collections, PowerShell-specific types, utilities, and arrays of allowed types. | Replace disallowed types with allowed accelerators such as `[string]`, `[int]`, and `[hashtable]`, or use cmdlets that avoid direct disallowed type usage. | Parameter type constraints are always enforced; other .NET type checks apply to unsigned scripts only | +| Type constraints | Type constraints on parameters and variables are checked for CLM compatibility. | Use allowed types in constraints, especially in parameter declarations. | Parameter constraints are always enforced; variable constraints are unsigned scripts only | +| Type expressions | Static references such as `[Type]::Method()` are flagged when they use disallowed types. | Replace with CLM-compatible cmdlet-based patterns or allowed type usage. | Unsigned scripts only | +| Type casts | Casts to disallowed types are flagged. | Remove the cast or cast to an allowed type. | Unsigned scripts only | +| Member invocations | Method or property calls on disallowed typed objects are flagged. | Use allowed types and CLM-compatible cmdlets instead of disallowed typed objects. | Unsigned scripts only | +| PowerShell classes | The `class` keyword isn't permitted in CLM. | Use `New-Object PSObject` with `Add-Member` or use hashtables. Avoid `[PSCustomObject]@{}` because it uses type casting. | Unsigned scripts only | +| XAML or WPF | XAML or WPF usage isn't permitted in CLM. | Avoid XAML and WPF in CLM-compatible scripts. | Unsigned scripts only | +| Invoke-Expression | `Invoke-Expression` is restricted in CLM. | Use direct invocation (`&`) or safer alternatives. | Unsigned scripts only | +| Dot-sourcing | Dot-sourcing can be restricted depending on the source location. | Prefer modules and `Import-Module` over dot-sourcing where possible. | All scripts (signed and unsigned) | +| Module manifest wildcards | Wildcards in `FunctionsToExport`, `CmdletsToExport`, `AliasesToExport`, or `VariablesToExport` aren't recommended and can be blocked in CLM contexts. | Replace `*` with explicit export lists. | All `.psd1` files (signed and unsigned) | +| Module manifest `.ps1` files | Attempts to use `.ps1` for `RootModule`, `ModuleToProcess`, or `NestedModules` isn't CLM-friendly. | Use `.psm1` (script module) or `.dll` (binary module). Avoid `ScriptsToProcess`. | All `.psd1` files (signed and unsigned) | ## Examples -### Example 1: Add-Type +### Add-Type -#### Wrong +#### Noncompliant ```powershell Add-Type -TypeDefinition @" @@ -171,24 +72,24 @@ Add-Type -TypeDefinition @" "@ ``` -#### Correct +#### Compliant ```powershell - # Code sign your scripts/modules using proper signing tools - # (for example, Set-AuthenticodeSignature or external signing processes) - # Use allowed cmdlets instead of Add-Type-defined types where possible - # Or pre-compile, sign, and load the assembly (for example, via Add-Type -Path) +# Sign your scripts or modules by using appropriate signing tools +# (for example, Set-AuthenticodeSignature or an external signing process). +# Use allowed cmdlets instead of Add-Type-defined types where possible. +# Or precompile, sign, and load the assembly (for example, by using Add-Type -Path). ``` -### Example 2: COM Objects +### COM objects -#### Wrong +#### Noncompliant ```powershell $excel = New-Object -ComObject Excel.Application ``` -#### Correct +#### Compliant ```powershell # Use allowed COM object @@ -198,9 +99,9 @@ $dict = New-Object -ComObject Scripting.Dictionary Import-Excel -Path $file # From ImportExcel module ``` -### Example 3: Disallowed Types +### Disallowed types -#### Wrong +#### Noncompliant ```powershell # Type constraint and member invocation flagged @@ -214,7 +115,7 @@ function Download-File { $data = $client.DownloadData($url) ``` -#### Correct +#### Compliant ```powershell # Use allowed cmdlets @@ -230,9 +131,9 @@ function Process-Text { } ``` -### Example 4: PowerShell Classes +### PowerShell classes -#### Wrong +#### Noncompliant ```powershell class MyClass { @@ -249,7 +150,7 @@ $obj = [PSCustomObject]@{ } ``` -#### Correct +#### Compliant ```powershell # Option 1: New-Object PSObject with Add-Member @@ -270,9 +171,9 @@ $obj = @{ } ``` -### Example 5: Module Manifests +### Module manifests -#### Wrong +#### Noncompliant ```powershell @{ @@ -283,7 +184,7 @@ $obj = @{ } ``` -#### Correct +#### Compliant ```powershell @{ @@ -297,16 +198,16 @@ $obj = @{ } ``` -### Example 6: Array Types +### Array types -#### Wrong +#### Noncompliant ```powershell # Disallowed type in array param([System.Net.WebClient[]]$Clients) ``` -#### Correct +#### Compliant ```powershell # Allowed types in arrays are fine @@ -315,92 +216,62 @@ param([int[]]$Numbers) param([hashtable[]]$Configuration) ``` -## Detailed Restrictions - -### 1. Add-Type - -`Add-Type` allows compiling arbitrary C# code and isn't permitted in CLM. - -**Enforced For**: Unsigned scripts only - -### 2. COM Objects - -Only three COM objects are allowed: - -- `Scripting.Dictionary` -- `Scripting.FileSystemObject` -- `VBScript.RegExp` - -All others (Excel.Application, WScript.Shell, etc.) are flagged. - -**Enforced For**: Unsigned scripts only - -### 3. .NET Types - -Only ~70 allowed types including: - -- Primitives: `string`, `int`, `bool`, `byte`, `char`, `datetime`, `decimal`, `double`, etc. -- Collections: `hashtable`, `array`, `arraylist` -- PowerShell: `pscredential`, `psobject`, `securestring` -- Utilities: `regex`, `guid`, `version`, `uri`, `xml` -- Arrays: `string[]`, `int[][]`, etc. (array of any allowed type) - -The rule checks type usage in: - -- Parameter type constraints (**always enforced, even for signed scripts**) -- Variable type constraints -- New-Object -TypeName -- Type expressions (`[Type]::Method()`) -- Type casts (`[Type]$variable`) -- Member invocations on typed variables - -**Enforced For**: Parameter constraints always; others unsigned only - -### 4. PowerShell Classes - -The `class` keyword is not permitted. Use `New-Object PSObject` with `Add-Member` or hashtables. - -**Note**: `[PSCustomObject]@{}` is also not allowed because it uses type casting. - -**Enforced For**: Unsigned scripts only - -### 5. XAML/WPF - -XAML and WPF are not permitted in CLM. +## Configure rule -**Enforced For**: Unsigned scripts only - -### 6. Invoke-Expression - -`Invoke-Expression` is restricted in CLM. - -**Enforced For**: Unsigned scripts only +```powershell +@{ + Rules = @{ + PSUseConstrainedLanguageMode = @{ + Enable = $true + } + } +} +``` -### 7. Dot-Sourcing +## Parameters -Dot-sourcing (`. $PSScriptRoot\script.ps1`) may be restricted depending on source location. +### Enable -**Enforced For**: ALL scripts (unsigned and signed) +This parameter controls whether ScriptAnalyzer checks code against this rule. It accepts a boolean +value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -### 8. Module Manifest Best Practices +### IgnoreSignatures -#### Wildcard Exports +This parameter controls how the rule handles signature detection. It accepts a boolean value. The +default value is `$false`. -Don't use `*` in: `FunctionsToExport`, `CmdletsToExport`, `AliasesToExport`, `VariablesToExport` +When this parameter is set to `$false`, ScriptAnalyzer automatically detects whether a script is +signed. Signed scripts get selective CLM checking, and unsigned scripts get full CLM checking. -Use explicit lists for security and clarity. +When this parameter is set to `$true`, ScriptAnalyzer skips signature detection and applies full CLM +checking to all scripts, regardless of signature status. -**Enforced For**: ALL .psd1 files (unsigned and signed) +The behavior is: -#### Script Module Files +- `$false` (default): Automatically detect signatures. Signed scripts receive selective checking. + Unsigned scripts receive full checks. +- `$true`: Bypass signature detection. All scripts get full CLM checking regardless of signature + status. -Don't use `.ps1` files in: `RootModule`, `ModuleToProcess`, `NestedModules` +```powershell +@{ + Rules = @{ + PSUseConstrainedLanguageMode = @{ + Enable = $true + IgnoreSignatures = $true # Enforce full CLM compliance for all scripts + } + } +} +``` -Use `.psm1` (script modules) or `.dll` (binary modules) for better performance and compatibility. +Use `IgnoreSignatures = $true` when: -**Enforced For**: ALL .psd1 files (unsigned and signed) +- Auditing signed scripts for complete CLM compatibility +- Preparing scripts for untrusted environments +- Enforcing strict CLM compliance organization-wide +- During development and testing, to see all potential issues -## More Information +## See also - [About Language Modes][01] - [PowerShell Constrained Language Mode][03] diff --git a/docs/Rules/UseCorrectCasing.md b/docs/Rules/UseCorrectCasing.md index b73df6415..f82f51cc1 100644 --- a/docs/Rules/UseCorrectCasing.md +++ b/docs/Rules/UseCorrectCasing.md @@ -1,6 +1,6 @@ --- -description: Use exact casing of cmdlet/function/parameter name. -ms.date: 03/19/2025 +description: Use exact casing for cmdlet names, functions, and parameters +ms.date: 06/10/2026 ms.topic: reference title: UseCorrectCasing --- @@ -10,17 +10,42 @@ title: UseCorrectCasing ## Description -This is a style/formatting rule. PowerShell is case insensitive wherever possible, so the casing of -cmdlet names, parameters, keywords and operators doesn't matter. This rule nonetheless ensures -consistent casing for clarity and readability. Using lowercase keywords helps distinguish them from -commands. Using lowercase operators helps distinguish them from parameters. +This rule detects inconsistent casing in cmdlet names, parameters, type names, keywords, and +operators. PowerShell is case-insensitive wherever possible, so the casing of cmdlet names, +parameters, keywords, and operators don't affect functionality. -## How +However, this rule ensures consistent casing for clarity and readability. Using lowercase keywords +helps distinguish them from commands, while using lowercase operators helps distinguish them from +parameters. + +To follow this rule: - Use exact casing for type names. -- Use exact casing of the cmdlet and its parameters. +- Use exact casing for cmdlet and parameter names. - Use lowercase for language keywords and operators. +## Example + +### Noncompliant + +```powershell +ForEach ($file in Get-childitem -Recurse) { + $file.Extension -EQ '.txt' +} + +invoke-command { 'foo' } -runasadministrator +``` + +### Compliant + +```powershell +foreach ($file in Get-ChildItem -Recurse) { + $file.Extension -eq '.txt' +} + +Invoke-Command { 'foo' } -RunAsAdministrator +``` + ## Configuration ```powershell @@ -36,40 +61,22 @@ Rules = @{ ## Parameters -### Enable: bool (Default value is `$false`) +### Enable -Enable or disable the rule during ScriptAnalyzer invocation. +This parameter controls whether ScriptAnalyzer checks code against this rule. It accepts a boolean +value. To enable this rule, set this parameter to `$true`. The default value is `$false`. -### CheckCommands: bool (Default value is `$true`) +### CheckCommands -If true, require the case of all command and parameter names to match their canonical casing. +This parameter controls whether ScriptAnalyzer checks that the casing of all command and parameter +names matches their canonical casing. It accepts a boolean value. The default value is `$true`. -### CheckKeyword: bool (Default value is `$true`) +### CheckKeyword -If true, require the case of all keywords to be lowercase. +This parameter controls whether ScriptAnalyzer checks that all language keywords are lowercase. It +accepts a boolean value. The default value is `$true`. -### CheckOperator: bool (Default value is `$true`) +### CheckOperator -If true, require the case of all operators to be lowercase. For example: `-eq`, `-ne`, `-gt` - -## Examples - -### Wrong way - -```powershell -ForEach ($file in Get-childitem -Recurse) { - $file.Extension -EQ '.txt' -} - -invoke-command { 'foo' } -runasadministrator -``` - -### Correct way - -```powershell -foreach ($file in Get-ChildItem -Recurse) { - $file.Extension -eq '.txt' -} - -Invoke-Command { 'foo' } -RunAsAdministrator -``` +This parameter controls whether ScriptAnalyzer checks that all operators are lowercase. For example, +`-eq`, `-ne`, and `-gt`. It accepts a boolean value. The default value is `$true`. diff --git a/docs/Rules/UseDeclaredVarsMoreThanAssignments.md b/docs/Rules/UseDeclaredVarsMoreThanAssignments.md index e316dbf85..8a86d1dca 100644 --- a/docs/Rules/UseDeclaredVarsMoreThanAssignments.md +++ b/docs/Rules/UseDeclaredVarsMoreThanAssignments.md @@ -1,6 +1,6 @@ --- -description: Extra Variables -ms.date: 03/06/2024 +description: Detect variables that are assigned but never used +ms.date: 06/10/2026 ms.topic: reference title: UseDeclaredVarsMoreThanAssignments --- @@ -10,19 +10,13 @@ title: UseDeclaredVarsMoreThanAssignments ## Description -Variables that are assigned but not used are not needed. - -> [!NOTE] -> For this rule, the variable must be used within the same scriptblock that it was declared or it -> won't be considered to be 'used'. - -## How - -Remove the variables that are declared but not used. +This rule detects variables that are assigned a value but never used. A variable counts as "used" +only when code references it in the same script block as its assignment. Variables that exist only +as assignments add noise to the code and should be removed. ## Example -### Wrong +### Noncompliant ```powershell function Test @@ -33,7 +27,7 @@ function Test } ``` -### Correct +### Compliant ```powershell function Test @@ -43,13 +37,13 @@ function Test } ``` -### Special cases +## Special cases The following examples trigger the **PSUseDeclaredVarsMoreThanAssignments** warning. This behavior -is a limitation of the rule. There is no way to avoid these false positive warnings. +is a limitation of the rule. There's no way to avoid these false positive warnings. -In this case, the warning is triggered because `$bar` is not used within the scriptblock where it -was defined. +In this case, the warning is triggered because `$bar` isn't used within the scriptblock where it was +defined. ```powershell $foo | ForEach-Object { diff --git a/docs/Rules/UseLiteralInitializerForHashtable.md b/docs/Rules/UseLiteralInitializerForHashtable.md index 16f9a2f9b..584b96afc 100644 --- a/docs/Rules/UseLiteralInitializerForHashtable.md +++ b/docs/Rules/UseLiteralInitializerForHashtable.md @@ -1,6 +1,6 @@ --- description: Create hashtables with literal initializers -ms.date: 06/28/2023 +ms.date: 06/11/2026 ms.topic: reference title: UseLiteralInitializerForHashtable --- @@ -10,33 +10,23 @@ title: UseLiteralInitializerForHashtable ## Description -Creating a hashtable using `[hashtable]::new()` or `New-Object -TypeName hashtable` without passing -a `IEqualityComparer` object to the constructor creates a hashtable where the keys are looked-up in -a case-sensitive manner. However, PowerShell is case-insensitive in nature and it is best to create -hashtables with case-insensitive key look-up. +This rule detects hashtables created using the `[hashtable]::new()` method or the `New-Object +-TypeName hashtable` cmdlet without passing an `IEqualityComparer` object. When you create a +hashtable using `[hashtable]::new()` or `New-Object -TypeName hashtable`, the keys are looked up in +a case-sensitive manner by default. -This rule is intended to warn the author of the case-sensitive nature of the hashtable when created -using the `new` method or the `New-Object` cmdlet. - -## How to Fix - -Create the hashtable using a literal hashtable expression. +However, PowerShell is case-insensitive in nature, and hashtables should maintain this behavior. To +ensure consistent case-insensitive key lookup, use literal hashtable expressions instead. ## Example -### Wrong +### Noncompliant ```powershell $hashtable = [hashtable]::new() ``` -### Wrong - -```powershell -$hashtable = New-Object -TypeName hashtable -``` - -### Correct +### Compliant ```powershell $hashtable = @{} diff --git a/docs/Rules/UseOutputTypeCorrectly.md b/docs/Rules/UseOutputTypeCorrectly.md index 733425fdd..f43451e37 100644 --- a/docs/Rules/UseOutputTypeCorrectly.md +++ b/docs/Rules/UseOutputTypeCorrectly.md @@ -1,6 +1,6 @@ --- -description: Use OutputType Correctly -ms.date: 06/28/2023 +description: Use the OutputType attribute correctly +ms.date: 06/11/2026 ms.topic: reference title: UseOutputTypeCorrectly --- @@ -10,18 +10,17 @@ title: UseOutputTypeCorrectly ## Description -A command should return the same type as declared in `OutputType`. +This rule detects when a function or script returns a different type than what is declared in the +`OutputType` attribute. A function should return values that match the types specified in its +`OutputType` attribute. -You can get more details by running `Get-Help about_Functions_OutputTypeAttribute` command in -PowerShell. - -## How - -Specify that the OutputType attribute lists and the types returned in the cmdlet match. +The `OutputType` attribute documents what type of output a function produces, and the actual return +values should comply with this declaration. To learn more, see +[about_Functions_OutputTypeAttribute][01]. ## Example -### Wrong +### Noncompliant ```powershell function Get-Foo @@ -34,7 +33,7 @@ function Get-Foo } ``` -### Correct +### Compliant ```powershell function Get-Foo @@ -47,3 +46,6 @@ function Get-Foo return 'four' } ``` + + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_outputtypeattribute diff --git a/docs/Rules/UsePSCredentialType.md b/docs/Rules/UsePSCredentialType.md index c962762ed..55197630c 100644 --- a/docs/Rules/UsePSCredentialType.md +++ b/docs/Rules/UsePSCredentialType.md @@ -1,6 +1,6 @@ --- -description: Use PSCredential type. -ms.date: 06/28/2023 +description: Use PSCredential type +ms.date: 06/11/2026 ms.topic: reference title: UsePSCredentialType --- @@ -10,16 +10,14 @@ title: UsePSCredentialType ## Description -If the cmdlet or function has a **Credential** parameter, the parameter must accept the -**PSCredential** type. - -## How - -Change the **Credential** parameter's type to be **PSCredential**. +This rule detects when a cmdlet or function defines a **Credential** parameter with a type other +than **PSCredential**. Credential parameters should always use the **PSCredential** type to ensure +proper handling of secure credential objects. Change any **Credential** parameter's type to +**PSCredential** for consistency and security. ## Example -### Wrong +### Noncompliant ```powershell function Credential([String]$Credential) @@ -28,7 +26,7 @@ function Credential([String]$Credential) } ``` -### Correct +### Compliant ```powershell function Credential([PSCredential]$Credential) diff --git a/docs/Rules/UseProcessBlockForPipelineCommand.md b/docs/Rules/UseProcessBlockForPipelineCommand.md index 2e5630880..8c12c0a6a 100644 --- a/docs/Rules/UseProcessBlockForPipelineCommand.md +++ b/docs/Rules/UseProcessBlockForPipelineCommand.md @@ -1,6 +1,6 @@ --- -description: Use process block for command that accepts input from pipeline. -ms.date: 06/28/2023 +description: Use process block for commands that accept input from a pipeline +ms.date: 06/11/2026 ms.topic: reference title: UseProcessBlockForPipelineCommand --- @@ -10,13 +10,15 @@ title: UseProcessBlockForPipelineCommand ## Description -Functions that support pipeline input should always handle parameter input in a process block. -Unexpected behavior can result if input is handled directly in the body of a function where -parameters declare pipeline support. +This rule detects functions with pipeline-enabled parameters that handle input directly in the +function body instead of using a process block. Functions that accept pipeline input through +parameters should always process that input in a process block. Handling parameter input directly in +the function body can lead to unexpected behavior because the function body executes once, while the +process block executes for each object in the pipeline. ## Example -### Wrong +### Noncompliant ```powershell Function Get-Number @@ -32,14 +34,7 @@ Function Get-Number } ``` -#### Result - -``` -PS C:\> 1..5 | Get-Number -5 -``` - -### Correct +### Compliant ```powershell Function Get-Number @@ -57,14 +52,3 @@ Function Get-Number } } ``` - -#### Result - -``` -PS C:\> 1..5 | Get-Number -1 -2 -3 -4 -5 -``` diff --git a/docs/Rules/UseShouldProcessForStateChangingFunctions.md b/docs/Rules/UseShouldProcessForStateChangingFunctions.md index 97bb97767..7e522a51c 100644 --- a/docs/Rules/UseShouldProcessForStateChangingFunctions.md +++ b/docs/Rules/UseShouldProcessForStateChangingFunctions.md @@ -1,6 +1,6 @@ --- -description: Use ShouldProcess For State Changing Functions -ms.date: 12/05/2024 +description: Use ShouldProcess for state changing functions +ms.date: 06/11/2026 ms.topic: reference title: UseShouldProcessForStateChangingFunctions --- @@ -10,12 +10,18 @@ title: UseShouldProcessForStateChangingFunctions ## Description -Functions whose verbs change system state should support `ShouldProcess`. To enable the -`ShouldProcess` feature, set the `SupportsShouldProcess` argument in the `CmdletBinding` attribute. -The `SupportsShouldProcess` argument adds **Confirm** and **WhatIf** parameters to the function. The -**Confirm** parameter prompts the user before it runs the command on each object in the pipeline. -The **WhatIf** parameter lists the changes that the command would make, instead of running the -command. +This rule detects functions with state-changing verbs that don't support `ShouldProcess`. Functions +whose verbs change system state should support `ShouldProcess` to provide users with the ability to +confirm or preview changes before execution. To enable this feature, set the `SupportsShouldProcess` +argument to `$true` in the `CmdletBinding` attribute. + +The `SupportsShouldProcess` argument automatically adds the **Confirm** and **WhatIf** parameters to +your function: + +- The **Confirm** parameter prompts the user to confirm the command before it runs on each object in + the pipeline. +- The **WhatIf** parameter displays the changes the command would make without actually running the + command. Verbs that should support `ShouldProcess`: @@ -28,13 +34,9 @@ Verbs that should support `ShouldProcess`: - `Reset` - `Update` -## How - -Include the `SupportsShouldProcess` argument in the `CmdletBinding` attribute. - ## Example -### Wrong +### Noncompliant ```powershell function Set-ServiceObject @@ -49,7 +51,7 @@ function Set-ServiceObject } ``` -### Correct +### Compliant ```powershell function Set-ServiceObject @@ -64,12 +66,12 @@ function Set-ServiceObject } ``` -## More information +## See also - [about_Functions_CmdletBindingAttribute][01] - [Everything you wanted to know about ShouldProcess][04] -- [Required Development Guidelines][03] -- [Requesting Confirmation from Cmdlets][02] +- [Required development guidelines][03] +- [Requesting confirmation from cmdlets][02] [01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_cmdletbindingattribute diff --git a/docs/Rules/UseSingleValueFromPipelineParameter.md b/docs/Rules/UseSingleValueFromPipelineParameter.md index 92c350eb4..879605476 100644 --- a/docs/Rules/UseSingleValueFromPipelineParameter.md +++ b/docs/Rules/UseSingleValueFromPipelineParameter.md @@ -1,6 +1,6 @@ --- -description: Use at most a single ValueFromPipeline parameter per parameter set. -ms.date: 03/20/2026 +description: Use a single ValueFromPipeline parameter per parameter set +ms.date: 06/25/2026 ms.topic: reference title: UseSingleValueFromPipelineParameter --- @@ -10,19 +10,17 @@ title: UseSingleValueFromPipelineParameter ## Description -Parameter sets should have at most one parameter marked as `ValueFromPipeline = true`. +This rule detects functions where multiple parameters within the same parameter set are marked as +accepting pipeline input by value. Parameter sets should have at most one parameter with +`ValueFromPipeline = true`. -This rule identifies functions where multiple parameters within the same parameter set have -`ValueFromPipeline` set to `true` (either explicitly or implicitly). - -## How - -Ensure that only one parameter per parameter set accepts pipeline input by value. If you need -multiple parameters to accept different types of pipeline input, use separate parameter sets. +When you need multiple parameters to accept different types of pipeline input, use separate +parameter sets instead. Each parameter set can have its own single `ValueFromPipeline` parameter, +but you can't have more than one within the same parameter set. ## Example -### Wrong +### Noncompliant ```powershell function Process-Data { @@ -41,8 +39,7 @@ function Process-Data { } ``` - -### Correct +### Compliant ```powershell function Process-Data { @@ -62,8 +59,8 @@ function Process-Data { ## Suppression -To suppress this rule for a specific parameter set, use the `SuppressMessage` attribute with the -parameter set name: +This rule is disabled by default. If you have enabled it in your configuration but want to suppress +it for a specific function, you can use the `SuppressMessage` attribute: ```powershell function Process-Data { @@ -91,9 +88,9 @@ For the default parameter set, use `'default'` as the suppression target: ## Notes - This rule applies to both explicit `ValueFromPipeline = $true` and implicit `ValueFromPipeline` - (which is the same as using `= $true`) -- Parameters with `ValueFromPipeline=$false` are not flagged by this rule + (which is the same as using `= $true`). +- This rule doesn't flag parameters with `ValueFromPipeline = $false`. - The rule correctly handles the default parameter set (`__AllParameterSets`) and named parameter - sets + sets. - Different parameter sets can each have their own single `ValueFromPipeline` parameter without - triggering this rule + triggering this rule. diff --git a/docs/Rules/UseSingularNouns.md b/docs/Rules/UseSingularNouns.md index 3997c069a..172503c43 100644 --- a/docs/Rules/UseSingularNouns.md +++ b/docs/Rules/UseSingularNouns.md @@ -1,6 +1,6 @@ --- -description: Cmdlet Singular Noun -ms.date: 03/27/2024 +description: Use single cmdlet nouns +ms.date: 06/11/2026 ms.topic: reference title: UseSingularNouns --- @@ -10,8 +10,14 @@ title: UseSingularNouns ## Description -PowerShell team best practices state cmdlets should use singular nouns and not plurals. Suppression -allows you to suppress the rule for specific function names. For example: +This rule detects cmdlet names that use plural nouns instead of singular nouns. + +PowerShell best practices require that cmdlets use singular nouns, not plurals. You can use the +`NounAllowList` parameter to exclude specific nouns from this rule, or suppress the rule for +individual functions using `SuppressMessageAttribute`. If a violation is found, change the plural +noun to its singular form. + +For example: ``` function Get-Elements { @@ -20,35 +26,9 @@ function Get-Elements { } ``` -## Configuration - -```powershell -Rules = @{ - PSUseSingularNouns = @{ - Enable = $true - NounAllowList = 'Data', 'Windows', 'Foos' - } -} -``` - -### Parameters - -- `Enable`: `bool` (Default value is `$true`) - - Enable or disable the rule during ScriptAnalyzer invocation. - -- `NounAllowList`: `string[]` (Default value is `{'Data', 'Windows'}`) - - Commands to be excluded from this rule. `Data` and `Windows` are common false positives and are - excluded by default. - -## How - -Change plurals to singular. - ## Example -### Wrong +### Noncompliant ```powershell function Get-Files @@ -57,7 +37,7 @@ function Get-Files } ``` -### Correct +### Compliant ```powershell function Get-File @@ -65,3 +45,27 @@ function Get-File ... } ``` + +## Configuration + +```powershell +Rules = @{ + PSUseSingularNouns = @{ + Enable = $true + NounAllowList = 'Data', 'Windows', 'Foos' + } +} +``` + +## Parameters + +### Enable + +This parameter controls whether ScriptAnalyzer checks the code against this rule. It accepts a +boolean value. To disable this rule, set this parameter to `$false`. The default value is `$true`. + +### NounAllowList + +This parameter specifies which noun commands to exclude from this rule. It accepts a string value. +Both `Data` and `Windows` are common false positives and excluded by default. Default values are +`'Data'` and `'Windows'`. diff --git a/docs/Rules/UseSupportsShouldProcess.md b/docs/Rules/UseSupportsShouldProcess.md index 904ad0773..24ce3d80f 100644 --- a/docs/Rules/UseSupportsShouldProcess.md +++ b/docs/Rules/UseSupportsShouldProcess.md @@ -1,6 +1,6 @@ --- description: Use SupportsShouldProcess -ms.date: 06/28/2023 +ms.date: 06/11/2026 ms.topic: reference title: UseSupportsShouldProcess --- @@ -10,15 +10,17 @@ title: UseSupportsShouldProcess ## Description -This rule discourages manual declaration of `WhatIf` and `Confirm` parameters in a function/cmdlet. -These parameters are, however, provided automatically when a function declares a `CmdletBinding` -attribute with `SupportsShouldProcess` as its named argument. Using `SupportsShouldProcess` not only -provides these parameters but also some generic functionality that allows the function/cmdlet -authors to provide the desired interactive experience while using the cmdlet. +This rule detects manual declarations of `WhatIf` and `Confirm` parameters in functions and cmdlets. +Rather than manually declaring these parameters, you should use the `CmdletBinding` attribute with +`SupportsShouldProcess` as a named argument. + +This approach automatically provides both parameters along with built-in functionality that gives +you and your users a consistent interactive experience. Using `SupportsShouldProcess` is more +maintainable and provides standard behavior without extra code. ## Example -### Wrong +### Noncompliant ```powershell function foo { @@ -30,7 +32,7 @@ function foo { } ``` -### Correct +### Compliant ```powershell function foo { diff --git a/docs/Rules/UseToExportFieldsInManifest.md b/docs/Rules/UseToExportFieldsInManifest.md index 5faaf9d1b..1d5038c2f 100644 --- a/docs/Rules/UseToExportFieldsInManifest.md +++ b/docs/Rules/UseToExportFieldsInManifest.md @@ -1,6 +1,6 @@ --- -description: Use the *ToExport module manifest fields. -ms.date: 06/28/2023 +description: Use the *ToExport module manifest fields +ms.date: 06/11/2026 ms.topic: reference title: UseToExportFieldsInManifest --- @@ -10,50 +10,28 @@ title: UseToExportFieldsInManifest ## Description -To improve the performance of module auto-discovery, module manifests should not use wildcards -(`'*'`) or null (`$null`) in the following entries: +This rule detects when module manifests use wildcards (`'*'`) or null (`$null`) in export fields. To +improve module autodiscovery performance, module manifests shouldn't use wildcards or null in the +following entries: - `AliasesToExport` - `CmdletsToExport` - `FunctionsToExport` - `VariablesToExport` -Using wildcards or null has causes PowerShell to perform expensive work to analyze a module during -module auto-discovery. +When you use wildcards or null, PowerShell performs expensive analysis of your module during +autodiscovery. Instead, use an explicit list of items to export. -## How +## Example -Use an explicit list in the entries. - -## Example 1 - -Suppose there are no functions in your module to export. Then, - -### Wrong +### Noncompliant ```powershell FunctionsToExport = $null ``` -### Correct - -```powershell -FunctionToExport = @() -``` - -## Example 2 - -Suppose there are only two functions in your module, `Get-Foo` and `Set-Foo` that you want to -export. Then, - -### Wrong - -```powershell -FunctionsToExport = '*' -``` - -### Correct +### Compliant ```powershell -FunctionToExport = @(Get-Foo, Set-Foo) +FunctionsToExport = @() ``` diff --git a/docs/Rules/UseUTF8EncodingForHelpFile.md b/docs/Rules/UseUTF8EncodingForHelpFile.md index 6d8e0f3c2..518b664fc 100644 --- a/docs/Rules/UseUTF8EncodingForHelpFile.md +++ b/docs/Rules/UseUTF8EncodingForHelpFile.md @@ -1,6 +1,6 @@ --- -description: Use UTF8 Encoding For Help File -ms.date: 01/07/2025 +description: Use UTF8 encoding for help file +ms.date: 06/11/2026 ms.topic: reference title: UseUTF8EncodingForHelpFile --- @@ -10,20 +10,48 @@ title: UseUTF8EncodingForHelpFile ## Description -Check that an `about_` help file uses UTF-8 encoding. The filename must start with `about_` and end -with `.help.txt`. The rule uses the **CurrentEncoding** property of the **StreamReader** class to -determine the encoding of the file. +This rule detects when an `about_` help file doesn't use UTF-8 encoding. The rule verifies that help +files starting with `about_` and ending with `.help.txt` are saved in UTF-8 encoding. It uses the +**CurrentEncoding** property of the **StreamReader** class to check the file's encoding. -## How +To ensure your help files use the correct encoding, follow these guidelines: -For PowerShell commands that write to files, ensure that you set the encoding parameter to `utf8`, -`utf8BOM`, or `utf8NoBOM`. +- When using PowerShell commands to write to files, set the encoding parameter to `utf8`, `utf8BOM`, + or `utf8NoBOM`. +- When creating or editing help files in a text editor, configure it to save files in UTF-8 format. + Consult your editor's documentation for instructions on setting the file encoding. -When you create a help file using a text editor, ensure that the editor is configured to save the -file in a UTF8 format. Consult the documentation for your text editor for instructions on how to -save files with a specific encoding. +## Example -## Further reading +### Noncompliant + +```powershell +$helpText = @' +TOPIC + about_Contoso + +SHORT DESCRIPTION + Describes Contoso commands. +'@ + +$helpText | Set-Content -Path "about_Contoso.help.txt" -Encoding Unicode +``` + +### Compliant + +```powershell +$helpText = @' +TOPIC + about_Contoso + +SHORT DESCRIPTION + Describes Contoso commands. +'@ + +$helpText | Set-Content -Path "about_Contoso.help.txt" -Encoding utf8NoBOM +``` + +## See also For more information, see the following articles: diff --git a/docs/Rules/UseUsingScopeModifierInNewRunspaces.md b/docs/Rules/UseUsingScopeModifierInNewRunspaces.md index bde0f667d..9245c3206 100644 --- a/docs/Rules/UseUsingScopeModifierInNewRunspaces.md +++ b/docs/Rules/UseUsingScopeModifierInNewRunspaces.md @@ -1,6 +1,6 @@ --- -description: Use 'Using:' scope modifier in RunSpace ScriptBlocks -ms.date: 06/28/2023 +description: Use the '$using:' scope modifier in runspace scriptblocks +ms.date: 06/11/2026 ms.topic: reference title: UseUsingScopeModifierInNewRunspaces --- @@ -10,61 +10,34 @@ title: UseUsingScopeModifierInNewRunspaces ## Description -If a scriptblock is intended to be run in a new runspace, variables inside it should use the -`$using:` scope modifier, or be initialized within the scriptblock. This applies to: +This rule detects when scriptblocks running in new runspaces reference parent scope variables +without the `$using:` scope modifier. When a scriptblock is intended to run in a new runspace, it +can't directly access variables from the parent scope. + +You must either use the `$using:` scope modifier to explicitly reference a parent scope variable, or +initialize the variable within the scriptblock itself. This rule applies to: - `Invoke-Command`- Only with the **ComputerName** or **Session** parameter. -- `Workflow { InlineScript {} }` +- `Workflow { InlineScript {} }` (supported only in Windows PowerShell 5.1 and earlier; not + available in PowerShell 6 or higher) - `Foreach-Object` - Only with the **Parallel** parameter - `Start-Job` - `Start-ThreadJob` -- The `Script` resource in DSC configurations, specifically for the `GetScript`, `TestScript` and - `SetScript` properties. - -## How to Fix - -Within the ScriptBlock, instead of just using a variable from the parent scope, you have to add the -`using:` scope modifier to it. +- The `Script` resource in Desired State Configuration (DSC) configurations, specifically for the + `GetScript`, `SetScript`, and `TestScript` properties. ## Example -### Wrong +### Noncompliant ```powershell $var = 'foo' 1..2 | ForEach-Object -Parallel { $var } ``` -### Correct +### Compliant ```powershell $var = 'foo' 1..2 | ForEach-Object -Parallel { $using:var } ``` - -## More correct examples - -```powershell -$bar = 'bar' -Invoke-Command -ComputerName 'foo' -ScriptBlock { $using:bar } -``` - -```powershell -$bar = 'bar' -$s = New-PSSession -ComputerName 'foo' -Invoke-Command -Session $s -ScriptBlock { $using:bar } -``` - -```powershell -# Remark: Workflow is supported on Windows PowerShell only -Workflow { - $foo = 'foo' - InlineScript { $using:foo } -} -``` - -```powershell -$foo = 'foo' -Start-ThreadJob -ScriptBlock { $using:foo } -Start-Job -ScriptBlock {$using:foo } -``` From bd7ce40efa43da395f2436a9773f8df7b910c57f Mon Sep 17 00:00:00 2001 From: sdwheeler <19415881+sdwheeler@users.noreply.github.com> Date: Thu, 25 Jun 2026 18:57:48 -0500 Subject: [PATCH 2/3] Address Copilot feedback --- docs/Rules/AvoidDefaultValueSwitchParameter.md | 7 ------- docs/Rules/AvoidOverwritingBuiltInCmdlets.md | 2 +- docs/Rules/MissingModuleManifestField.md | 4 ++-- docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md | 2 +- docs/Rules/ReviewUnusedParameter.md | 2 +- docs/Rules/UseCompatibleCmdlets.md | 6 +++--- docs/Rules/UseCompatibleCommands.md | 2 +- docs/Rules/UseCompatibleTypes.md | 2 +- docs/Rules/UseToExportFieldsInManifest.md | 3 ++- 9 files changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/Rules/AvoidDefaultValueSwitchParameter.md b/docs/Rules/AvoidDefaultValueSwitchParameter.md index 311724af1..1957d7288 100644 --- a/docs/Rules/AvoidDefaultValueSwitchParameter.md +++ b/docs/Rules/AvoidDefaultValueSwitchParameter.md @@ -60,13 +60,6 @@ function Test-Script $Switch ) - begin { - # Ensure that the $Switch is set to false if not provided - if (-not $PSBoundParameters.ContainsKey('Switch')) { - $Switch = $false - } - } - ... } ``` diff --git a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md index a60ef410d..8bd9c0f3d 100644 --- a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md +++ b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md @@ -70,7 +70,7 @@ against. > [!NOTE] > The default value for `PowerShellVersion` is `core-7.0.0-windows` if PowerShell 7 or later is -installed, and `desktop-5.1.17763.316-windows` if it's not. +> installed, and `desktop-5.1.17763.316-windows` if it's not. Patched PowerShell releases usually share the same cmdlet metadata, so the built-in allow lists are provided by major and minor version. You can also generate a custom allow list with diff --git a/docs/Rules/MissingModuleManifestField.md b/docs/Rules/MissingModuleManifestField.md index fb00328da..5eba0c314 100644 --- a/docs/Rules/MissingModuleManifestField.md +++ b/docs/Rules/MissingModuleManifestField.md @@ -10,11 +10,11 @@ title: MissingModuleManifestField ## Description -This rule detects when a module manifest is missing required fields. A module manifest is a `.psd1` +This rule detects when a module manifest is missing a required field. A module manifest is a `.psd1` file that contains a hash table. The keys and values in the hash table describe the contents and attributes of the module, define the prerequisites, and determine how the components are processed. -A module manifest must contain the following key (and a corresponding value) to be considered valid: +A module manifest must contain the following key-value pair to be considered valid: - `ModuleVersion` diff --git a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md index 94b322d9f..0b956bf72 100644 --- a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md +++ b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md @@ -1,5 +1,5 @@ --- -description: Use equality operator (==) instead of an equal sign (=) as an assignment operator +description: Use equality operator (-eq) instead of an equal signs ms.date: 06/05/2026 ms.topic: reference title: PossibleIncorrectUsageOfAssignmentOperator diff --git a/docs/Rules/ReviewUnusedParameter.md b/docs/Rules/ReviewUnusedParameter.md index abc535729..bbe5adb99 100644 --- a/docs/Rules/ReviewUnusedParameter.md +++ b/docs/Rules/ReviewUnusedParameter.md @@ -10,7 +10,7 @@ title: ReviewUnusedParameter ## Description -This rule detects parameters that are declared but not used a script, scriptblock, or function +This rule detects parameters that are declared but not used in a script, scriptblock, or function scope. You should consider removing unused parameters to improve code clarity and reduce confusion about your function's dependencies. diff --git a/docs/Rules/UseCompatibleCmdlets.md b/docs/Rules/UseCompatibleCmdlets.md index cc339f06d..848592959 100644 --- a/docs/Rules/UseCompatibleCmdlets.md +++ b/docs/Rules/UseCompatibleCmdlets.md @@ -34,13 +34,13 @@ configuration: @{ 'Rules' = @{ 'PSUseCompatibleCmdlets' = @{ - 'Compatibility' = @('core-6.1.0-windows') + 'compatibility' = @('core-6.1.0-windows') } } } ``` -The **Compatibility** parameter accepts a list of one or more target identifiers, such as: +The **compatibility** parameter accepts a list of one or more target identifiers, such as: - desktop-2.0-windows - desktop-3.0-windows @@ -56,7 +56,7 @@ minor version profiles. You can also create a custom profile with [New-CommandDataFile.ps1][01]. Place the generated JSON file in the `Settings` folder of the `PSScriptAnalyzer` module. Then you can reference that file by -name under `Compatibility`. +name under `compatibility`. The `core-6.0.2-*` files were removed in PSScriptAnalyzer 1.18 because PowerShell 6.0 reached its end of life. diff --git a/docs/Rules/UseCompatibleCommands.md b/docs/Rules/UseCompatibleCommands.md index e5c72b6a2..0624a1951 100644 --- a/docs/Rules/UseCompatibleCommands.md +++ b/docs/Rules/UseCompatibleCommands.md @@ -12,7 +12,7 @@ title: UseCompatibleCommands This rule detects commands that aren't available on your targeted PowerShell platform. -A name in the PowerShell platform is identified in the following format: +PowerShell platform names use the following format: ``` ______ diff --git a/docs/Rules/UseCompatibleTypes.md b/docs/Rules/UseCompatibleTypes.md index dc98ecdd3..e50822d29 100644 --- a/docs/Rules/UseCompatibleTypes.md +++ b/docs/Rules/UseCompatibleTypes.md @@ -12,7 +12,7 @@ title: UseCompatibleTypes This rule detects types that aren't available by default on your targeted PowerShell platforms. -A name in the PowerShell platform is identified in the following format: +PowerShell platform names use the following format: ``` ______ diff --git a/docs/Rules/UseToExportFieldsInManifest.md b/docs/Rules/UseToExportFieldsInManifest.md index 1d5038c2f..3dfe43583 100644 --- a/docs/Rules/UseToExportFieldsInManifest.md +++ b/docs/Rules/UseToExportFieldsInManifest.md @@ -20,7 +20,8 @@ following entries: - `VariablesToExport` When you use wildcards or null, PowerShell performs expensive analysis of your module during -autodiscovery. Instead, use an explicit list of items to export. +autodiscovery. Instead, use an explicit list of items to export. If you have no items to export, use +an empty array (`@()`) instead of null or a wildcard. ## Example From 3116b9fe15e304541a9e0ffa86255eca8e9f193b Mon Sep 17 00:00:00 2001 From: sdwheeler <19415881+sdwheeler@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:01:13 -0500 Subject: [PATCH 3/3] Fix duplication --- docs/Rules/README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/Rules/README.md b/docs/Rules/README.md index dad6a755f..5e134ad0e 100644 --- a/docs/Rules/README.md +++ b/docs/Rules/README.md @@ -6,15 +6,10 @@ title: List of PSScriptAnalyzer rules --- # PSScriptAnalyzer Rules -The PSScriptAnalyzer module includes the following built-in rule definitions. You can disable most -configurable rules by setting the `Enable` property to `$false` in a custom rule configuration file. -Rules listed as _Always enabled_ can't be disabled using configuration. However, there are two ways -to avoid rules you don't want to use: - The PSScriptAnalyzer module includes the following built-in rule definitions. For rules that support settings, you can enable or disable them by setting the `Enable` configuration property in a custom settings file. Rules listed as _Always enabled_ don't expose a per-rule `Enable` property. - There are two way to avoid using these rules: + There are two ways to avoid using these rules: - Create a custom rule configuration file to include only the rules you want or exclude the rules you don't want.