2 people like it.

Csv + Registry

Had a C tool to parse a csv of queries and check registry against query, then spit out the result, was horrible to parse and model the data in C (just too much code) so I have converted it to F#.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
#nowarn "62"

open System
open Microsoft.Win32

let workingDir = "E:\\win_reg\\"

type regQuery = {
  name           : string
  defaultVal     : string
  recommendedVal : string
  registryDir    : string
  registryKey    : string
}

// we keep output as obj because we printf it with `%A' 
// this means we dont have to do key specific conversions!
type csvOutput = {
  input  : regQuery
  output : obj }

let csvToRegQuery (xs : string) =
  let s = xs.Split ','
  { name           = s.[1]
    defaultVal     = s.[2]
    recommendedVal = s.[3]
    registryDir    = s.[4]
    registryKey    = s.[5] 
  }

let parseInputCsv = 
  IO.File.ReadAllLines >> Seq.map csvToRegQuery

let getValue (q : regQuery) =
  { input  =  q
    output =  Registry.GetValue(q.registryDir, q.registryKey, "")
  }

let writeCsvOutput (data : csvOutput seq) =
  let hdr = ",name,default,recommended,current,reg,key,\r\n"
  let fmt = sprintf ",%s,%s,%s,%A,%s,%s,\r\n"

  let append data = 
    IO.File.AppendAllText(workingDir ^ "out.csv",data)

  append hdr
  data |> Seq.map (fun x -> 
    fmt x.input.name 
        x.input.defaultVal 
        x.input.recommendedVal 
        x.output 
        x.input.registryDir 
        x.input.registryKey)
      |> Seq.iter append

workingDir ^ "Windows-All-Reg.csv"
|> parseInputCsv 
|> Seq.map getValue 
|> writeCsvOutput

(* Example of file Windows-All-Reg.csv is:
,name,default,recommended,reg,key,
,Disable anonymous enum of SAM accounts and shares,0,1,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,RestrictAnonymous,
,Disable storage of creds for network auth,0,1,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,DisableDomainCreds,

and the output:
,name,default,recommended,current,reg,key,
,Disable anonymous enum of SAM accounts and shares,0,1,0,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,RestrictAnonymous,
,Disable storage of creds for network auth,0,1,0,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,DisableDomainCreds,
*)
namespace System
namespace Microsoft
namespace Microsoft.Win32
val workingDir : string

Full name: Script.workingDir
type regQuery =
  {name: string;
   defaultVal: string;
   recommendedVal: string;
   registryDir: string;
   registryKey: string;}

Full name: Script.regQuery
regQuery.name: string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
regQuery.defaultVal: string
regQuery.recommendedVal: string
regQuery.registryDir: string
regQuery.registryKey: string
type csvOutput =
  {input: regQuery;
   output: obj;}

Full name: Script.csvOutput
csvOutput.input: regQuery
csvOutput.output: obj
type obj = Object

Full name: Microsoft.FSharp.Core.obj
val csvToRegQuery : xs:string -> regQuery

Full name: Script.csvToRegQuery
val xs : string
val s : string []
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
val parseInputCsv : (string -> seq<regQuery>)

Full name: Script.parseInputCsv
namespace System.IO
type File =
  static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
  static member AppendAllText : path:string * contents:string -> unit + 1 overload
  static member AppendText : path:string -> StreamWriter
  static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
  static member Create : path:string -> FileStream + 3 overloads
  static member CreateText : path:string -> StreamWriter
  static member Decrypt : path:string -> unit
  static member Delete : path:string -> unit
  static member Encrypt : path:string -> unit
  static member Exists : path:string -> bool
  ...

Full name: System.IO.File
IO.File.ReadAllLines(path: string) : string []
IO.File.ReadAllLines(path: string, encoding: Text.Encoding) : string []
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val getValue : q:regQuery -> csvOutput

Full name: Script.getValue
val q : regQuery
type Registry =
  static val CurrentUser : RegistryKey
  static val LocalMachine : RegistryKey
  static val ClassesRoot : RegistryKey
  static val Users : RegistryKey
  static val PerformanceData : RegistryKey
  static val CurrentConfig : RegistryKey
  static val DynData : RegistryKey
  static member GetValue : keyName:string * valueName:string * defaultValue:obj -> obj
  static member SetValue : keyName:string * valueName:string * value:obj -> unit + 1 overload

Full name: Microsoft.Win32.Registry
Registry.GetValue(keyName: string, valueName: string, defaultValue: obj) : obj
val writeCsvOutput : data:seq<csvOutput> -> unit

Full name: Script.writeCsvOutput
val data : seq<csvOutput>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val hdr : string
val fmt : (string -> string -> string -> obj -> string -> string -> string)
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val append : (string -> unit)
val data : string
IO.File.AppendAllText(path: string, contents: string) : unit
IO.File.AppendAllText(path: string, contents: string, encoding: Text.Encoding) : unit
val x : csvOutput
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter

More information

Link:http://fssnip.net/g6
Posted:5 years ago
Author:David Klein
Tags: csv , registry , basic parsing