Parse file convert elements from string to object

Hello,
I’m trying to parse a file and extract specific data from it. I want to also assign handles or objectify the data so that it can be further manipulated, searched, filtered, exported etc…
An example would be NAME = “SNMPConfig”, PARAM_TYPE = STANDARD, ACTIVE = False, MONITOR = False, CHECK = False.
This is only one piece of the puzzle but what I want to accomplish is to take each string in the file similar to this one and break it apart so that NAME becomes a handle, PARAM_TYPE becomes a handle, ACTIVE becomes a handle, MONITOR becomes a handle, and CHECK becomes a handle. Under each handle would be the items on the other side of the equals sign. Each string in the file that is similar to what I provided will have NAME, PARAM_TYPE, ACTIVE etc… and something different on the other side of the equals sign. So imagine you execute get-service or get-process; I want all the different strings in the files I parse to look like the output you get from a typical powershell cmd-let. Is that possible?

Example Text File: Forgive me if I get the code blocks wrong.

!KM ZEROED ON 07/02/14 09:02 AM
!PATROLV3.5.20i 7DA778CDE6DDDF13E2838E4B0F567C54
!#MSG_DOMAIN	pwk_sec
!++
!
! PATROL Session Knowledge Module
!
!--
!RELEASE          4.7.00
!REVISION         00
!PACKAGE          pwk
!DESCRIPTION      PATROL Knowledge Module for Microsoft Windows Operating System
!PRODUCTCODE      pwk


VERSION 1.153

COMPUTERS = {
  { NAME = "NT",
	SCREEN_POSITION = {12, 24},
	OK_PICTURE = "nt_ok.xpm",
	WRONG_PICTURE = "nt_warn.xpm",
	COMMANDS = {
		{ NAME = "SNMP Reconfigure", AVAILABILITY = AVAILABLE_ALWAYS, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  1087855579 "requires pwk_nt;\
pwk_nt__ReconfigureSnmp();\
pwk_nt__StartSnmp();"}
				}
		},
		{ NAME = "Refresh Parameters", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "OS",
				  COMMAND_TEXT =  892081741 "%REFRESH_PARAMS"}
				}
		},
		{ NAME = "OS Command", AVAILABILITY = AVAILABLE_ALWAYS, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "OS",
				  COMMAND_TEXT =  759992599 "%%{OS Command}"}
				}
		},
		{ NAME = "OS Task", AVAILABILITY = AVAILABLE_ALWAYS, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "OS",
				  COMMAND_TEXT =  759992599 "%%{Command}"}
				},
		 TASK = {  SHOW_TIMER = True, INTERACTIVE = True, ATTN_POPUP = False }
		},
		{ NAME = "PSL Command", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  759992599 "%%{Command}"}
				}
		},
		{ NAME = "PSL Task", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  759992599 "%%{Command}"}
				},
		 TASK = {  SHOW_TIMER = True, INTERACTIVE = True, ATTN_POPUP = False }
		},
		{ NAME = "Configure Recovery Actions", AVAILABILITY = AVAILABLE_ALWAYS, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  984071155 "requires PATROLRecovery;\
ListRecoveryActionsDialog(\"\", TRUE);"}
				}
		}

	},
	INFO_BOX = {
		{ NAME = "OS Name", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  890946737 "print(get(\"/osName\"));"}
				}
		},
		{ NAME = "OS Version", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  937583757 "#%ECHO %{reg_OsVersion}\
print(get(\"/reg_OsVersion\").\" \".get(\"/reg_SvcPk\"));"}
				}
		},
		{ NAME = "Build Number", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  890946938 "#%ECHO %{reg_BuildNumber}\
print(get(\"/reg_BuildNumber\"));"}
				}
		},
		{ NAME = "UpTime", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  997455536 "requires pwk_ntos;\
print( pwk_ntos__SystemUpTime() );"}
				}
		},
		{ NAME = "Last Reboot At", AVAILABILITY = AVAILABLE_ONLINE, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  997455547 "requires pwk_ntos;\
print( pwk_ntos__SystemBootTime() );"}
				}
		},
		{ NAME = "NT KM Version", AVAILABILITY = AVAILABLE_ALWAYS, SECURITY = SECURITY_INHERIT,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  1078269349 "requires pwk_version;\
print( pwk_version__GetVersion() );"}
				}
		}

	},
	PARAMETERS = {
		{	NAME = "SNMPConfig", PARAM_TYPE = STANDARD, ACTIVE = False, MONITOR = False, CHECK = False,
 HELP_FILE = "pwkkm.hlp",
 HELP_CONTEXT_ID = 13711,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  1087855701 "requires pwk_nt;\
pwk_nt__StartSnmp();"}
				},
			START = "ASAP",
			POLL_TIME = "60", EXTERNAL_POLLING = False,
			HISTORY_TIME = "60", HISTORY_SPAN = 0, HISTORY_LEVEL = False,
			FORMAT = "%f", OUTPUT = OUTPUT_NONE,
			AUTO_RESCALE = True, Y_AXIS_MIN = 0, Y_AXIS_MAX = 100,
			RANGES = {
			  { NAME = "BORDER", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  },
			  { NAME = "ALARM1", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  },
			  { NAME = "ALARM2", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  }
			}
		},
		{	NAME = "SNMPStart", PARAM_TYPE = STANDARD, ACTIVE = True, MONITOR = False, CHECK = False,
 HELP_FILE = "pwkkm.hlp",
 HELP_CONTEXT_ID = 13710,
				BASE_COMMAND = { 
				{ COMPUTER_TYPE = "NT", COMMAND_TYPE = "PSL",
				  COMMAND_TEXT =  1087855708 "requires pwk_nt;\
pwk_nt__StartSnmp();"}
				},
			START = "ASAP",
			POLL_TIME = "30", EXTERNAL_POLLING = False,
			TITLE = "SNMPStart",
			HISTORY_TIME = "30", HISTORY_SPAN = 0, HISTORY_LEVEL = False,
			FORMAT = "%f", OUTPUT = OUTPUT_NONE,
			AUTO_RESCALE = True, Y_AXIS_MIN = 0, Y_AXIS_MAX = 100,
			RANGES = {
			  { NAME = "BORDER", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  },
			  { NAME = "ALARM1", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  },
			  { NAME = "ALARM2", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0
			  }
			}
		}

	},
	COMMAND_TYPES = {
		{ NAME = "DISKPERF", TEMPLATE =  1003325895 "diskperf  %{command}", KILL_GRP = False, KILL_SIG = 0 },
		{ NAME = "SNMPSTART", TEMPLATE =  996242303 "%{snmp_prog} %{snmp_config} %{snmp_parm} %{command}", KILL_GRP = False, KILL_SIG = 0 },
		{ NAME = "SNMPHUP", TEMPLATE =  996162113 "%{cmdline}\\bin\\snmphup %{command}", KILL_GRP = False, KILL_SIG = 0 },
		{ NAME = "CHKDSK", TEMPLATE =  992614858 "chkdsk %{command}", KILL_GRP = False, KILL_SIG = 0 },
		{ NAME = "LOGD", TEMPLATE =  992613024 "logd %{command}", KILL_GRP = False, KILL_SIG = 0 }

	}
  }

Powershell Command I’ve been trying:


function Get-Params{
[CmdletBinding()]
param(
    [Parameter()]
    [string[]]$FileName='.\Data Files\NT_CPU.km'
)
Begin{
$Parse = Get-Content -Path $FileName
$Parse = $Parse | Select-String -Pattern RELEASE,DESCRIPTION,PARAM_TYPE,TITLE
$Parse = $Parse -replace "{",""
$Parse = $Parse -replace "			",""
# Replaces with new lines
$Parse = $Parse -replace ",","`r`n"
$Parse = $Parse -replace " ",""
#$Parse = $Parse | Select-String RELEASE,DESCRIPTION,NAME,PARAMETERS,TITLE,UNITS
#$Parse = $Parse -replace "{ NAME = `"BORDER`", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0",""
#$Parse = $Parse -replace "{ NAME = `"ALARM1`", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0",""
#$Parse = $Parse -replace "{ NAME = `"ALARM2`", ACTIVE = False, MINIMUM = 0, MAXIMUM = 0, STATE = OK, ALARM_WHEN = ALARM_INSTANT, ALARM_WHEN_N = 0",""
}

Process{

$Parse
}

End{}

Maybe you can tell me if what I’m trying to do given the format of the file is even possible. There is other data I also want from the file but I thought I would start here.

I think I’m not following what you want ;). Could you maybe post just the small portion of that big file that you’re trying to work with? And maybe mock up what you want the result to be?

Hello Don,
Thank you for the reply, it just so happens that I made a small discovery last night and was able to make some progress towards my goal. I happened upon a cmdlet that I think is new to powershell 5 called ConvertFrom-String. This had the affect of breaking up the file I want to parse and assigning the pieces to handles (P1,P2,P3 etc…)

A new revision of my script:

function Get-PatrolParameter{
[CmdletBinding()]
param(
    [Parameter()]
    [string[]]$FileName='.\NT_CPU.km'
)
Begin{
$Parse = Get-Content -Path $FileName
$Parse = $Parse | Select-String PARAM_TYPE
$Parse = $Parse -replace "`"",""
$Parse = $Parse -replace ",",""
$Parse = $Parse | ConvertFrom-String
$Parse = $Parse | Select-Object @{name='Parameter';expression={$_.P5}},@{name='Parameter Type';expression={$_.P8}},@{name='Active';expression={$_.P11}},@{name='Monitor';expression={$_.P14}},@{name='Check';expression={$_.P17}}
}

Process{

$Parse
}

End{}



}

This script starts out by getting the content of the file, then I parse the file for one of the strings I’m interested in which is any line that contains the word “PARAM_TYPE”. For the file that I had posted in code blocks, this parse will pull back two lines. Those two lines contain five items I was interested in splitting up but I wanted to be sure that each of the two lines once all the items were split would be categorized correctly. So in this instance I would be looking to see a result like:
Parameter | Parameter Type | Active | Monitor | Check
SNMPConfig | STANDARD | False | False | False
SNMPStart | STANDARD | False | False | False

After doing the parse, a little clean up with the -replace, and using the ConvertFrom-String I was well on my way. I then did a Select-Object to only pull the objects I wanted and renamed them from the default naming scheme.

I still have some work ahead of me and I’m stuck again. I hope thus far I’m doing a better job of explaining and hopefully the new script will help you understand me better as well.

My next couple of hurdles are as follows. Unfortunately I don’t think the first large file I provided had all the elements I’m looking for. You see; I have many of these files, and they all contain basically the same information and are the same format. Most I would say are larger than the one I provided, but I think you may be able to see my problem with it none the less. Let’s say I wanted to parse something else in the file like “TITLE” for instance. This is separate from the other string data so it does two things that I don’t know how to deal with. First it will have a space between it and the rest of my data, and second, it will also have own set of handles.

I would like to parse other strings in the file, not have them be separated by returns and I would like them to simply get appended to the original object line. So if I initially have P1 - P17 from parsing “PARAM_TYPE”, I would like to continue in that series starting at P18 when I parse for something else.

I know that is long winded, I couldn’t think of a short way to explain this. I appreciate the assistance and the video tutorials on Youtube.