Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -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
Expand All @@ -31,7 +29,7 @@ catch [DivideByZeroException]
}
```

### Correct
### Compliant

```powershell
try
Expand Down
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -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
Expand All @@ -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
Expand All @@ -46,7 +44,7 @@ function Test-Script
}
```

### Correct
### Compliant

```powershell
function Test-Script
Expand All @@ -60,3 +58,7 @@ function Test-Script
...
}
```

<!-- link references -->

[01]: /dotnet/api/system.security.securestring
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
---
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`.

## Configuration

```powershell
Rules = @{
PSAvoidUsingPositionalParameters = @{
CommandAllowList = 'Join-Path', 'MyCmdletOrScript'
Enable = $true
}
}
```

### Parameters

#### CommandAllowList: string[] (Default value is @()')

Commands or scripts to be excluded from this rule.

#### Enable: bool (Default value is `$true`)

Enable or disable the rule during ScriptAnalyzer invocation.

## How
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`.

Use full parameter names when calling commands.

## Example

### Wrong
### Noncompliant

```powershell
Get-Command ChildItem Microsoft.PowerShell.Management
```

### Correct
### Compliant

```powershell
Get-Command -Noun ChildItem -Module Microsoft.PowerShell.Management
```

## Configure rule

```powershell
Rules = @{
PSAvoidUsingPositionalParameters = @{
CommandAllowList = 'Join-Path', 'MyCmdletOrScript'
Enable = $true
}
}
```

## Parameters

### CommandAllowList

This parameter specifies commands or scripts to be excluded from this rule. It accepts a string
array. The default value is `@()`.

### 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`.
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -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
Expand All @@ -36,7 +33,7 @@ function Test-Script
}
```

### Correct
### Compliant

```powershell
function Test-Script
Expand Down
Original file line number Diff line number Diff line change
@@ -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
---
Expand All @@ -10,49 +10,39 @@ 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`
- `Invoke-WmiMethod`
- `Register-WmiEvent`
- `Set-WmiInstance`

Use the following cmdlets instead:
Use these CIM cmdlets instead:

- `Get-CimInstance`
- `Remove-CimInstance`
- `Invoke-CimMethod`
- `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' }
```
Loading
Loading