Skip to content

Commit da95630

Browse files
committed
fix: Add missing Documentation
1 parent 4422b7e commit da95630

File tree

1 file changed

+256
-0
lines changed

1 file changed

+256
-0
lines changed

docs/Rules/AvoidUsingNewObject.md

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
---
2+
description: Avoid Using New-Object
3+
ms.date: 06/14/2025
4+
ms.topic: reference
5+
title: AvoidUsingNewObject
6+
---
7+
# AvoidUsingNewObject
8+
9+
**Severity Level: Warning**
10+
11+
## Description
12+
13+
The `New-Object` cmdlet should be avoided in modern PowerShell code except when creating COM objects. PowerShell provides more efficient, readable, and idiomatic alternatives for object creation that offer better performance and cleaner syntax.
14+
15+
This rule flags all uses of `New-Object` ***except*** when used with the `-ComObject` parameter, as COM object creation is one of the few legitimate remaining use cases for this cmdlet.
16+
17+
## Why Avoid New-Object?
18+
19+
### Performance Issues
20+
`New-Object` uses reflection internally, which is significantly slower than direct type instantiation or accelerated type syntax. The performance difference becomes more pronounced in loops or frequently executed code.
21+
22+
### Readability and Maintainability
23+
Modern PowerShell syntax is more concise and easier to read than `New-Object` constructions, especially for common .NET types.
24+
25+
### PowerShell Best Practices
26+
The PowerShell community and Microsoft recommend using native PowerShell syntax over legacy cmdlets when better alternatives exist.
27+
28+
## Examples
29+
30+
### Wrong
31+
32+
```powershell
33+
# Creating .NET objects
34+
$list = New-Object System.Collections.Generic.List[string]
35+
$hashtable = New-Object System.Collections.Hashtable
36+
$stringBuilder = New-Object System.Text.StringBuilder
37+
$datetime = New-Object System.DateTime(2023, 12, 25)
38+
39+
# Creating custom objects
40+
$obj = New-Object PSObject -Property @{
41+
Name = "John"
42+
Age = 30
43+
}
44+
```
45+
46+
### Correct
47+
48+
```powershell
49+
# Use accelerated type syntax for .NET objects
50+
$list = [System.Collections.Generic.List[string]]::new()
51+
$hashtable = @{} # or [hashtable]@{}
52+
$stringBuilder = [System.Text.StringBuilder]::new()
53+
$datetime = [DateTime]::new(2023, 12, 25)
54+
55+
# Use PSCustomObject for custom objects
56+
$obj = [PSCustomObject]@{
57+
Name = "John"
58+
Age = 30
59+
}
60+
61+
# COM objects are still acceptable with New-Object
62+
$excel = New-Object -ComObject Excel.Application
63+
$word = New-Object -ComObject Word.Application
64+
```
65+
66+
## Alternative Approaches
67+
68+
### For .NET Types
69+
- **Static `new()` method**: `[TypeName]::new(parameters)`
70+
- **Type accelerators**: Use built-in shortcuts like `@{}` for hashtables
71+
- **Cast operators**: `[TypeName]$value` for type conversion
72+
73+
### For Custom Objects
74+
- **PSCustomObject**: `[PSCustomObject]@{ Property = Value }`
75+
- **Ordered dictionaries**: `[ordered]@{ Property = Value }`
76+
77+
### For Collections
78+
- **Array subexpression**: `@(items)`
79+
- **Hashtable literal**: `@{ Key = Value }`
80+
- **Generic collections**: `[System.Collections.Generic.List[Type]]::new()`
81+
82+
## Performance Comparison
83+
84+
```powershell
85+
# Slow - uses reflection
86+
Measure-Command { 1..1000 | ForEach-Object { New-Object System.Text.StringBuilder } }
87+
88+
# Fast - direct instantiation
89+
Measure-Command { 1..1000 | ForEach-Object { [System.Text.StringBuilder]::new() } }
90+
```
91+
92+
The modern syntax provides a performance improvement over `New-Object` for most common scenarios.
93+
94+
## Exceptions
95+
96+
The rule allows `New-Object` when used with the `-ComObject` parameter because:
97+
- COM object creation requires the `New-Object` cmdlet.
98+
- No direct PowerShell alternative exists for COM instantiation.
99+
- COM objects are external to the .NET type system.
100+
101+
```powershell
102+
# This is acceptable
103+
$shell = New-Object -ComObject WScript.Shell
104+
$ie = New-Object -ComObject InternetExplorer.Application
105+
```
106+
107+
---
108+
109+
## Migration Guide
110+
111+
| Old Syntax | New Syntax |
112+
|------------|------------|
113+
| **Creating a custom object**: <br> `New-Object PSObject -Property @{ Name = 'John'; Age = 30 }` | **Use PSCustomObject**: <br> `[PSCustomObject]@{ Name = 'John'; Age = 30 }` |
114+
| **Creating a hashtable**: <br> `New-Object System.Collections.Hashtable` | **Use hashtable literal**: <br> `@{}` <br> **Or explicitly cast**: <br> `[hashtable]@{}` |
115+
| **Creating a generic list**: <br> `New-Object 'System.Collections.Generic.List[string]'` | **Use static `new()` method**: <br> `[System.Collections.Generic.List[string]]::new()` |
116+
| **Creating a DateTime object**: <br> `New-Object DateTime -ArgumentList 2023, 12, 25` | **Use static `new()` method**: <br> `[DateTime]::new(2023, 12, 25)` |
117+
| **Creating a StringBuilder**: <br> `New-Object System.Text.StringBuilder` | **Use static `new()` method**: <br> `[System.Text.StringBuilder]::new()` |
118+
| **Creating a process object**: <br> `New-Object System.Diagnostics.Process` | **Use static `new()` method**: <br> `[System.Diagnostics.Process]::new()` |
119+
| **Creating a custom .NET object**: <br> `New-Object -TypeName 'Namespace.TypeName' -ArgumentList $args` | **Use static `new()` method**: <br> `[Namespace.TypeName]::new($args)` |
120+
121+
---
122+
123+
### Detailed Examples
124+
125+
#### Custom Object Creation
126+
127+
**Old Syntax:**
128+
129+
```powershell
130+
$obj = New-Object PSObject -Property @{
131+
Name = 'John'
132+
Age = 30
133+
}
134+
```
135+
136+
**New Syntax:**
137+
138+
```powershell
139+
$obj = [PSCustomObject]@{
140+
Name = 'John'
141+
Age = 30
142+
}
143+
```
144+
145+
#### Hashtable Creation
146+
147+
**Old Syntax:**
148+
149+
```powershell
150+
$hashtable = New-Object System.Collections.Hashtable
151+
$hashtable.Add('Key', 'Value')
152+
```
153+
154+
**New Syntax:**
155+
156+
```powershell
157+
$hashtable = @{
158+
Key = 'Value'
159+
}
160+
```
161+
162+
Or explicitly cast:
163+
164+
```powershell
165+
$hashtable = [hashtable]@{
166+
Key = 'Value'
167+
}
168+
```
169+
170+
#### Generic List Creation
171+
172+
**Old Syntax:**
173+
174+
```powershell
175+
$list = New-Object 'System.Collections.Generic.List[string]'
176+
$list.Add('Item1')
177+
$list.Add('Item2')
178+
```
179+
180+
**New Syntax:**
181+
182+
```powershell
183+
$list = [System.Collections.Generic.List[string]]::new()
184+
$list.Add('Item1')
185+
$list.Add('Item2')
186+
```
187+
188+
#### DateTime Object Creation
189+
190+
**Old Syntax:**
191+
192+
```powershell
193+
$date = New-Object DateTime -ArgumentList 2023, 12, 25
194+
```
195+
196+
**New Syntax:**
197+
198+
```powershell
199+
$date = [DateTime]::new(2023, 12, 25)
200+
```
201+
202+
#### StringBuilder Creation
203+
204+
**Old Syntax:**
205+
206+
```powershell
207+
$stringBuilder = New-Object System.Text.StringBuilder
208+
$stringBuilder.Append('Hello')
209+
```
210+
211+
**New Syntax:**
212+
213+
```powershell
214+
$stringBuilder = [System.Text.StringBuilder]::new()
215+
$stringBuilder.Append('Hello')
216+
```
217+
218+
#### Custom .NET Object Creation
219+
220+
**Old Syntax:**
221+
222+
```powershell
223+
$customObject = New-Object -TypeName 'Namespace.TypeName' -ArgumentList $arg1, $arg2
224+
```
225+
226+
**New Syntax:**
227+
228+
```powershell
229+
$customObject = [Namespace.TypeName]::new($arg1, $arg2)
230+
```
231+
232+
#### Process Object Creation
233+
234+
**Old Syntax:**
235+
236+
```powershell
237+
$process = New-Object System.Diagnostics.Process
238+
```
239+
240+
**New Syntax:**
241+
242+
```powershell
243+
$process = [System.Diagnostics.Process]::new()
244+
```
245+
246+
---
247+
## Related Links
248+
249+
- [New-Object][01]
250+
- [PowerShell scripting performance considerations][02]
251+
- [Creating .NET and COM objects][03]
252+
253+
<!-- link references -->
254+
[01]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-object
255+
[02]: https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/performance/script-authoring-considerations
256+
[03]: https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-.net-and-com-objects--new-object-

0 commit comments

Comments
 (0)