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 *

Back to top button