Chef registry_key with binary values
Yesterday, I needed to add a few registry keys to a CHEF cookbook that I am developing for a client. I am creating a base OS cookbook for Windows and as part of the solution, we need to update registry keys. In the past, I have done some minor work with basic DWORD and REG_SZ values. In this case, I needed to adjust a BINARY value and more specifically a single key in that BINARY value. This leads me to an interesting challenge. What is the required syntax and more specifically, how do I update the code. After a lot of trial and error, I finally figured out the formatting and the required configuration:
def get_current_values(key, name) data_array = [] # Use native helper registry_get_values based on the Key passed. subkey_array = registry_get_values(key, :machine) subkey_array.each do |values| # Return a variable of the data values by first converting the value to a string and then # splitting into characters and returning the object as an array of chrs. # Only perform if the name of the subkey matches required name. data_array = values[:data].to_s.chars.map(&:chr) if values[:name] == name end data_array end
Once I created this new method, I could easily call it as part of the custom_resource action. In my case, I also needed to update a single octet in the data_array. Since the values return as an array, this was actually easy to do but the format of the call is a little different. For this example, I am going to update the Internet Explorer Proxy settings and specifically the Key – HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections\DefaultConnectionSettings
key_root ='HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections' key_data_value = get_current_values(key_root, 'DefaultConnectionSettings') # Update the 9th element in the array (corresponds to the 8th byte) by setting a decimal value enclosed # as a string and returning it as a Hex which is converted into a chr() encoded value. This # is required in order to ensure that the correctly formatted value is placed into the binary object. key_data_value[8] = '13'.hex.chr # Sets the value to HEX 0D registry_key 'Reset Autodetect to default' do key 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections' values [{ name: 'DefaultConnectionSettings', type: :binary, # We need to return the array as a single string hence the join data: key_data_value.join }] action :create end
After all of that, we can now edit a single octet of a binary registry key and return the correctly formatted value. This might seem like we are doing a lot of conversions but each of these conversions ensure the return of a validly encoded binary value. Hopefully, this will save you some stress and headaches the next time that you need to edit a binary registry key for your next Windows+CHEF project.