Skip to content

Add new AvoidUsingNewObject rule#2186

Open
iRon7 wants to merge 5 commits into
PowerShell:mainfrom
iRon7:#2046-AvoidUsingNewObject
Open

Add new AvoidUsingNewObject rule#2186
iRon7 wants to merge 5 commits into
PowerShell:mainfrom
iRon7:#2046-AvoidUsingNewObject

Conversation

@iRon7

@iRon7 iRon7 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Closes #2046

PR Summary

Avoid using the New-Object cmdlet to create objects as it might perform poorly.
Instead, use type initializer to construct or cast the intended object.

Note

In most cases if there isn't an automatic correction isn't available,
the rule won't report any violation either.
This is because if there isn't an automatic correction available, it generally means
that there isn't a simple type-casting or type constructor that can be used that would
be used that would be more efficient or has a better syntax than using New-Object.
In other words, if the common -Verbose parameter is used, or both the parameters
-ArgumentList and -Property are used, there won't be a simple type initializer
available and the rule won't report any violation for the New-Object cmdlet.

Nevertheless, there are still some cases where the New-Object cmdlet might be
replaceable with a type initializer that would be more efficient or has a better syntax,
but an automatic correction can't be provided.
For example if the -ArgumentList parameter is used with a variable,
the rule will report a violation, but won't be able to provide a correction,
as it's not possible to determine from the AST alone whether the variable contains a
single value that can be used in a type initializer,
or if it contains multiple values that would require splatting.

This PR replaces PR #2109

PR Checklist

Copilot AI review requested due to automatic review settings June 9, 2026 18:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new PSScriptAnalyzer rule that warns on New-Object usage and provides auto-fix suggestions, along with documentation, localized strings, and Pester tests.

Changes:

  • Added AvoidUsingNewObject rule implementation with suggested corrections/fixes.
  • Added rule documentation and registered it in the rules index.
  • Added localization strings and comprehensive Pester tests for detection/suppression/fix behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
docs/Rules/README.md Registers the new rule in the documentation rules table.
docs/Rules/AvoidUsingNewObject.md Adds rule reference documentation and examples.
Tests/Rules/AvoidUsingNewObject.tests.ps1 Adds Pester coverage for rule behavior, suppression, and -fix.
Rules/Strings.resx Adds localized strings for rule name/description/message/correction.
Rules/AvoidUsingNewObject.cs Implements the rule logic and suggested corrections.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Rules/AvoidUsingNewObject.cs
Comment thread docs/Rules/AvoidUsingNewObject.md
Comment thread docs/Rules/AvoidUsingNewObject.md
Comment thread Rules/AvoidUsingNewObject.cs
Comment thread Tests/Rules/AvoidUsingNewObject.tests.ps1
@iRon7 iRon7 requested a review from Copilot June 10, 2026 08:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Comment thread Rules/AvoidUsingNewObject.cs Outdated
Comment thread Rules/AvoidUsingNewObject.cs Outdated
Comment thread Rules/AvoidUsingNewObject.cs
Comment thread Rules/AvoidUsingNewObject.cs
Comment thread docs/Rules/AvoidUsingNewObject.md Outdated
Comment thread Tests/Rules/AvoidUsingNewObject.tests.ps1 Outdated
Comment thread Tests/Rules/AvoidUsingNewObject.tests.ps1 Outdated
@iRon7 iRon7 requested a review from Copilot June 10, 2026 08:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

/// <returns>A an enumerable type containing the violations</returns>
public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
{
if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
Comment on lines +101 to +112
else if (boundResult.ConstantValue != null)
{
string valueText = boundResult.Value.Extent.Text;
if (
boundResult.Value is StringConstantExpressionAst stringConstant &&
stringConstant.StringConstantType == StringConstantType.BareWord
)
{
valueText = '"' + valueText.Replace("\"", string.Empty) + '"'; // Test""123 --> "Test123"
}
correction = "[" + typeName + "]" + valueText;
}

@iRon7 iRon7 Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think I got this right, if the -ArgumentList contains an constant value, I might use a shorter (preferred) syntax by simply casting the value expression.
For the given example: New-Object DateTime 0 vs [DateTime]0, both return the same results:

Monday, January 1, 0001 12:00:00 AM

Comment on lines +113 to +116
else if (
boundResult.Value is ParenExpressionAst parenExpressionAst &&
!parenExpressionAst.Pipeline.Extent.Text.StartsWith(",")
)

@iRon7 iRon7 Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The Pipeline.Extent.Text (the inner Ast of the ParenExpressionAst) is already trimmed.
Btw. I don't think there is an easier way to check for a wrapped object (unary comma operator).

Comment thread Rules/AvoidUsingNewObject.cs Outdated
@iRon7 iRon7 changed the title WIP: Add new AvoidUsingNewObject rule Add new AvoidUsingNewObject rule Jun 10, 2026
@iRon7 iRon7 mentioned this pull request Jun 10, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rule request: AvoidNewObjectCmdlet

2 participants