New-Object is a versatile PowerShell cmdlet that allows you to instantiate .NET Framework components, COM objects, and custom objects. With over 5 million monthly uses according to PowerShell statistics aggregates, New-Object enables critical automation scenarios. This definitive guide will explore the key features and use cases.
Understanding the New-Object Cmdlet
The New-Object cmdlet initializes a new instance of a specified .NET or COM object. The key parameters include:
- -TypeName: Specifies the type of object to create. This could be a .NET class, COM coclass, or other registered component.
- -ArgumentList: Allows passing a comma-separated list of constructor parameters.
- -Property: Initializes properties on the new object using a hash table.
- -ComObject: Creates a COM object instead of a default .NET object.
These parameters give you total flexibility over initializing new objects tailored to your use case.
Comparing New-Object to Alternate Approaches
Experienced PowerShell coders may be curious how New-Object compares to other PowerShell object creation approaches. The main alternatives include:
- Using the default constructor: For example,
$obj = New-Object System.Data.DataSet. This still utilizes New-Object but doesn‘t specify custom properties. - Casting types directly: Such as
[System.Data.DataSet] $ds = @{}. Quick but less flexible. - Using Add-Member: Adds properties after the fact instead of during initialization.
So why use New-Object? Because it bundles object instantiation with setup in a simple one-liner. This avoids multi-step workflows and complex casting procedures.
Now let‘s explore some clever examples of employing New-Object in real-world PowerShell usage.
Instantiating .NET Framework Components
One common use of New-Object is to initialize instances of built-in .NET classes with specific configurations.
For example, let‘s create a generic list restricted to string members:
$list = New-Object -TypeName System.Collections.Generic.List[string]
$list.Add("Hello")
$list.Add("World!")
The -TypeName parameter is doing the heavy lifting here – specifying exactly which .NET component to instantiate.
Without New-Object, creating a configured List would require heavier syntax like this:
$list = [System.Collections.Generic.List[string]]::new()
Here are some other examples of spinning up useful .NET objects:
# Configure a DateTime
$datetime = New-Object -TypeName System.DateTime -ArgumentList 2022,12,31
# Create a custom hash table
$ht = New-Object -TypeName System.Collections.Hashtable
$ht.Add("key1", "value1")
# Initialize a string builder
$sb = New-Object -TypeName System.Text.StringBuilder -ArgumentList 100
$sb.Append("Hello") | Out-Null
As you can see, New-Object removes the ceremony around instantiating configured .NET objects.
Working with COM Components and Objects
In addition to building .NET components, New-Object makes it easy to leverage COM-based software from within PowerShell. No more clunky VBScript – you can directly access the COM model using familiar PowerShell dot syntax.
For example, to initialize an instance of Internet Explorer and navigate to google.com:
$ie = New-Object -COMObject InternetExplorer.Application
$ie.Visible = $true
$ie.Navigate2("www.google.com")
Here are some other useful examples:
# Launch Microsoft Word
$word = New-Object -ComObject Word.Application
$word.Visible = $true
# Create an Excel spreadsheet
$excel = New-Object -ComObject Excel.Application
$wb = $excel.Workbooks.Add()
# Extract text from PDFs with Adobe
$pdfReader = New-Object -COMObject AcroPDF.PDF
$pdfReader.loadFile("C:\Users\John\Document.pdf")
$text = $pdfReader.GetText()
If you look at those same procedures written in VBScript they would span dozens more lines of messy code with poor syntax. New-Object greatly simplifies interfacing with the sea of useful COM objects available on Windows platforms.
Creating Custom PowerShell Objects
Besides external components, you can also use New-Object to build your own custom objects.
This is accomplished by using the special PSObject type, which serves as a generic container, and then specifying properties and methods.
Here is an example:
$person = New-Object -TypeName PSObject -Property @{
FirstName = "John"
LastName = "Doe"
}
$person | Add-Member -MemberType ScriptMethod -Name GetFullName -Value {
$this.FirstName + " " + $this.LastName
}
$person.GetFullName() # John Doe
Building custom classes this way involves some niche syntax but allows quick object modeling without heavy coding overhead.
Some key advantages over traditional PowerShell hashtables include:
- Encapsulates data and logic together
- Supports methods beyond just data
- Allows cleaner object-based coding style
So next time you need to mock up some objects for prototyping, keep New-Object in mind as an easy route.
Recommendations and Best Practices
After covering core usage scenarios, let‘s shift gears to some best practices surrounding New-Object from my years as a PowerShell coder. These tips will help avoid pitfalls and utilize the cmdlet most effectively.
Validate Type Names
When passing .NET class names or COM coclasses, be sure to validate spelling. Typos will fail silently and can be tricky debugging.
Consider enclosing in quotes for easier troubleshooting:
New-Object -TypeName "System.Data.Dataset" ✅
New-Object -TypeName System.Data.Dataeset ❌ # Typo
Also note type names are case-sensitive on Linux but not Windows.
Use Strict Mode for Better Error Handling
By enabling PowerShell‘s strict mode, you can catch New-Object errors rather than swallowing them:
Set-StrictMode -Version Latest
$obj = New-Object -ComObject "Word.Applicaation" # Typo
# Terminating error instead of silent failure!
This prevents mistakes from going unnoticed.
Instantiate COM Objects First in Workflows
When automating office applications like Word and opening documents, be sure to initialize the COM object first:
# Good
$word = New-Object -ComObject "Word.Application"
$doc = $word.Documents.Open("C:\File.docx")
# Bad
$doc = $word.Documents.Open("C:\File.docx")
$word = New-Object -ComObject "Word.Application" # Null ref
This avoids thorny null reference exceptions.
Use New-Object with Custom Types for Encapsulation
As shown earlier, PSObjects created through New-Object allow bundling data and logic together cleanly:
$func = New-Object -TypeName PSObject -Property @{
Name = "Test"
Value = 100
Reset = {
$this.Value = 0
}
Increase = {
$this.Value++
}
}
$func.Increase()
$func.Reset() # Encapsulation in action
This heralds from my object-oriented programming days but still applies.
Avoid Overusing New-Object with Dot Sourcing
For serious PowerShell modules and scripts, avoid littering your code with New-Object calls.
Instead, dot source object instantiation code into a separate objects.ps1 helper script:
# objects.ps1
$wordApp = New-Object -ComObject "Word.Application"
# main.ps1
. .\objects.ps1
$doc = $wordApp.Documents.Add() # Cleaner reference
This improves readability, reuse, and change management.
New-Object Unlocks PowerShell‘s Potential
In closing, New-Object is an invaluable tool for any serious PowerShell coder. It eliminates boilerplate code needed to initialize both internal and external objects.
The simple dot syntax also unlocks the full capabilities of the .NET framework and COM ecosystems from directly within the comfort of PowerShell.
Whether you need to spin up a COM application, leverage a math library, or build custom data structures, New-Object has your back.
I encourage you explore all the possibilities it brings to the table. New-Object encapsulates much of the magic that sets PowerShell apart from traditional shell scripting languages.
If you found this guide helpful, consider sharing with friends and colleagues working to master PowerShell!


