Group Policy

הפצת Registry ב-GPO

צריכים להפיץ ערך ברגיסטרי לכל המחשבים בדומיין? כך תעשו זאת

גילוי נאות: הנהלת האתר לא תישא בשום נזק כלשהו שייגרם כתוצאה מעבודה לפי מדריך זה. השינויים והעבודה על אחריות המשתמש בלבד.

סמפטום

ישנן תקלות שחוזרות על עצמן לאחר כל logoff ו-logon. במקום להגדיר סקריפט שירוץ על העמדה ברמת משתמש, מומלץ להכניס הפצת ערך ברגיסטרי מצד השרת ברמת המחשב. איך זה מתבצע?

הוספת ערך ב-Registry ב-GPO באופן ידני

לאחר שפתחנו את הפוליסי שלנו:

ניגש ב-GPO אל הנתיב:

Computer Configuration\Preferences\Windows Settings\Registry

להוספת Registry ניתן ללחוץ על כפתור הפלוס:

וכאן ניתן להגדיר היכן למקם את הערך, מה יהיה שמו, ואיזה ערך לתת לו:

המרת והעתקת קובץ Reg מוכן ל-GPO באמצעות Powershell

שיטה נחמדה יותר היא להעתיק את קובץ ה-REG לחלונית ה-GPO.

מתי נשתמש בה? כאשר נרצה לבצע Export משרת אחד ולאחר מכן Import לשרת אחר.

ניתן כמובן ליצור קובץ REG עם הערכים הרלוונטים או לייצא את מה שרוצים ישירות מתוך ה Registry..

אם ננסה להעתיק את קובץ ה-REG כמות שהוא- זה לא יתאפשר.

על מנת להכניס את קובץ ה-REG, יש צורך להמיר אותו קודם כל לקובץ XML.

ההמרה נעשית באמצעות שימוש בסקריפט Powershell הבא:

<# Added by Michael Pietroforte #>
Param(
  [Parameter(Mandatory=$True)][string]$regPath,
  [Parameter(Mandatory=$True)][string]$xmlPath
  )

<# 
Orginal script by Malcolm McCaffery  
More info at the http://chentiangemalc.wordpress.com/2014/07/02/importing-reg-files-into-group-policy-preferences/
#>

function Convert-RegEscapeCodes
{
Param(
    [Parameter(Position=1)][string]$regstring)
    return $regstring.Replace("\\","\").Replace('\"','"')
}

function Convert-Reg2Xml
{
Param(
  [Parameter(Mandatory=$True)][string]$regPath,
  [Parameter(Mandatory=$True)][string]$xmlPath
  )


  $clsidCollection = "{53B533F5-224C-47e3-B01B-CA3B3F3FF4BF}"
  $clsidRegistry =   "{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}"

  $settings = New-Object System.Xml.XmlWriterSettings
  $settings.Indent=$True
  $settings.Encoding = [System.Text.Encoding]::UTF8

  $xml = [System.Xml.XmlWriter]::Create($xmlPath,$settings)
  $descr = "Imported Reg File"
  $action = "U"

  $unicoder = New-Object System.Text.UnicodeEncoding

  $lastHive="";
  $lastKey="";
  write-host $regPath
  $sr=New-Object System.IO.StreamReader($regPath)

  $lastHive=""
  $lastKey=""

  $collectionCount=0

  while (!$sr.EndOfStream)
  {
  
    $line = $sr.ReadLine()
    if ($line.StartsWith("["))
    {
        $currentHive=$line.Substring(1,$line.IndexOf("\")-1)
        $currentKey=$line.Substring($line.IndexOf("\")+1,$line.Length-$line.IndexOf("\")-2)

        if ($lastHive -eq "")
        {
            $xml.WriteStartElement("Collection")
            $xml.WriteAttributeString("clsid",$clsidCollection)
            $xml.WriteAttributeString("name",$currentHive)
            $collectionCount++

            ForEach ($key in $currentKey.Split('\'))
            {
                $xml.WriteStartElement("Collection")
                $xml.WriteAttributeString("clsid",$clsidCollection)
                $xml.WriteAttributeString("name",$key)
                $collectionCount++
            }
        }
        else
        {
           # hives don't match - settings.xml doesn't support this!
            if ($currentHive -ne $lastHive)
            {
               # invalid - settings.xml only supports one HIVE type per file
               Throw "Reg file format is not supported by settings .XML. Please use only $currentHive or $lastHive per XML file"
               return
            }
            else
            {
                # going up a key
                if ($currentKey.StartsWith($lastKey + "\"))
                {
                    $newKey=$currentKey.Substring($lastKey.Length+1)
                    ForEach ($key in $newKey.Split('\'))
                    {
                        $xml.WriteStartElement("Collection")
                        $xml.WriteAttributeString("clsid",$clsidCollection)
                        $xml.WriteAttributeString("name",$key)
                        $collectionCount++
                    }
                }
                else
                {
                    # funky logic to handle change in key path
                    # maybe this logic even works :)
                    $currentKeySplit=$currentKey.Split('\')
                    $lastKeySplit=$lastKey.Split('\')

                    $match=$true

                    $i=-1

                    while ($match)
                    {
                        $i++
                        if ($i -ge $currentKeySplit.Length -or $i -ge $lastKeySplit.Length)
                        {
                            $match=$false
                        }
                        else
                        {
                            if ($currentKeySplit[$i] -ne $lastKeySplit[$i]) { $match=$false }
                        }
                    }

                    for ($x=$lastKeySplit.Length;$x -gt $i;$x--)
                    {
                        $xml.WriteEndElement()
                        $collectionCount--
                    }

                    for ($x=$i;$x -lt $currentKeySplit.Length;$x++)
                    {
                        $xml.WriteStartElement("Collection")
                        $xml.WriteAttributeString("clsid",$clsidCollection)
                        $xml.WriteAttributeString("name",$currentKeySplit[$x])
                        $collectionCount++
                    }
                    
                }
            }
        }
        
        $lastHive=$currentHive
        $lastKey=$currentKey
    }
    else
    {
        if ($line.Contains("="))
        {
            $regType=[Microsoft.Win32.RegistryValueKind]::Unknown

            # detect registry type 
            if ($line.StartsWith("@=") -or $line.Contains('"="')) { $regType=[Microsoft.Win32.RegistryValueKind]::String }
            if ($line.Contains("=hex:")) { $regType=[Microsoft.Win32.RegistryValueKind]::Binary }
            if ($line.Contains("=dword:")) { $regType=[Microsoft.Win32.RegistryValueKind]::DWord }
            if ($line.Contains("=hex(7):")) { $regType=[Microsoft.Win32.RegistryValueKind]::MultiString }
            if ($line.Contains("=hex(2):")) { $regType=[Microsoft.Win32.RegistryValueKind]::ExpandString }
            if ($line.Contains("=hex(b):")) { $regType=[Microsoft.Win32.RegistryValueKind]::QWord }

            switch ($regType)
            {
                # *** PROCESS REG_SZ
                ([Microsoft.Win32.RegistryValueKind]::String)
                {
                    $default="0"
                    if ($line.StartsWith("@="))
                    {
                        $valueName=""
                        $value=$line.Substring(3,$line.Length-4)
                        "Name = '$valueName' Value = '$value'"
                        $default="1"
                    }
                    else
                    {
                        $i = $line.IndexOf('"="')
                        $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                        $value=Convert-RegEscapeCodes $line.Substring($i+3,$line.Length-$i-4)
                       "Name = '$valueName' Value = '$value'"
                 
                    }

                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","7")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default",$default)
                    $xml.WriteattributeString("type","REG_SZ")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value)
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
         }

                # *** PROCESS REG_BINARY
                ([Microsoft.Win32.RegistryValueKind]::Binary)
                {
                    # read binary key to end
                    while ($line.EndsWith("\"))
                    {
                        $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim()
                    }

                    $i = $line.IndexOf('"=hex:')
                    $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                    $value=$line.Substring($i+6).Replace(",","")
                    "Name = '$valueName' Value = '$value'"

                    # build XML
                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","17")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default","0")
                    $xml.WriteattributeString("type","REG_BINARY")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value)
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()

                }

                # *** PROCESS REG_DWORD
                ([Microsoft.Win32.RegistryValueKind]::DWord)
                {
                
                    $i = $line.IndexOf('"=dword:')
                    $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                    $value=$line.Substring($i+8).ToUpper()
                     "Name = '$valueName' Value = '$value'"

                    # build XML
                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","17")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default","0")
                    $xml.WriteattributeString("type","REG_DWORD")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value)
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
                }

                # *** PROCESS REG_QWORD
                ([Microsoft.Win32.RegistryValueKind]::QWord)
                {
                    $i = $line.IndexOf('"=hex(b):')
                    $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                    $tempValue=$line.Substring($i+9).Replace(",","").ToUpper()
                    $value=""

                    # unreverse QWORD for settings.xml format
                    for ($i = $tempValue.Length -2;$i -gt 0;$i-=2)
                    {
                        $value+=$tempValue.Substring($i,2)
                    }
                    
                     "Name = '$valueName' Value = '$value'"

                     # build XML
                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","17")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default","0")
                    $xml.WriteattributeString("type","REG_QWORD")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value)
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
                }

                # *** PROESS REG_MULTI_MZ
                ([Microsoft.Win32.RegistryValueKind]::MultiString)
                {
                    # read binary key to end
                    while ($line.EndsWith("\"))
                    {
                        $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim()
                    }

                    # read hex codes
                    $i = $line.IndexOf('"=hex(7):')
                    $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                    $value=$line.Substring($i+9).Replace(",","")
                    # convert hex codes to binary array
                    $byteLength=$value.Length/2
                    $byte = New-Object Byte[] $byteLength
                    
                    $x=0
                    for ($i=0;$i -lt $value.Length;$i+=2)
                    {
                        $byte[$x]="0x" + $value.Substring($i,2)
                        $x++
                    }

                    # convert binary array to unicode string
                    $value=$unicoder.GetString($byte)

                    # retrieve multi values
                    $values=$value.Replace("`0`0","").Split("`0")
                    
                    "Name = '$valueName'"

                     # build XML
                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","7")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default","0")
                    $xml.WriteattributeString("type","REG_MULTI_SZ")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value.Replace("`0"," "))
                   
                    $x=1

                    $xml.WriteStartElement("Values")

                    ForEach ($value in $values)
                    {
                        $xml.WriteStartElement("Value")
                        $xml.WriteString($value)
                        "Value $x = '$value'"
                        $xml.WriteEndElement()
                    }
                    
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
                }

                ([Microsoft.Win32.RegistryValueKind]::ExpandString)
                {
                    # read binary key to end
                    while ($line.EndsWith("\"))
                    {
                        $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim()
                    }

                    # read hex codes
                    $i = $line.IndexOf('"=hex(2):')
                    $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
                    $value=$line.Substring($i+9).Replace(",","")
                    # convert hex codes to binary array
                    $byteLength=$value.Length/2
                    $byte = New-Object Byte[] $byteLength
                    
                    $x=0
                    for ($i=0;$i -lt $value.Length;$i+=2)
                    {
                        $byte[$x]="0x" + $value.Substring($i,2)
                        $x++
                    }

                    # convert binary array to unicode string
                    $value=$unicoder.GetString($byte).Replace("`0","")
                    "Name = '$valueName' Value = '$value'"

                    $xml.WriteStartElement("Registry")
                    $xml.WriteAttributeString("clsid",$clsidRegistry)
                    $xml.WriteAttributeString("name",$valueName)
                    $xml.WriteAttributeString("descr",$descr)
                    $xml.WriteAttributeString("image","7")
                   
                    $xml.WriteStartElement("Properties")
                    $xml.WriteAttributeString("action",$action)
                    $xml.WriteAttributeString("hive",$currentHive)
                    $xml.WriteAttributeString("key",$currentKey)
                    $xml.WriteattributeString("name",$valueName)
                    $xml.WriteattributeString("default",$default)
                    $xml.WriteattributeString("type","REG_EXPAND_SZ")
                    $xml.WriteattributeString("displayDecimal","0")
                    $xml.WriteAttributeString("value",$value)
                    $xml.WriteEndElement()
                    $xml.WriteEndElement()
                }

            }

        }
        
    }

  }
  
  $sr.Close()
  while ($collectionCount -gt 0)
  {
        $xml.WriteEndElement()
        $collectionCount--
    }

    $xml.Close()
  
}
<# Replaced by Michael Pietroforte
 Convert-Reg2Xml -regPath "C:\support\ReceiverCSTRegUpx64.reg" -xmlPath C:\support\Citrix.xml #>
 Convert-Reg2Xml -regPath $regPath -xmlPath $xmlPath

המרת קובץ Reg לקובץ XML


מורידים את הסקריפט המצורף, מריצים אותו בעזרת PowerShell כאדמין (הסקריפט עצמו הוא בסיומת ps1).
נכניס בשורה הראשונה את הנתיב המלא לקובץ reg, למשל:
c:\intel\1.reg
בשורה השניה נכתוב את המיקום המלא כולל הסיומת xml לנתיב שאליו נרצה לייצא את הקובץ, למשל:
c:\intel\1.xml

לאחר מכן הסקריפט יצור לנו קובץ xml עם השם שנתנו לו.

זה נראה כך:

PS C:\intel> .\RegToXML.ps1

cmdlet RegToXML.ps1 at command pipeline position 1
Supply values for the following parameters:
regPath: C:\intel\1.reg
xmlPath: c:\intel\1.xml
C:\intel\1.reg
Name = 'DisableLocationScripting' Value = '00000001'
Name = 'DisableWindowsLocationProvider' Value = '00000001'
Name = 'DisableLocation' Value = '00000001'
Name = 'DisableSensors' Value = '00000001'
PS C:\intel>

בסיום יופיע לנו קובץ XML במיקום שהגדרנו:

יש לי קובץ XML מה עושים כעת?

כעת גוררים (או נעתיק ונדביק) את קובץ ה-XML אל חלונית ה-Registry ב-GPO:

כאן תוקפץ החלונית הבאה בה נלחץ על אישור:

נוכל לראות כעת שהקובץ נטען לתוך הרגיסטרי ב-GPO:

נוכל לראות את המיקום של ערך הרגיסטרי אם נפתח את עץ התיקיות (בצד שמאל) אשר מתחת לערך שהוספנו.

חשוב מאוד! החלת ה-GPO על השרת הרצוי

כעת נותר רק לקשר את ה-GPO לשרת שלנו:

נבחר את ה-GPO הרצוי ונאשר:

קרדיט לשמואל אלון על המדריך.

Rami

יזם, איש סיסטם, מתכנת בחסד, ונושם אינטרנט.

מאמרים קשורים

Leave a Reply

Your email address will not be published. Required fields are marked *

אתה תאהב גם את זה
Close
Back to top button
Skip to content