PowerShell .NET Classes: Use the Full .NET Framework

PowerShell is built on .NET, which means every class in the .NET Framework and .NET 8 is available directly in your scripts — no C# project, no compilation, no extra modules. When there is no cmdlet for what you need, there is almost always a PowerShell .NET Framework class that does it. This post shows you how to access namespaces, call static methods, work with System.IO and System.Net, and add types when you need something beyond the built-ins.
Quick Answer / TL;DR
Access .NET static members with [Namespace.ClassName]::Method(). Instantiate with [ClassName]::new(args) or New-Object NameSpace.ClassName. Use Add-Type -AssemblyName to load additional .NET assemblies.
Access .NET Classes with [ClassName]
Any .NET type can be referenced in PowerShell with the bracket notation [TypeName]. Common types from the System namespace can be shortened: [string], [int], [datetime]. Types in other namespaces need the full name: [System.IO.Path]. Access static members with ::.
# Static members of System.Environment
[System.Environment]::MachineName
[System.Environment]::ProcessorCount
[System.Environment]::OSVersion.Version.ToString()
# Math class static methods
[System.Math]::Round(3.14159, 2)
[System.Math]::Sqrt(144)
[System.Math]::PI
# String static methods
[string]::IsNullOrWhiteSpace(' ') # True
[string]::Join(', ', @('a','b','c')) # "a, b, c"
WIN-SERVER01
8
10.0.17763.0
3.14
12
3.14159265358979
True
a, b, c
Using Static Methods
Static methods do not require instantiation. They are called directly on the type with [Type]::MethodName(args). Static methods are ideal for utility operations: parsing, formatting, file path manipulation, and mathematical functions.
# System.IO.Path static methods (safer than string concatenation)
[System.IO.Path]::Combine('C:\Logs', 'app', 'today.log') # proper path join
[System.IO.Path]::GetFileNameWithoutExtension('C:\Scripts\deploy.ps1') # 'deploy'
[System.IO.Path]::GetExtension('C:\Data\report.csv') # '.csv'
[System.IO.Path]::GetTempPath() # system temp directory
[System.IO.Path]::GetRandomFileName() # random temp filename
# GUID generation
[System.Guid]::NewGuid().ToString()
# Convert between types
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('Hello World'))
System.IO.File vs Get-Content
System.IO.File static methods are faster for large files because they bypass the PowerShell provider layer. Use them when performance matters — reading millions of lines, writing large files, or appending to logs in tight loops.
# System.IO.File — faster for large files
$lines = [System.IO.File]::ReadAllLines('C:\Logs\huge.log')
$lines.Count
# Write all lines at once (faster than Add-Content in loops)
[System.IO.File]::WriteAllText('C:\Output\result.txt', $content)
[System.IO.File]::AppendAllText('C:\Logs\script.log', "$(Get-Date) - Entry`n")
# Copy with progress (native, no Add-Type needed)
[System.IO.File]::Copy('C:\Source\large.dat', 'C:\Dest\large.dat', $true)
# Compare with Get-Content performance on large file
$t1 = (Measure-Command { $x = [System.IO.File]::ReadAllLines('C:\Logs\large.log') }).TotalMilliseconds
$t2 = (Measure-Command { $x = Get-Content 'C:\Logs\large.log' }).TotalMilliseconds
Write-Host "File.ReadAllLines: $([math]::Round($t1,0)) ms vs Get-Content: $([math]::Round($t2,0)) ms"
System.Net.WebClient for Downloads
System.Net.WebClient provides synchronous file download methods. While Invoke-WebRequest is more idiomatic, WebClient can be faster for simple file downloads and provides DownloadFileAsync for non-blocking downloads.
# Download a file synchronously
$client = New-Object System.Net.WebClient
$client.DownloadFile(
'https://github.com/PowerShell/PowerShell/releases/latest',
'C:\Temp\ps_latest.html'
)
# Download a string (e.g., API response)
$jsonText = $client.DownloadString('https://api.github.com/repos/PowerShell/PowerShell')
$json = $jsonText | ConvertFrom-Json
Write-Host "Repo: $($json.full_name), Stars: $($json.stargazers_count)"
$client.Dispose()
Math Class for Calculations
[System.Math] provides the full set of mathematical functions: trigonometry, logarithms, rounding, and power functions. Use it for any calculation that goes beyond PowerShell’s built-in arithmetic operators.
# Math class methods
[math]::Abs(-42) # 42
[math]::Ceiling(4.1) # 5
[math]::Floor(4.9) # 4
[math]::Round(3.14159, 2) # 3.14
[math]::Pow(2, 10) # 1024
[math]::Log10(1000) # 3
[math]::Max(42, 77) # 77
[math]::Min(42, 77) # 42
# Compute percentage
$used = 85
$total = 120
$pct = [math]::Round(($used / $total) * 100, 1)
Write-Host "Disk usage: $pct%"
Add .NET Assembly with Add-Type
Some .NET assemblies are not loaded by default. Use Add-Type -AssemblyName to load them. This is how you access WinForms, WPF, and other GUI frameworks, as well as less common .NET libraries.
# Load WinForms assembly
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show('Hello from PowerShell!')
# Load System.Drawing for image manipulation
Add-Type -AssemblyName System.Drawing
$bitmap = New-Object System.Drawing.Bitmap(200, 100)
$gfx = [System.Drawing.Graphics]::FromImage($bitmap)
$gfx.Clear([System.Drawing.Color]::Blue)
$bitmap.Save('C:\Temp\test.png')
$gfx.Dispose(); $bitmap.Dispose()
# Load compression types (for manual ZIP manipulation)
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory('C:\archive.zip', 'C:\extracted')
Common Errors and Fixes
- Namespace must be fully qualified unless using Add-Type with using namespace.
[IO.Path]works as a shortcut for[System.IO.Path]because PowerShell auto-addsSystem.prefix for many types. But[Net.WebClient]expands to[System.Net.WebClient], not[Microsoft.Net.WebClient]. For third-party assemblies, always use the full namespace. - .NET exceptions need catch block typed to .NET exception class. Exceptions from .NET method calls are .NET exceptions, not PowerShell terminating errors. Catch them with
catch [System.IO.IOException],catch [System.Net.WebException], etc. for specific handling, or use a generalcatchblock with$_.Exception.GetType().FullNameto discover the exception type.
Related Cmdlets / See Also
Wrapping Up
The entire .NET class library is available in PowerShell scripts with the [Namespace.Type]::Member syntax. Reach for System.IO.File for high-performance file operations, System.IO.Path for safe path construction, System.Math for calculations, and Add-Type -AssemblyName to load additional assemblies. The .NET library is your first stop when no PowerShell cmdlet covers your scenario.


