Help Creating Binary registry entries using an input file

This topic contains 9 replies, has 3 voices, and was last updated by Profile photo of charles otstot charles otstot 1 year, 9 months ago.

  • Author
    Posts
  • #30856
    Profile photo of charles otstot
    charles otstot
    Participant

    Hello,
    I'm new to PowerShell, so the answer may be staring me in the face....
    I'm building a script to modify various registry entries using a .csv as an input file.
    The environment is a Win 7 environment, with PowerShell 3.0...

    I'm stuck on properly creating the values for binary entries.
    The section of script is simply adding sites to the "Allowed Sites" list for the pop-up blocker in IE 10 and/or 11 (GPOs are not an option).

    Here's the code-everything seems to work, except that the value is not as expected...

    #Create an array using a .csv file that is formatted and populated with data as indicated below
    # Name,Type,Value
    #Site1,Binary,"00,00"
    $as = @(import-csv 'somepath\Allowed.csv')
    foreach ($a in $as)
    {
    $a.Name,$a.Type,$a.Value
    new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $a.name -type $a.type -Value $a.value
    }

    Running the script against the input file, I consistently get a registry value of {0}, rather than {0,0}. However, if I run the new-itemproprty cmdlet with the -value property discretely entered as 00,00..the value returns {0,0}.
    i.e. "new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $a.name -type *a.type -Value 00,00" returns values as expected...

    I presume my error lies in the properties of the .value noteproperty string value? I'd like to expand the base script to additional registry keys, so I need to make sure I get values to populate properly from the array properties. Am I missing a blatant conversion step, or is my issue more subtle?

    Thanks for any help!

    Charlie O

  • #30858
    Profile photo of Steven Ayers
    Steven Ayers
    Participant

    Can you manually add that value with no problem?

    I've found an example format of what binary values should look like:
    ([byte[]](0x00,0xFF))

    #Create an array using a .csv file that is formatted and populated with data as indicated below
    # Name,Type,Value
    #Site1,Binary,"00,00"
    $as = @(import-csv 'somepath\Allowed.csv')
    foreach ($a in $as)
    {
    $Name = $a.Name
    $Type = $a.Type
    $Value = $a.Value
    new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $Name -type $Type -Value "$Value"
    
  • #30859
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    The issue is due to the data type from the csv file. The binary data is being stored as a string and when you write the value to the registry key the sting is converted to a byte data type.

    $a = "00,00"
    $a #displays as 00,00
    [byte]$a #displays as 0
    

    to properly write the value from the csv you will need to convert $a.Value from a string to a CharArray

    $as = @(import-csv 'PATHTO\Allowed.csv')
    foreach ($a in $as)
    {
    $a.Name,$a.Type,$a.Value
    new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $a.name -type $a.type -Value $a.value.ToCharArray()
    }
    

    also take a look at https://social.technet.microsoft.com/Forums/scriptcenter/en-US/a97a34bb-40cc-4b74-a44d-f90bc733a412/how-to-change-registry-string-and-binary-values-with-powershell?forum=ITCG for more examples of working with binary registry keys

  • #30865
    Profile photo of charles otstot
    charles otstot
    Participant

    Hi Steve...
    I can create the value directly with the cmdlet...
    I've seen a couple of different iterations of the example you found (some with parentheses as yours shows, others with bracket) and they all throw errors, bracketed attempts give positional parameter errors or improper value format errors, depending upon how it's bracketed. Those enclosed in parentheses throw expression errors.

    I tried your version and it does not throw an error with the input file values formatted as I've shown in the top of my post, but the value still only writes as {0} (but this at least indicates that the iteration you found is the correct syntax).
    If I change the values in my input file to "0x00,0x00"-the script throws "Cannot convert value "0x00,0x00" to type "System.Byte." Error: "Additional non-parsable characters are at the end of the string."

    If I run the cmdlet manually with the value as indicated in your example (...-Value ([byte[]] (0x00,0x00))...), everything works fine. Including the value as (00,00) also works if entered in the example format.
    Additionally, simply including the value as 00,00 with type binary without the [byte[]] statements also works. In all three cases, running the command manually returns {0, 0} for the value (perfectly formatted binary value)...

    Truly puzzling to me at this point...

  • #30866
    Profile photo of Steven Ayers
    Steven Ayers
    Participant

    Hi Charles,

    Jonathan actually gave you a far more useful answer than me, and taught me something in reading it myself.

    Just do some trial an error, for example, try swapping out $value1, $value2 and $value3. I've never attempted what you're attempting, but just play around with it 🙂

    "0x00,0x00"-the script throws "Cannot convert value "0x00,0x00" to type "System.Byte. tells me this is all along the right lines...

    Please let me know what worked!

     
    #Create an array using a .csv file that is formatted and populated with data as indicated below
    # Name,Type,Value
    #Site1,Binary,"00,00"
    $as = @(import-csv 'somepath\Allowed.csv')
    foreach ($a in $as)
    {
    $Name = $a.Name
    $Type = $a.Type
    $StringValue = $a.Value
    $Value1 = [byte]$StringValue
    $Value2 = $StringValue.ToCharArray()
    $Value3 = [byte]$StringValue.ToCharArray()
    
    new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $Name -type $Type -Value $Value1
    
  • #30880
    Profile photo of charles otstot
    charles otstot
    Participant

    OK...still puzzled here...
    Thanks for the input Jonathan...Your cause is pretty much what I suspected...
    I'm guessing my remaining issues are with translation and my (lack) of knowledge therein,,,
    The csv has a value of 00,00 (in quotes to match specs for csv)
    Using ToCharArray for $a.value yields:
    Script output of {48, 48, 44, 48...}-matching the decimal character for the Hex characters appearing in the registry
    Registry setting of 30 30 2c 30 30- matching the hex character to decimal? output in the script
    instead of script output of {0, 0}
    Registry setting of 00 00

  • #30885
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    You can store the string value in your csv and use your code to convert to the binary value

    # Name,Type,Value
    #Site1,Binary,"www.powershell.org"
    $as = @(import-csv 'd:\test\test.csv')
    foreach ($a in $as){
        $a.Name,$a.Type,$a.Value
        #This assumes the csv file is encoded as ASCII
        $new = [System.Text.Encoding]::ASCII.GetBytes($a.Value)
        # If the file is encoded as unicode use the below line 
        # $new = [System.Text.Encoding]::UniCode.GetBytes($a.Value)
        $new
        [System.Text.Encoding]::ASCII.GetString($new)
        # [System.Text.Encoding]::UniCode.GetString($new)
    }
    

    Here is some helpful info about what you see when you look at the registry key
    http://blogs.technet.com/b/heyscriptingguy/archive/2005/02/24/how-can-i-write-binary-data-to-the-registry.aspx

  • #30907
    Profile photo of charles otstot
    charles otstot
    Participant

    Still no love using any of the methods...
    It appears that if the input to -Value is evaluated to a single instance of 00,00, it is output as a single 0. Most frustrating!

    I did find a workaround for the specific case of 00,00 as the input for a binary registry value that should output to 00 00 in the registry...
    I simply added a column to my csv and separated the instances of 00...
    Now the csv looks like this:
    Name,Type,Value1,Value2
    Somesite,Binary,00,00
    Now, new-property line looks like:
    new-itemproperty -path 'HKCU:\software\Microsoft\Internet Explorer\New Windows\Allow' -name $a.name -Value $a.value1,$a.value2 -type $a.type
    Script output is:
    *.test1.cso : {0, 0} (as desired)
    Registry output is
    *.test1.cso Reg_Binary 00 00 (as desired)

    I know this is a limited solution, so please, any additional info would be appreciated and I'll keep digging as well...

    Charlie

  • #30912
    Profile photo of Steven Ayers
    Steven Ayers
    Participant

    Are you sure you're writing out your binary in a valid format?

    Here's what I would do:
    Test out some example strings you find on the internet, For Example "(0x00,0xFF)". Put it in a variable and try to convert it, once you've converted it successfully and pipe it to get-member to see if it's what you want.

        $test = "(0x00,0xFF)"
        $new = [System.Text.Encoding]::ASCII.GetBytes($test)
        # If the file is encoded as unicode use the below line 
        # $new = [System.Text.Encoding]::UniCode.GetBytes($test)
        $new
        $new | gm
    

    Then, use the string you're trying to use, does it convert? does it work as expected?

    I don't have a direct answer for you, but hopefully if this is helpful you'll come back and tell me how it's done 🙂

  • #30914
    Profile photo of charles otstot
    charles otstot
    Participant

    Thanks Stephen...
    It's very possible that my original premise is incorrect...I'm not the brightest candle in the room working with character sets 🙂
    I'll definitely spend some more time researching (and testing your example)... 🙂
    I know that the workaround I have is limited and doesn't give the flexibility needed for anything other than this specific use case, so I'll need to work on it more...

    The big key in the long run will be writing something that I can give a tech such that he/she can simply provide the base information to the input file (reg keys, value name, value type, value) in common formats and get the script to do the interpretation correctly across a range of input types (that will take a little figuring out...:) ). For now, I've got a short-term solution that can be deployed for the point problem and similar problems that will give me the breathing room to build a more complete and correct long-term solution...

    Thanks!
    Charlie

You must be logged in to reply to this topic.