├── .gitattributes ├── .gitignore ├── App.config ├── PolFileManager.cs ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx ├── README.md ├── SetPol.csproj └── SetPol.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PolFileManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace SetPol { 6 | //much of the code in here is geared towards saving these settings into domain-based GPOs but the core get/set/save are used by setpol to save against a known pol file. 7 | public enum PolType 8 | { 9 | Computer, 10 | User 11 | } 12 | public enum KeyType { 13 | REG_BINARY = 3, 14 | REG_DWORD = 4, 15 | REG_DWORD_LITTLE_ENDIAN = 4, 16 | REG_DWORD_BIG_ENDIAN = 5, 17 | REG_EXPAND_SZ = 2, 18 | REG_LINK = 6, 19 | REG_MULTI_SZ = 7, 20 | REG_NONE = 0, 21 | REG_QWORD = 11, 22 | REG_QWORD_LITTLE_ENDIAN = 11, 23 | REG_SZ = 1 24 | } 25 | 26 | public class PolValue { 27 | public string m_Key; 28 | public string m_Value; 29 | public KeyType m_KeyType; 30 | public int m_DataSize; 31 | public byte[] m_Data; 32 | public bool m_bDeleteValue = false; 33 | 34 | public System.Collections.ArrayList m_Parsed; 35 | 36 | public string GetDataAsString() { 37 | string ret = ""; 38 | for ( long l = 0; l < m_Data.Length; l=l+2 ) { 39 | char c = System.Convert.ToChar((m_Data[l+1] << 8) + m_Data[l]); 40 | if ( c != 0 && c != '\n' ) 41 | ret += c; 42 | } 43 | return ret; 44 | } 45 | public ulong GetDataAsDWORD() { 46 | ulong ret = 0; 47 | if ( m_Data.Length >= 4 ) 48 | ret = (ulong)((m_Data[3]<<24) + (m_Data[2]<<16) + (m_Data[1]<<8) + (m_Data[0])); 49 | return ret; 50 | } 51 | public void SetDataAsEmpty() 52 | { 53 | m_DataSize = 2; 54 | m_Data = new byte[m_DataSize]; 55 | } 56 | public void SetDataAsString( string val ) { 57 | m_DataSize = val.Length*2; 58 | m_Data = new byte[m_DataSize]; 59 | System.CharEnumerator ce = val.GetEnumerator(); 60 | long l = 0; 61 | while ( ce.MoveNext() ) { 62 | m_Data[l] = (byte)(ce.Current&0xFF); 63 | l++; 64 | m_Data[l] = (byte)(ce.Current>>8); 65 | l++; 66 | } 67 | } 68 | public void SetDataAsMString(string[] arr, int Length) 69 | { 70 | m_DataSize = (Length+arr.Length) * 2; 71 | m_Data = new byte[m_DataSize]; 72 | long l = 0; 73 | foreach (string elem in arr) 74 | { 75 | if (string.IsNullOrEmpty(elem)) 76 | continue; 77 | System.CharEnumerator ce = elem.GetEnumerator(); 78 | while (ce.MoveNext()) 79 | { 80 | m_Data[l] = (byte)(ce.Current & 0xFF); 81 | l++; 82 | m_Data[l] = (byte)(ce.Current >> 8); 83 | l++; 84 | } 85 | m_Data[l] = 0; 86 | l++; 87 | m_Data[l] = 0; 88 | l++; 89 | } 90 | } 91 | public void SetDataAsDWORD(ulong val) { 92 | m_DataSize = 4; 93 | m_Data = new byte[m_DataSize]; 94 | m_Data[0] = (byte)(val&0xFF); 95 | m_Data[1] = (byte)((val&0xFF00)>>8); 96 | m_Data[2] = (byte)((val&0xFF0000)>>16); 97 | m_Data[3] = (byte)((val&0xFF000000)>>24); 98 | } 99 | public void SetDataAsQWORD(UInt64 val) 100 | { 101 | m_DataSize = 8; 102 | m_Data = new byte[m_DataSize]; 103 | m_Data[0] = (byte)(val & 0xFF); 104 | m_Data[1] = (byte)((val & 0xFF00) >> 8); 105 | m_Data[2] = (byte)((val & 0xFF0000) >> 16); 106 | m_Data[3] = (byte)((val & 0xFF000000) >> 24); 107 | m_Data[4] = (byte)((val & 0xFF00000000) >> 32); 108 | m_Data[5] = (byte)((val & 0xFF0000000000) >> 40); 109 | m_Data[6] = (byte)((val & 0xFF000000000000) >> 48); 110 | m_Data[7] = (byte)((val & 0xFF00000000000000) >> 56); 111 | } 112 | } 113 | public class PolFileManager { 114 | public void OpenPolFile(string path, PolType type) { 115 | if ( type == PolType.Computer ) { 116 | if ( m_path_c != null && m_path_c.Length > 0 ) 117 | return; 118 | m_vals_c = new System.Collections.Generic.Dictionary(); 119 | m_path_c = path; 120 | } else { 121 | if ( m_path_u != null && m_path_u.Length > 0 ) 122 | return; 123 | m_vals_u = new System.Collections.Generic.Dictionary(); 124 | m_path_u = path; 125 | } 126 | if (File.Exists(path) ) { 127 | byte[] file = File.ReadAllBytes(path); 128 | if ( !( file[0] == 0x50 && 129 | file[1] == 0x52 && 130 | file[2] == 0x65 && 131 | file[3] == 0x67 && 132 | file[4] == 0x01 && 133 | file[5] == 0x00 && 134 | file[6] == 0x00 && 135 | file[7] == 0x00 ) ) { 136 | System.String str = Properties.Resources.IDS_INVALID_POL_FORMAT; 137 | throw new Exception(String.Format(str,path)); 138 | } 139 | FillVals(file,type); 140 | } 141 | } 142 | public PolValue Get(string key, PolType type) { 143 | System.Collections.Generic.Dictionary dict = GetVals(type); 144 | string [] splitKey = key.Split(new char[] {'\\'}); 145 | int splitLength = splitKey.Length; 146 | //create a variable that includes the reg path minus the valuename so that we can compare that as well down below 147 | string keyName = key.TrimEnd(splitKey[splitLength - 1].ToCharArray()); 148 | foreach (string dictKey in dict.Keys) 149 | { 150 | string[] splitDict = dictKey.Split(new char[] { '\\' }); 151 | if (splitDict[splitDict.Length-1].Equals(splitKey[splitLength - 1].ToLower()) && dictKey.Contains(keyName.ToLower())) 152 | return (PolValue)GetVals(type)[dictKey.ToLower()]; 153 | 154 | } 155 | return null; 156 | } 157 | public System.Collections.Generic.Dictionary GetVals(string key, PolType type) 158 | { 159 | System.Collections.Generic.Dictionary dict = GetVals(type); 160 | return dict; 161 | } 162 | public System.Collections.ArrayList GetLike(string Key, PolType type) { 163 | System.Collections.ArrayList arr = new System.Collections.ArrayList(); 164 | foreach ( KeyValuePair val in GetVals(type) ) { 165 | PolValue vl = (PolValue)(val.Value); 166 | string k = val.Key.ToString(); 167 | System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match( k, Key, System.Text.RegularExpressions.RegexOptions.IgnoreCase); 168 | if (m.Success) 169 | { 170 | PolValue newval = new PolValue(); 171 | newval.m_Key = vl.m_Key; 172 | newval.m_Value = vl.m_Value; 173 | newval.m_KeyType = vl.m_KeyType; 174 | newval.m_DataSize = vl.m_DataSize; 175 | newval.m_Data = vl.m_Data; 176 | newval.m_Parsed = new System.Collections.ArrayList(); 177 | newval.m_Parsed.Clear(); 178 | newval.m_Parsed.AddRange(m.Groups); 179 | arr.Add(newval); 180 | } 181 | } 182 | return arr; 183 | } 184 | public void Set(PolValue val, PolType type) { 185 | // generate key 186 | string key = val.m_Key + "\\" + val.m_Value; 187 | key = key.ToLower(); 188 | // generate disabled/enabled (inverse) key based on provided key 189 | string delPrefix = "**del."; 190 | string inverseKey = val.m_Key + "\\" + delPrefix + val.m_Value; 191 | if (val.m_Value.Length >= 6 && val.m_Value.Contains(delPrefix)) 192 | { 193 | inverseKey = val.m_Key + "\\" + val.m_Value.Substring(6, val.m_Value.Length - 6); 194 | } 195 | inverseKey = inverseKey.ToLower(); 196 | // check if key is being disabled 197 | if (val.m_bDeleteValue) 198 | { 199 | // remove key 200 | Remove(key, type); 201 | // add disabled key 202 | GetVals(type).Add(inverseKey, val); 203 | } 204 | else 205 | { 206 | // check if key already exists 207 | if (GetVals(type).ContainsKey(key)) 208 | { 209 | // update key value 210 | GetVals(type)[key] = val; 211 | } 212 | else 213 | { 214 | // check if inverse key already exists 215 | if (GetVals(type).ContainsKey(inverseKey)) 216 | { 217 | // remove inverse key 218 | Remove(inverseKey, type); 219 | } 220 | // add new key 221 | GetVals(type).Add(key, val); 222 | } 223 | } 224 | } 225 | public void Remove(string key, PolType type) { 226 | GetVals(type).Remove(key.ToLower()); 227 | } 228 | public void SavePolFile(PolType type) { 229 | byte[] file = FillFile(type); 230 | File.WriteAllBytes(GetPath(type),file); 231 | } 232 | private enum CurrentToken { 233 | None = 0, 234 | Key, 235 | Value, 236 | Type, 237 | Size, 238 | Data } 239 | private void FillVals(byte[] file, PolType type) { 240 | long start = 8; 241 | PolValue pv = null; 242 | string token = ""; 243 | byte[] buf = new byte [file.Length]; 244 | int buf_size = 0; 245 | CurrentToken curtoken = CurrentToken.None; 246 | for ( long l = start; l < file.Length; l=l+2 ) { 247 | if ( file[l] == '[' && pv == null ) { 248 | pv = new PolValue(); 249 | curtoken = CurrentToken.Key; 250 | continue; 251 | } 252 | if ( file[l] == ';' && curtoken != CurrentToken.Data ) { 253 | switch (curtoken) { 254 | case CurrentToken.Key: 255 | { 256 | pv.m_Key = token; 257 | curtoken = CurrentToken.Value; 258 | break; 259 | } 260 | case CurrentToken.Value: 261 | { 262 | pv.m_Value = token; 263 | curtoken = CurrentToken.Type; 264 | break; 265 | } 266 | case CurrentToken.Type: 267 | { 268 | pv.m_KeyType = (KeyType)((file[l-1]<<24) + (file[l-2]<<16) + (file[l-3]<<8) + (file[l-4])); 269 | curtoken = CurrentToken.Size; 270 | break; 271 | } 272 | case CurrentToken.Size: 273 | { 274 | pv.m_DataSize = ((file[l-1]<<24) + (file[l-2]<<16) + (file[l-3]<<8) + (file[l-4])); 275 | curtoken = CurrentToken.Data; 276 | break; 277 | } 278 | case CurrentToken.Data: 279 | case CurrentToken.None: 280 | default: 281 | { 282 | System.String str = Properties.Resources.IDS_INVALID_POL_FORMAT; 283 | throw new Exception(String.Format(str,GetPath(type))); 284 | } 285 | } 286 | token = ""; 287 | continue; 288 | } 289 | if ( file[l] == ']' && buf_size >= pv.m_DataSize ) { 290 | pv.m_Data = new byte[buf_size]; 291 | Array.Copy(buf,pv.m_Data, buf_size); 292 | buf_size = 0; 293 | GetVals(type)[pv.m_Key.ToLower() + "\\" + pv.m_Value.ToLower()]=pv; 294 | pv = null; 295 | token = ""; 296 | continue; 297 | } 298 | if ( curtoken == CurrentToken.Data ) { 299 | buf[buf_size] = file[l]; 300 | buf_size++; 301 | if ( buf_size < pv.m_DataSize ) { 302 | buf[buf_size] = file[l+1]; 303 | buf_size++; 304 | } else { 305 | l--; 306 | } 307 | } else { 308 | char c = System.Convert.ToChar((file[l+1] << 8) + file[l]); 309 | if ( c != 0 ) 310 | token += c; 311 | } 312 | } 313 | } 314 | private byte[] FillFile(PolType type) { 315 | System.Collections.ArrayList arr = new System.Collections.ArrayList(); 316 | arr.Add (0x50 ); 317 | arr.Add (0x52 ); 318 | arr.Add (0x65 ); 319 | arr.Add (0x67 ); 320 | arr.Add (0x01 ); 321 | arr.Add (0x00 ); 322 | arr.Add (0x00 ); 323 | arr.Add (0x00 ); 324 | foreach ( KeyValuePair val in GetVals(type) ) { 325 | //foreach ( System.Collections.DictionaryEntry val in GetVals(type) ) { 326 | PolValue vl = (PolValue)(val.Value); 327 | arr.Add('['); 328 | arr.Add(0); 329 | 330 | // key 331 | System.CharEnumerator ce = vl.m_Key.GetEnumerator(); 332 | while ( ce.MoveNext() ) { 333 | arr.Add ( (ce.Current&0xFF) ); 334 | arr.Add ( (ce.Current>>8) ); 335 | } 336 | arr.Add(0); 337 | arr.Add(0); 338 | arr.Add(';'); 339 | arr.Add(0); 340 | 341 | // value 342 | ce = vl.m_Value.GetEnumerator(); 343 | while ( ce.MoveNext() ) { 344 | arr.Add ( (ce.Current&0xFF) ); 345 | arr.Add ( (ce.Current>>8) ); 346 | } 347 | arr.Add(0); 348 | arr.Add(0); 349 | arr.Add(';'); 350 | arr.Add(0); 351 | 352 | // type 353 | int l = (int)vl.m_KeyType; 354 | arr.Add( (l&0x000000FF) ); 355 | arr.Add( ((l>>8)&0x0000FFFF) ); 356 | arr.Add( ((l>>16)&0x00FFFFFF) ); 357 | arr.Add( (l>>24) ); 358 | arr.Add(';'); 359 | arr.Add(0); 360 | 361 | //size 362 | 363 | int data_size = vl.m_DataSize; 364 | if ( vl.m_KeyType == KeyType.REG_SZ || 365 | vl.m_KeyType == KeyType.REG_EXPAND_SZ || 366 | vl.m_KeyType == KeyType.REG_MULTI_SZ ) 367 | { 368 | data_size += 2; 369 | } 370 | 371 | l = data_size; 372 | arr.Add( (l&0x000000FF) ); 373 | arr.Add( ((l>>8)&0x0000FFFF) ); 374 | arr.Add( ((l>>16)&0x00FFFFFF) ); 375 | arr.Add( (l>>24) ); 376 | 377 | arr.Add(';'); 378 | arr.Add(0); 379 | 380 | 381 | for ( int i = 0; i < vl.m_Data.Length; i++ ) { 382 | arr.Add(vl.m_Data[i]); 383 | } 384 | 385 | if ( vl.m_KeyType == KeyType.REG_SZ || 386 | vl.m_KeyType == KeyType.REG_EXPAND_SZ || 387 | vl.m_KeyType == KeyType.REG_MULTI_SZ ) 388 | { 389 | arr.Add(0); 390 | arr.Add(0); 391 | } 392 | arr.Add(']'); 393 | arr.Add(0); 394 | } 395 | byte[] res = new byte[arr.Count]; 396 | for ( int i = 0; i < arr.Count; i++ ) { 397 | res[i] = System.Convert.ToByte(arr[i]); 398 | } 399 | return res; 400 | } 401 | private System.Collections.Generic.Dictionary GetVals(PolType type) 402 | { 403 | System.Collections.Generic.Dictionary vals = null; 404 | if ( type == PolType.Computer ) 405 | vals = m_vals_c; 406 | else 407 | vals = m_vals_u; 408 | return vals; 409 | } 410 | private string GetPath(PolType type) { 411 | string path = null; 412 | if ( type == PolType.Computer ) 413 | path = m_path_c; 414 | else 415 | path = m_path_u; 416 | return path; 417 | } 418 | 419 | private System.Collections.Generic.Dictionary m_vals_c; 420 | private string m_path_c; 421 | private System.Collections.Generic.Dictionary m_vals_u; 422 | private string m_path_u; 423 | } 424 | } 425 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace SetPol 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | //arg0: path to .pol file 15 | //arg1: registry key path in the form of "Software\Microsoft\Windows\CurrentVersion\Policies 16 | //arg2: registry value type (currently supporting REG_SZ and REG_DWORD) 17 | //arg3: registry value (name of registry value) 18 | //arg4: registry data (data for value) 19 | 20 | var polFilePath = args[0]; 21 | var keyPath = args[1]; 22 | var keyType = args[2]; 23 | var value = args[3]; 24 | var data = args[4]; 25 | 26 | PolFileManager polFile = new PolFileManager(); 27 | if (File.Exists(polFilePath)) 28 | { 29 | polFile.OpenPolFile(polFilePath, PolType.Computer); 30 | PolValue val = new PolValue(); 31 | val.m_Key = keyPath; 32 | Enum.TryParse(keyType, out val.m_KeyType); 33 | val.m_Value = value; 34 | if (val.m_KeyType == KeyType.REG_DWORD) 35 | { 36 | ulong v = Convert.ToUInt64(data); 37 | val.SetDataAsDWORD(v); 38 | } 39 | if (val.m_KeyType == KeyType.REG_SZ) 40 | { 41 | val.SetDataAsString(data.ToString()); 42 | } 43 | if (val.m_KeyType == KeyType.REG_NONE) 44 | { 45 | val.SetDataAsString(data.ToString()); 46 | } 47 | 48 | polFile.Set(val, PolType.Computer); 49 | polFile.SavePolFile(PolType.Computer); 50 | 51 | } 52 | 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SetPol")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SetPol")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5b6278b8-f13c-4dbb-a424-751485d96d74")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SetPol.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SetPol.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Invalid Policy File Format. 65 | /// 66 | internal static string IDS_INVALID_POL_FORMAT { 67 | get { 68 | return ResourceManager.GetString("IDS_INVALID_POL_FORMAT", resourceCulture); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Invalid Policy File Format 122 | 123 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # setpol 2 | Lets you write arbitrary registry entries to Group Policy related .pol files (e.g. registry.pol). 3 | 4 | NOTE: MAKE SURE YOU BACKUP YOUR POL FILES BEFORE USING THIS, JUST IN CASE!!!! 5 | 6 | Command-line utility setpol.exe takes a set of arguments for passing registry entries into a pol file, including: 7 | 8 | arg1: policy file path 9 | 10 | arg2: registry key path 11 | 12 | arg3: registry value type (e.g. REG_SZ, REG_DWORD) 13 | 14 | arg4: registry value name 15 | 16 | arg5: registry data 17 | 18 | For example: 19 | 20 | setpol.exe "\\cpandl.com\sysvol\cpandl.com\policies\{0EB0D8E0-2599-48AC-A7C4-18099BABFC95}\Machine\registry.pol" "Software\Policies\Windows\System" "REG_DWORD" "AllowX-ForestPolicy-and-RUP" 1 21 | 22 | 23 | Note that polfilemanager.cs has methods to do more than just write settings into .pol files. At this point, setpol is just an example consumer that lets you do just that, but will probably add calls to get and remove settings as well (or feel free to!) 24 | -------------------------------------------------------------------------------- /SetPol.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5B6278B8-F13C-4DBB-A424-751485D96D74} 8 | Exe 9 | Properties 10 | SetPol 11 | SetPol 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | True 52 | Resources.resx 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | ResXFileCodeGenerator 61 | Resources.Designer.cs 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 76 | -------------------------------------------------------------------------------- /SetPol.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SetPol", "SetPol.csproj", "{5B6278B8-F13C-4DBB-A424-751485D96D74}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5B6278B8-F13C-4DBB-A424-751485D96D74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {5B6278B8-F13C-4DBB-A424-751485D96D74}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {5B6278B8-F13C-4DBB-A424-751485D96D74}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {5B6278B8-F13C-4DBB-A424-751485D96D74}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | --------------------------------------------------------------------------------