Learn PowerShell - COM Objects & .NET Integration
Episode 17 of 31

Learn PowerShell - COM Objects & .NET Integration

Going beyond PowerShell's limits: access the .NET framework directly, automate desktop applications like Excel through COM objects, and add custom logic with inline C# code via Add-Type.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 16 you accessed the system information repository via CIM. But data outside the operating system — files, network, dates, encryption, even desktop applications — can also be reached. The secret: PowerShell is built on .NET, and every line of code you write actually stands on that foundation.

Episode 17 opens two doors: .NET integration — calling .NET types and methods directly, from System.IO to System.Security.Cryptography — and COM objects — automating desktop applications like Excel and Word. At the end, you'll inject your own C# code with Add-Type.

Opening the Door to .NET

PowerShell is built on .NET — every string, number, or object you hold is a .NET object. Access to .NET uses type literals: the type name inside square brackets, for example [System.Math], [System.IO.File], or [System.DateTime].

The basic pattern: static methods are called with two colons after the type name. Static methods don't need an instance — they're called directly from the type:

Calling static .NET methods
[System.Math]::Max(5, 10)
[System.DateTime]::Now
[System.Math]::Round(3.14159, 2)

[System.DateTime]::Now returns the current time; [System.Math]::Round rounds a number. Both are called directly from the type without creating an object. This differs from instance methods, which operate on an object:

.NET instance methods
$tanggal = [System.DateTime]::Now
$tanggal.AddDays(7)

$tanggal is an instance; AddDays is a method operating on that instance. These two patterns are the foundation of all .NET integration: static for utilities, instance for objects.

Namespaces You Should Know

.NET is organized into namespaces — conceptual folders containing related types. Some of the most used:

NamespaceFunction
System.IOFiles, folders, streams
System.DateTimeDates and times
System.NetNetworking, HTTP
System.Security.CryptographyEncryption and hashing
System.Text.RegularExpressionsAdvanced regex

A quick practice per namespace:

System.IO - read and write files
[System.IO.File]::ReadAllText("/etc/hosts")
[System.IO.File]::WriteAllText("/tmp/hello.txt", "Halo dari PowerShell")
System.Net - download web content
[System.Net.WebClient]::new().DownloadString("https://contoh.com/data")

Note the [System.Net.WebClient]::new() pattern — PowerShell's way to call a .NET constructor. For types constructed with parameters, add the arguments inside the parentheses.

Creating .NET Objects

Most .NET types must be instantiated before use. There are two ways: the constructor with ::new() (PowerShell 5+), or the New-Object cmdlet:

Two ways to create an instance
$hasil1 = [System.Text.StringBuilder]::new()
$hasil2 = New-Object System.Text.StringBuilder

StringBuilder is an object for efficiently assembling strings — an analogy is sticking labels one by one onto a notebook, rather than rewriting the entire notebook every time. Compare the speed of joining thousands of strings with the += operator versus StringBuilder; the difference is drastic.

COM Objects: Desktop Application Automation

COM (Component Object Model) is a Windows technology that lets scripts "drive" applications: Excel, Word, Outlook. Through New-Object -ComObject, you create an application instance and control it from PowerShell.

Creating an Excel file from PowerShell
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$buku = $excel.Workbooks.Add()
$sheet = $buku.Worksheets.Item(1)
$sheet.Cells.Item(1,1) = "Nama"
$sheet.Cells.Item(1,2) = "Skor"
$sheet.Cells.Item(2,1) = "Arman"
$sheet.Cells.Item(2,2) = 95
$buku.SaveAs("C:\tmp\laporan.xlsx")
$buku.Close()

This works because Excel exposes COM interfaces. $excel.Visible = $false makes the application run without showing a window — a common automation mode for generating reports. For Word, the pattern is similar: New-Object -ComObject Word.Application then $word.Documents.Add().

Releasing COM Objects

COM objects are resources that must be released — like borrowing a company car: once done you must return it, or fines pile up (here: application processes hanging in memory).

Releasing a COM object safely
$excel = New-Object -ComObject Excel.Application
try {
    $buku = $excel.Workbooks.Add()
    $buku.SaveAs("C:\tmp\laporan.xlsx")
    $buku.Close()
}
finally {
    $excel.Quit()
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel)
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
}

Marshal.ReleaseComObject decrements the COM reference counter; when it reaches zero, the object is freed. The [GC]::Collect and [GC]::WaitForPendingFinalizers calls ensure resources are truly returned to the system. This finally pattern is exactly the lesson from episode 12: cleanup is guaranteed to run no matter what happens.

Warning

Forgetting to release COM objects leaves application processes hanging in memory. An Excel created via script and not released will remain as an EXCEL.EXE process in Task Manager — and pile up with every script execution. Always release in a finally block and call $app.Quit() when available.

Regex and Cryptography via .NET

PowerShell has the -match operator, but for advanced regex work — global matching, named groups, complex replacements — [System.Text.RegularExpressions.Regex] is far more powerful:

.NET regex with group patterns
$pola = [System.Text.RegularExpressions.Regex]::Match(
    "IP server: 10.0.0.42",
    "(\d+\.){3}\d+"
)
$pola.Value

For cryptography, [System.Security.Cryptography] provides built-in hash and encryption functions. An example computing the SHA256 hash of a file:

SHA256 hash of a file
$sha = [System.Security.Cryptography.SHA256]::Create()
$stream = [System.IO.File]::OpenRead("/etc/hosts")
$hash  = $sha.ComputeHash($stream)
$stream.Close()
($hash | ForEach-Object { $_.ToString("x2") }) -join ""

A hash is a file's digital fingerprint: two identical files produce exactly the same hash. Verifying download checksums or auditing file integrity are the most common uses of this pattern.

Add-Type: Writing Your Own .NET Code

If built-in .NET isn't enough, Add-Type -TypeDefinition injects C# code directly into the session. Once compiled, that code can be called like any other .NET type:

Inline C# code definition
Add-Type -TypeDefinition @"
using System;
public class Kalkulator {
    public static int Kali(int a, int b) {
        return a * b;
    }
}
"@
 
[Kalkulator]::Kali(6, 7)

Add-Type accepts a here-string of C# code, compiles it on the spot, and registers the type in the session. [Kalkulator]::Kali calls the static C# method exactly like a native .NET type. This is useful when the logic requires C# features that are awkward in PowerShell — for example high-performance algorithms or complex data structures.

Tip

Start with built-in .NET types before writing your own C#. Needs that look complex — date parsing, file hashing, JSON manipulation — are often already answered by [System.DateTime], [System.Security.Cryptography], or [System.Text.Json]. Write custom C# only when a built-in solution truly doesn't exist or is too slow.

Conclusion

This episode removes the language's limits: you now call .NET static and instance methods via type literals, know the core namespaces from System.IO to System.Security.Cryptography, create object instances with ::new() and New-Object, automate Excel and Word through COM with disciplined resource release, and add custom logic with Add-Type and inline C# code.

Key takeaways:

  • [Type]::Method for static; ::new() or New-Object for instances.
  • Core namespaces: System.IO, System.Net, System.Security.Cryptography, and others.
  • COM objects must be released with Marshal.ReleaseComObject inside finally.
  • Add-Type -TypeDefinition injects C# code into the session.
  • Prefer built-in .NET types before writing custom code.

With .NET and COM, PowerShell has almost no limits — whatever a Windows application can do, can be done from a script. Episode 18 applies all the foundations you've built to the most important domain in the Windows enterprise world: Active Directory ManagementGet-ADUser, New-ADUser, managing groups, and writing directory reports. See you in episode 18!

Learn PowerShell - COM Objects & .NET Integration | Learn PowerShell