[Microsoft.Win32.Registry] VS Set-ItemProperty

Created March 19, 2023

Today I would like to show you a performance table comparing different ways to write to the registry.

Writing to the registry is more or less a standard task while working as an administrator or software packaging person.


This is how most of the people would write to the registry with PowerShell:

$Path ="HKCU:\SOFTWARE\mysupersoftware"
$Name = "SuperItem"
$Value = "Super"

try{
    Set-ItemProperty -Path $Path -Name $Name -Value $Value -ErrorAction Stop
}catch{
    Write-Error "Cant't write $Value to $Name in $Path"
}

Which is totally fine because it is easily readable by human beeings.


Another way is to use the .net class [Microsoft.Win32.Registry]:

$Path ="SOFTWARE\mysupersoftware"
$Name = "SuperItem"
$Value = "Super"

try{
    $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($Path, $true)
    $key.SetValue($Name,$Value)
}catch{
    Write-Error "Cant't write to superitem"
}finally{
    $key.Close()
}   

The readability of the first one is kinda better for my point of view. But this way is more secure because the $Path variable only points to the CurrentUser scope and if this snippet would get converted into a function where the user can define the path as a parameter it is even more secure.


Now we can have a look which way is faster:

$StopWatchA = New-Object System.Diagnostics.Stopwatch
$StopWatchC = New-Object System.Diagnostics.Stopwatch

$Randoms = (1..1000).foreach({
    Get-Random -Minimum 1 -Maximum 1000
})

$Path ="HKCU:\SOFTWARE\mysupersoftware"
$Name = "SuperItem"
$StopWatchA.Start()
foreach($Random in $Randoms){
    try{
        Set-ItemProperty -Path $Path -Name $Name -Value $Random -ErrorAction Stop
    }catch{
        Write-Error "Cant't write to superitem"
    }
}
$StopWatchA.Stop()

$Path ="SOFTWARE\mysupersoftware"
$StopWatchC.Start()
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($Path, $true)
foreach($Random in $Randoms){
    try{
        $key.SetValue($Name, $Random)
    }catch{
        Write-Error "Cant't write to superitem"
    } 
}
$key.Close()
$StopWatchC.Stop()

The results of StopWatchA and StopWatchC look like this:

Method Time elapsed Time (ms) elapsed
Set-ItemProperty 00:00:00.8431953 843
[Microsoft.Win32.Registry] 00:00:00.0151768 15

In summary, the .NET method is the one you should use when you need to be as performant as possible or particularly secure in a function. In all other cases, using the native PowerShell method is sufficient.

Best regards, Christian