Working with .NET types in PowerShell often leads to verbose code like this:
# Tedious fully qualified type names
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
[System.Security.Cryptography.X509Certificates.StoreName]::My,
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
)
PowerShell's New-Object
accepts string arguments for type names, allowing programmatic construction:
$ns = "System.Security.Cryptography.X509Certificates"
$store = New-Object "$ns.X509Store" My,LocalMachine
This approach automatically converts string literals to enum values when used in parameter positions expecting enumerations.
For more permanent solutions across sessions, consider these approaches:
# Create type accelerators
Add-Type -TypeDefinition @"
using System.Security.Cryptography.X509Certificates;
namespace MyShortcuts {
public static class CertTypes {
public static X509Store CreateStore() {
return new X509Store(StoreName.My, StoreLocation.LocalMachine);
}
}
}
"@
[MyShortcuts.CertTypes]::CreateStore()
For PowerShell 5 and later, you can create type aliases:
# Create type accelerator
$accelerators = [PowerShell].Assembly.GetType('System.Management.Automation.TypeAccelerators')
$accelerators::Add('X509Store', 'System.Security.Cryptography.X509Certificates.X509Store')
# Now use the short form
[X509Store]$myStore = New-Object X509Store My,LocalMachine
For production environments, create a module with your common type shortcuts:
# MyTypeShortcuts.psm1
$accelerators = [PowerShell].Assembly.GetType('System.Management.Automation.TypeAccelerators')
@{
'X509Store' = 'System.Security.Cryptography.X509Certificates.X509Store'
'StoreName' = 'System.Security.Cryptography.X509Certificates.StoreName'
'StoreLocation' = 'System.Security.Cryptography.X509Certificates.StoreLocation'
}.GetEnumerator() | ForEach-Object {
if (!$accelerators::Get.ContainsKey($_.Key)) {
$accelerators::Add($_.Key, $_.Value)
}
}
Export-ModuleMember -Variable * -Function * -Alias *
PowerShell automatically converts string literals to enum values when the parameter expects an enum:
# These are equivalent
$store1 = New-Object X509Store([StoreName]::My, [StoreLocation]::LocalMachine)
$store2 = New-Object X509Store("My", "LocalMachine")
While string-based enum conversion is convenient, for performance-critical code:
# Cache enum values for repeated use
$storeName = [StoreName]::My
$storeLocation = [StoreLocation]::LocalMachine
1..1000 | ForEach-Object {
$store = New-Object X509Store($storeName, $storeLocation)
# Work with store
}
Working with .NET types in PowerShell often leads to verbose code when dealing with deep namespace hierarchies. For example, when handling X509 certificates, you might need to write:
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
[System.Security.Cryptography.X509Certificates.StoreName]::My,
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
)
PowerShell allows building type names dynamically as strings:
$ns = "System.Security.Cryptography.X509Certificates"
$store = New-Object "$ns.X509Store" -ArgumentList "My","LocalMachine"
This automatically converts string literals to enum values when they match valid enumeration members.
For frequently used types, create type accelerators:
Add-Type -TypeDefinition @"
using System.Security.Cryptography.X509Certificates;
public static class PSX509Types {
public static X509Store CreateStore(StoreName name, StoreLocation location) {
return new X509Store(name, location);
}
}
"@
$store = [PSX509Types]::CreateStore("My","LocalMachine")
Modern PowerShell versions support type accelerators:
using namespace System.Security.Cryptography.X509Certificates
$store = [X509Store]::new([StoreName]::My, [StoreLocation]::LocalMachine)
PowerShell automatically converts matching strings to enum values:
$store = New-Object "$ns.X509Store" -ArgumentList @(
"My", # Equivalent to [StoreName]::My
"LocalMachine" # Equivalent to [StoreLocation]::LocalMachine
)
- For temporary scripts: Use string concatenation for namespaces
- For reusable modules: Implement type accelerators
- For PowerShell 5+: Leverage the
using namespace
directive - For enum parameters: Use string literals when possible