Search notes:

PowerShell cmdLet New-Object

new-object creates a new PowerShell object which represents either a .NET or a COM Object
The new-object cmdLet cannot be piped into.

Creating a .NET object / psObject

An instance of a .NET object is created by specifying the type of a .NET Framework class. The optional -typeName argument can be used to explicitly mark the argument as a type name.
Under the hood, new-object creates a System.Management.Automation.PSObject object whose member ImmediateBaseObject is a reference to the actual object that is created.
PS C:\> $webClient = new-object System.Net.WebClient

PS C:\> $webClient.GetType().FullName
System.Net.WebClient

PS C:\> $webClient.psObject.GetType().FullName
System.Management.Automation.PSObject

PS C:\> $webClient.psObject.ImmediateBaseObject.GetType().FullName
System.Net.WebClient

Constructor

If the .NET object to be created does not provide a default constructor, the arguments to the constructor need to be passed after the type name:
$txt = new-object System.String 'Hello world'

psObject

psObject has a special meaning: it creates a System.Management.Automation.PSCustomObject object, one of the most important, if not the most important object type in PowerShell:
PS C:\> $obj = new-object psObject
PS C:\> $obj.GetType().FullName
System.Management.Automation.PSCustomObject
With new-object psObject, PowerShell also creates a PSObject with ImmediateBaseObject referencing the PSCustomObject.

Beware of particularities of argument parsing mode

Arguments that are passed to a .NET type constructor are parsed in argument parsing mode which is different from expression parsing mode. This might lead to seemingly inexplainable results.
One of the main differences of these parsing modes is that argument parsing mode does not recognize the type reference (for example [System.Console]) but assumes it to be a string.
Thus, if a method on a type is called to fill an argument to the constructor of the object being created, such a type reference must be enclosed in parenthesis:
$obj = new-object type.name ( [Another.type.name]::method() )

Creating a COM object

A COM Object is created with the -comObject option that specifies a progid.
$obj = new-object -comObject prog.id
See also Creating COM Objects with PowerShell.

Creating an object from inline C-Sharp code

The add-type cmdLet allows to compile C# classes that then can be created in PowerShell:
add-Type -typedef @'

using System;
namespace tq84 {

   public class CLS {

      private String txt;

      public void writeTxt() {
         Console.WriteLine("txt is {0}", txt);
      }

      public CLS(String txt_) {
         txt = txt_;
      }
   }
}
'@

$obj_1 = new-object tq84.CLS 'Hello world'
$obj_2 = new-object tq84.CLS 'The number is 42'

$obj_1.writeTxt()
#
#  txt is Hello world

$obj_2.writeTxt()
#
#  txt is The number is 42
Github repository about-PowerShell, path: /cmdlets/object/new/inline-c-sharp.ps1

-property

The -property option takes an object that implements the System.Collections.IDictionary interface.
An object with such an interface can be created with the @{ … } syntax (which creates a hash table.

psObject

In the following example, a Powershell custom object is created with the property names and values of the hash table ($probs) that is first created:
$props = @{
   num = 42
   txt ='Hello world'
}

$props.GetType().FullName
#
# System.Collections.Hashtable

$obj = new-object psObject -property $props

$obj | get-member -memberType noteProperty
#
#    TypeName: System.Management.Automation.PSCustomObject
#
# Name MemberType   Definition
# ---- ----------   ----------
# num  NoteProperty int num=42
# txt  NoteProperty string txt=Hello world

#
#  The properties of the object can
#  now be changed
#
$obj.num = 4

$obj | format-table
#
# num txt
# --- ---
#   4 Hello world

.NET class

This example is similar to the previous one, but this time a «real» .NET class is created. This class already has the two properties num and txt. Thus, the member type of the properties is property as opposed to noteProperty in psObject objects:
add-Type -typedef @'

   using System;

   public class XYZ {
      public int    num;
      public String txt;
   }

'@

$props = @{
  num = 4
  txt ='four'
}

$obj_1 = new-object XYZ -property $props

#
#  Note: the memberType we're looking for is
#  property, not noteProperty:
#
$obj_1 | get-member -memberType property
#
#    TypeName: XYZ
# 
# Name MemberType Definition
# ---- ---------- ----------
# num  Property   int num {get;set;}
# txt  Property   string txt {get;set;}

Instantiating an object from a DLL

The following simple example tries to demonstrate how a class from a DLL can be used in PowerShell.
First, we need to create such a DLL. Here's the C# source code:
namespace TQ84 {

   public class Obj {

      private string name_;

      public Obj(string name) {
         name_ = name;
         System.Console.WriteLine("Obj's constructor was called");
      }

      public static int twice(int a) {
         return 2*a;
      }

      public void saySomeThing(string someThing) {
         System.Console.WriteLine(name_ + " says " + someThing);
      }

   }
}
Github repository about-PowerShell, path: /cmdlets/object/new/cs-class/obj.cs
The source code is compiled into a DLL (-target:library):
PS C:\path\to\somewhere > csc -nologo -target:library .\obj.cs
In order to use the class, the DLL needs to be added to the current PowerShell session:
PS C:\path\to\somewhere > add-type -path 'obj.dll'
Static methods can be called without instantiating a class.
PS C:\path\to\somewhere > [TQ84.Obj]::twice(21)
However, member methods require an object, which is what new-object creates.
When the object is created, its constructor is automatically called. Because the constructor contains a System.Console.WriteLine statement, Obj's constructor was called is printed.
PS C:\path\to\somewhere > $obj_1 = new-object TQ84.Obj one
Obj's constructor was called
PS C:\path\to\somewhere > $obj_2 = new-object TQ84.Obj two
Obj's constructor was called
Now, that the objects have been created, we can use them:
PS C:\path\to\somewhere > $obj_1.saySomeThing('eins')
one says eins
PS C:\path\to\somewhere > $obj_2.saySomeThing('zwei')
two says zwei

Error message: Cannot find type …: verify that the assembly containing this type is loaded

Some assemblies need to be explicitly added to a PowerShell session in order to use them, otherwise, an Cannot find type …: verify that the assembly containing this type is loaded error is thrown:
PS C:\> $bmp = new-object Drawing.Bitmap 200, 40
new-object : Cannot find type [Drawing.Bitmap]: verify that the assembly containing this type is loaded.o
… etc. etc. …
The required assembly can be added with the add-type cmdLet:
PS C:\> add-type -assembly 'System.Drawing'
PS C:\> $bmp = new-object Drawing.Bitmap 200, 40

See also

new-object psObject
Powershell command noun: object
Object creation in PowerShell

Index