How to Simplify .NET Type References in PowerShell: Namespace Shortcuts and Type Aliasing


2 views

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