Parsing a text file for multiple lines of text

I have a script that dumps the DHCP configuration of a DHCP server to a text file. I need to parse that file for all Scope information. The following is the information of interest:

Scope [x.x.x.x] <domain> x.x.x.x/24
	Address Pool:
		Start IP Address	: x.x.x.x
		End IP Address	: x.x.x.x
		Subnet Mask		: x.x.x.x
		Lease duration		: 0 days, 8 hours, 0 minutes
	Exclusions:
		<None>
	Reservations:
		<None>
	Scope Options:
		Option Name	: 00003 Router
		Vendor		: Standard
		Value		: x.x.x.x
		Policy Name	: <None>

		Option Name	: 00006 DNS Servers
		Vendor		: Standard
		Value		: x.x.x.x x.x.x.x x.x.x.x
		Policy Name	: <None>

		Option Name	: 00015 DNS Domain Name
		Vendor		: Standard
		Value		: <domain>
		Policy Name	: <None>

	Policies:
		<None>
	DNS:
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS A & PTR records only if requested by the DHCP clients
		Discard A & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Failover:
		<None>
	Statistics:
		Description	Details
		Total Addresses	55
		In Use		2 (4)%
		Available	53 (96)%
1 Like

This is untested, but should work for the “Scope Options” Option Name : sections:

( concatenations ";" of ( (preceding text of first ":" of it as trimmed string & " : " & following text of first ":" of it as trimmed string) of (it as string) ) of (it; next line of it; next line of next line of it; next line of next line of next line of it) of it) of lines containing "	Option Name	: " of files "whatever.txt"

Let me know if that works or not. Thanks for providing example text.

  • Is there a particular part you are trying to parse?
  • Can you provide example output in the format you’d like to see it in?
  • Can you provide the script that dumps the DHCP config for others to use with these analysis properties?
  • Do you have a bigfix action to automate this?

Side Note: This shows how to post code / text snippets to the forum and preserve the formatting: How to post code to the forums without it messing up the appearance

It didn’t work. I’m posting the entire output of the script just in case that is the issue.

DHCP Server Information
	Server name	: xxxxxxx
	Database path	: C:\Windows\system32\dhcp
	Backup path	: C:\Windows\system32\dhcp\backup

	DHCP server is authorized

Connections and server bindings
	Enabled x.x.x.x Ethernet

	There were no IPv6 server bindings

IPv4
Properties
	General
		DHCP audit logging is enabled
	DNS
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS A & PTR records only if requested by the DHCP clients
		Discard A & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Network Access Protection
		Network Access Protection is Disabled on all scopes
		DHCP server behavior when NPS is unreachable: Full Access
	Filters
		Enable Allow list	: Disabled
		Enable Deny list	: Disabled
	Failover
		There was no Failover configured for DHCP server xxxxxx
	Advanced
		Conflict detection attempts	: 0
		Audit log file path		: C:\Windows\system32\dhcp
		DNS dynamic update registration credentials: 
			User name	: 
			Domain		: 
	Statistics
		Description			Details
		Start Time:			01/18/2017 05:36:23
		Up Time:			9 days, 4 hours, 21 minutes, 40 seconds
		Discovers:			29456
		Offers:				8
		Delayed Offers:			0
		Requests:			770
		Acks:				118984
		Nacks:				0
		Declines:			0
		Releases:			1
		Total Scopes:			2
		Scopes w/delay configured:	0
		Total Addresses:		565
		In Use:				262 (46)%
		Available:			303 (54)%
Scope [x.x.x.x] xxxxx x.x.x.x/24
	Address Pool:
		Start IP Address	: x.x.x.x
		End IP Address		: x.x.x.x
		Subnet Mask		: x.x.x.x
		Lease duration		: 0 days, 8 hours, 0 minutes
	Exclusions:
		<None>
	Reservations:
		<None>
	Scope Options:
		Option Name	: 00003 Router
		Vendor		: Standard
		Value		: x.x.x.x
		Policy Name	: <None>

		Option Name	: 00006 DNS Servers
		Vendor		: Standard
		Value		: x.x.x.x x.x.x.x x.x.x.x
		Policy Name	: <None>

		Option Name	: 00015 DNS Domain Name
		Vendor		: Standard
		Value		: xxxxxx.xxx
		Policy Name	: <None>

	Policies:
		<None>
	DNS:
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS A & PTR records only if requested by the DHCP clients
		Discard A & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Failover:
		<None>
	Statistics:
		Description	Details
		Total Addresses	55
		In Use		2 (4)%
		Available	53 (96)%

Scope [x.x.x.x] xxxxxx x.x.x.x/22 
	Address Pool:
		Start IP Address	: x.x.x.x
		End IP Address		: x.x.x.x
		Subnet Mask		: x.x.x.x
		Lease duration		: 8 days, 0 hours, 0 minutes
	Exclusions:
		<None>
	Reservations:
		<None>
	Scope Options:
		Option Name	: 00003 Router
		Vendor		: Standard
		Value		: x.x.x.x
		Policy Name	: <None>

		Option Name	: 00006 DNS Servers
		Vendor		: Standard
		Value		: x.x.x.x x.x.x.x x.x.x.x
		Policy Name	: <None>

		Option Name	: 00015 DNS Domain Name
		Vendor		: Standard
		Value		: xxxxxx.xxx
		Policy Name	: <None>

	Policies:
		<None>
	DNS:
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS A & PTR records only if requested by the DHCP clients
		Discard A & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Failover:
		<None>
	Statistics:
		Description	Details
		Total Addresses	510
		In Use		260 (51)%
		Available	250 (49)%

		There were no IPv4 Multicast scopes
	Server Options
		There were no IPv4 server options
	Policies
		There were no IPv4 policies
	Filters
		There were no IPv4 allow filters
		There were no IPv4 deny filters
IPv6
Properties
	General
		DHCP audit logging is enabled
	DNS
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS AAAA & PTR records only if requested by the DHCP clients
		Discard AAAA & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Advanced
		Audit log file path C:\Windows\system32\dhcp
		DNS dynamic update registration credentials: 
			User name	: 
			Domain		: 
	Statistics
		Description		Details
		Start Time: 		01/18/2017 05:36:23
		Up Time: 		9 days, 4 hours, 21 minutes, 43 seconds
		Solicits: 		0
		Advertises: 		0
		Requests: 		0
		Replies: 		0
		Renews: 		0
		Rebinds: 		0
		Confirms: 		0
		Declines: 		0
		Releases: 		0
		Total Scopes: 		0
		Total Addresses: 	0
		In Use: 		0 (0%)
		Available: 		0 (0%)
	There were no IPv6 scopes
Server Options
		There were no IPv6 server options

C:\DHCP%computername%.txt

I think you need to post what you want the output of the parsing to look like. Do you just want all of the lines of the file within each “Scope” definition? Are you looking for a result that looks like

Scope [x.x.x.x] xxxxx x.x.x.x/24
	Address Pool:
		Start IP Address	: x.x.x.x
		End IP Address		: x.x.x.x
		Subnet Mask		: x.x.x.x
		Lease duration		: 0 days, 8 hours, 0 minutes
	Exclusions:
		<None>
	Reservations:
		<None>
	Scope Options:
		Option Name	: 00003 Router
		Vendor		: Standard
		Value		: x.x.x.x
		Policy Name	: <None>

		Option Name	: 00006 DNS Servers
		Vendor		: Standard
		Value		: x.x.x.x x.x.x.x x.x.x.x
		Policy Name	: <None>

		Option Name	: 00015 DNS Domain Name
		Vendor		: Standard
		Value		: xxxxxx.xxx
		Policy Name	: <None>

	Policies:
		<None>
	DNS:
		Enable DNS dynamic updates			: Enabled
		Dynamically update DNS A & PTR records only if requested by the DHCP clients
		Discard A & PTR records when lease deleted	: Enabled
		Name Protection					: Disabled
	Failover:
		<None>
	Statistics:
		Description	Details
		Total Addresses	55
		In Use		2 (4)%
		Available	53 (96)%

Or do you want particular lines? Do you want a result for the Options? Or what?

The intent is to create an analysis that collects all of the Scope information so that any or all of that data can be presented via Web Reports. The most important lines are “Scope [x.x.x.x] xxxxx x.x.x.x/24” and “Option Name”.

How about this?

unique values of (it as trimmed string) of following texts of firsts ":" of lines containing "Option Name" of files whose(name of it ends with ".txt") of folders "C:\DHCP"

Progress. The following is what is produced:
$($ScopeOption.OptionId.ToString(“00000”)) $($ScopeOption.Name)"
$($ServerOption.OptionId.ToString(“000”)) $($ServerOption.Name)"
$($ServerOption.OptionId.ToString(“00000”)) $($ServerOption.Name)"

The following would be better:

                Option Name	: 00003 Router
		Vendor		: Standard
		Value		: x.x.x.x
		Policy Name	: <None>

		Option Name	: 00006 DNS Servers
		Vendor		: Standard
		Value		: x.x.x.x x.x.x.x x.x.x.x
		Policy Name	: <None>

		Option Name	: 00015 DNS Domain Name
		Vendor		: Standard
		Value		: xxxxxx.xxx
		Policy Name	: <None>

It can’t produce results that aren’t in the source file. Are you sure the file is where you think it is?

What relevance would be required to read all lines of the file? lines of files "?????"

1 Like

Do you have extra text files in the directory? I don’t see how the source file or jgstew’s query would insert any of the “$($ScopeOption.OptionId.ToString(“00000”)) $($ScopeOption.Name)” results.

If you’re just trying to report the entire content of the file for some kind of export, and you don’t care about formatting the data, this might be as simple as

concatenation "%0d%0a" of lines of file ("c:\DHCP\" & hostname & ".txt")

In our normal use cases, we’d create separate properties for each scope and each option, for instance to be able to filter by “All servers with a scope configuring DNS Servers to 1.2.3.4”, so we might be overthinking this if you just want a data dump.

Just make sure you do not evaluate this property very frequently. Once a week or even less often would be best.

1 Like

There was another text file in the folder and it appears that’s what caused that output. I removed the file but now I’m not getting anything.
The goal is for an engineer in InfoSec to be able to run a report on the configuration of any\all DHCP servers in the environment (think multiple forests and domains) with an emphasis on Scope configuration. With that said, I created a relevance ( lines of files "c:\DHCP\DHCP_Inventory.txt" ) that produces the entire output of the script. I wanted to add an additional analysis to produce just the Scope information. Am I going about this the wrong way?

1 Like

I’m having a little bit of trouble separating out the scopes, probably @jgstew can help.
The way I’m reading this, is that a Scope is the line that begins with “Scope [”, up to the next line that does not start with a Tab.

q: ((lines (((integers in (item 0 of it, item 1 of it))  of ((item 0 of it, minima of items 1 of (it, line numbers of lines whose (it does not start with "%09") of item 1 of it) whose (item 1 of it > item 0 of item 0 of it)) of (line numbers of lines whose (it starts with "Scope [") of it, it))) of it) of it))of file "c:\temp\dhcp.txt"
A: Scope [x.x.x.x] xxxxx x.x.x.x/24
A: 	Address Pool:
A: 		Start IP Address	: x.x.x.x
A: 		End IP Address		: x.x.x.x
A: 		Subnet Mask		: x.x.x.x
A: 		Lease duration		: 0 days, 8 hours, 0 minutes
A: 	Exclusions:
A: 		<None>
A: 	Reservations:
A: 		<None>
A: 	Scope Options:
A: 		Option Name	: 00003 Router
A: 		Vendor		: Standard
A: 		Value		: x.x.x.x
A: 		Policy Name	: <None>
A: 
A: Scope [x.x.x.x] xxxxxx x.x.x.x/22 
A: 	Address Pool:
A: 		Start IP Address	: x.x.x.x
A: 		End IP Address		: x.x.x.x
A: 		Subnet Mask		: x.x.x.x
A: 		Lease duration		: 8 days, 0 hours, 0 minutes
A: 	Exclusions:
A: 		<None>
A: 	Reservations:
A: 		<None>
A: 	Scope Options:
A: 		Option Name	: 00003 Router
A: 		Vendor		: Standard
A: 		Value		: x.x.x.x
A: 		Policy Name	: <None>
A: 
T: 3.317 ms
I: plural file line

I can concatenate those together to get a single result, but haven’t found the right blend of concatenation & parentheses that give exactly two results (one for each Scope).

1 Like

Also, this is just a single development server. Some of the production DHCP servers have many defined scopes.

This is the right way, but it depends a bit on what you want the final output to actually look like.

This should give you just the option names, but I don’t know that is what you want:

unique values of (it as trimmed string) of following texts of firsts ":" of lines containing "Option Name" of files "c:\DHCP\DHCP_Inventory.txt"

Something like this should give you just those 4 lines of each Option Name entry:

( concatenations " ; " of (it as string as trimmed string) of (it;next lines of it;next lines of next lines of it; next lines of next lines of next lines of it) of it ) of lines containing "Option Name" of files "c:\DHCP\DHCP_Inventory.txt"

These 2 would be perfect but I’m still getting “none” in the analysis. Is there a log I can review for errors?
I’ve run both in query analyzer on the target DHCP server. Nothing happens. No errors, just nothing.

…you’re updating our examples with the right filenames as they appear on your server, right?

Yes. I’ll get one of my peers to double check my work today.

Work has been validated.