24

How to set a binary registry value (REG_BINARY) with PowerShell?

Background:

I need to change some properties of the ASP.NET State service using a PowerShell script. Unfortunately, the built-in PowerShell cmdlet Set-Service only lets you modify the service description, startup type, display name, and status. I need to modify the Subsequent failures property found on the Recovery tab (when viewing the service's properties). I found that this value was stored in the registry as a REG_BINARY value.

An export of the value looks like this:

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\aspnet_state]
"FailureActions"=hex:50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,\
  00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00

In Powershell there is a Set-ItemProperty cmdlet with which you can set registry value values. For a string or dword value, you can just pass a string or an int. I know which hex value in the array to change, but I can't figure out how to set a binary value.

brett rogers
  • 6,501
  • 7
  • 33
  • 43

7 Answers7

26

The following line gives you an example how to create one

New-ItemProperty -Path . -Name Test -PropertyType Binary -Value ([byte[]](0x30,0x31,0xFF))

and how to change an existing one:

Set-ItemProperty -Path . -Name Test -Value ([byte[]](0x33,0x32,0xFF))
Howard
  • 38,639
  • 9
  • 64
  • 83
9

This post has helped me out with similar problem. Thanks!

Bringing xBr0k3n and Howard's answers together:

#Change these three to match up to the extracted registry data and run as Admin
$YourInput = "50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00"
$RegPath   = 'HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\aspnet_state'
$AttrName  = "FailureActions"

$hexified = $YourInput.Split(',') | % { "0x$_"}
New-ItemProperty -Path $RegPath -Name $AttrName -PropertyType Binary -Value ([byte[]]$hexified)
Frison Alexander
  • 3,228
  • 2
  • 29
  • 32
8

Is it just me who feels this misses the main part of this question?

How would you go about changing the original:

50,33,01,00,00,00,00,00,00,00,00,00,03,00,00,00,0e,00,00,\
00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00

Into a format like:

([byte[]](0x33,0x32,0xFF))

EDIT: After trying to get this working it turns out you just prefix all of the pairs with '0x'. Not sure why that was not mentioned in the answer. So just change the above to:

0x50,0x33,0x01,0x00,0x00,0x00,0x00,0x00... etc.

Then wrap that in the following:

([byte[]](0x50,0x33,0x01,0x00,0x00,0x00,0x00,0x00... etc.))
xBr0k3n
  • 415
  • 1
  • 5
  • 9
  • The original question isn't about parsing the `*.reg` export format. Although others may come here looking for that, your answer, unlike [Frison Alexander's](https://stackoverflow.com/a/33586470/45375), doesn't actually show how to convert a string such as `'50,33,01,00,00,...'` into an equivalent `[byte[]]` array. – mklement0 Feb 05 '19 at 21:55
4

Resurrecting this.

Here's how you can modify registry item binary values concisely in easy-to-follow powershell. In this example DefaultConnectionSettings is the registry item with a REG_BINARY value that we're trying to modify.

$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
$objName = "DefaultConnectionSettings"
$getObj = Get-ItemProperty -path $path -name $objName
$getObj.DefaultConnectionSettings[8] = 1
$objValue = $getObj.DefaultConnectionSettings
Set-ItemProperty -path $path -name $objName -Value $objValue

When you use Get-ItemProperty for a registry item with a REG_BINARY value, it gives you a number of child objects in a collection.

By referencing the name of the item (in this case we do getObj.DefaultConnectionSettings) as a child object of getObj, we get an array of values, where each binary value (i.e 50,33,01,00,00,00,00,00,04) has its own position in the array.

Because it is an array we can reference, modify, and iterate through it easily by doing $getObj.DefaultConnectionSettings[8] = 1 or whatever number you want in place of 8. The 8 refers to the position of the value in the array. In the example of 50,33,01,00,00,00,00,00,04 the 9th position is 04. Remember that, like other things, arrays start counting at 0.

Setting it = 1 will change that 04 value in the binary to 01 while leaving the rest of the values unchanged in the array.

Finally, we set the change in place with Set-ItemProperty -path $path -name $objName -Value $objValue

Hope this helps others.

Fishcakes
  • 195
  • 1
  • 1
  • 8
  • Great! This, with the `-band` operator, lets me **set a single bit** in `HKCU\Control Panel\Desktop\UserPreferencesMask`. – mivk Mar 29 '22 at 21:38
2

FYI, you can also set binary values with the PSRemoteRegistry PowerShell module ( http://psremoteregistry.codeplex.com/), on local or remote computers.

$Key = 'SOFTWARE\MyCompany'     
Set-RegBinary -Hive LocalMachine -ComputerName Server1 -Key $Key -Value RegBinary -Data @([char[]]'PowerShell')
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
0

Let's start with an integer:

$int = 0xffffffff

Get the bytes:

$bytes = [bitconverter]::GetBytes($int)

Using set-itemproperty with the little knows '-type' parameter that can be used with registry paths:

Set-ItemProperty hkcu:\key1 bin1 $bytes -type binary

Get it back:

$bytes = Get-ItemProperty hkcu:\key1 bin1 | % bin1

Turn 4 bytes into an int:

$int = [bitconverter]::toint32($bytes, 0)

'0x{0:x}' -f $int
0xffffffff
js2010
  • 23,033
  • 6
  • 64
  • 66
0

I had problems with the other solutions, here's what I found to work:

Short Answer:

New-ItemProperty -path $path -name $name -value [byte]0x00,0x01,0x02 -PropertyType Binary

Complete Example:

$path = "HKCU:\Software\Hex-Rays\"
$name = "StrWinStringTypes"
$value = [byte]0x00,0x01,0x02

#if key path found, just add/modify the value/data pair
If (Test-Path($path))
{
    New-ItemProperty -path $path -name $name -value $value -PropertyType Binary -Force | Out-Null
}

#if key path not found, create it first before adding value/data
Else
{
    New-Item -path $path -force
    New-ItemProperty -path $path -name $name -value $value -PropertyType Binary -Force | Out-Null
}
GuidedHacking
  • 3,628
  • 1
  • 9
  • 59