Reputation: 313
I am trying to create a Powershell script which, based on an input TXT or CSV, splits it into sections which are delimited by specific regexes and then manipulates the data inside it based on other regexes.
To be more specific, I'm trying to manipulate data from a NAT rulebase, which is formatted like so:
IP version : IPv4
Index : 1
----------General----------
Original Source : Any
Translated Source : ORIGINAL
Original Destination : 192.168.1.1
Translated Destination: ORIGINAL
Original Service : IKE
Translated Service : ORIGINAL
Inbound Interface : Any
Outbound Interface : Any
Comment : IKE NAT
Enable NAT Policy : True
System Policy : True
----------Advanced----------
[...] (irrelevant data)
What I'm trying to achieve, is get all that data and manipulate it in order to create a command which will add that rule automatically via API on another firewall for all the NAT rules which are present within the TXT file, so for this example:
add nat-rule position 1 enabled true original-source "Any" translated-source "Original" original-destination "192.168.1.1" translated-destination: "Original" original-service "IKE" translated-service: "Original" comment "IKE NAT"
The position of this rule should be based on the "Index" variable.
I'm basically stuck in saying the program: "The sections start with 'IP version' and end with 'System Policy : ...' "
For each of these sections, I believe I can assign a regex to a variable and if it matches, it assigns the value to a new variable.
How can I achieve this, by using Powershell?
So far, I've managed to produce the following script:
$filepath = 'C:\test.txt'
$getfile = Get-Content $filepath -Raw
$splitfile = $getfile - split
foreach($object in $splitfile){
Write-Host $object
}
Thanks in advance.
Upvotes: 0
Views: 179
Reputation: 313
I've managed to produce the following script. Maybe it's a bit inelegant or crude, but it does the job.
Thanks all for your help and hints.
$filepath = 'C:\test.txt'
$getfile = Get-Content $filepath -Raw
$splitfile = $getfile -split 'IP Version : '
#Assignment of variables for regex part
$regex_index = 'Index : '
$regex_original_source = 'Original Source : '
$regex_translated_source = 'Translated Source : '
$regex_original_destination = 'Original Destination : '
$regex_translated_destination = 'Translated Destination : '
$regex_original_service = 'Original_Service : '
$regex_translated_service = 'Translated_Service : '
$regex_comment = 'Comment : '
#Loop for each line of the text
foreach($object in $splitfile){
#Split the file for each line and analyze for each regex, if present, the output might be performed via CLI
$lines = $object.Split([Environment]::NewLine)
$data_index=@($lines) -match $regex_index
$value_index = $data_index -replace $regex_index, ''
#Write-Host $value_index
$data_original_source=@($lines) -match $regex_original_source
$value_original_source = $data_original_source -replace $regex_original_source, ''
#Write-Host $value_original_source
$data_translated_source=@($lines) -match $regex_translated_source
$value_translated_source = $data_translated_source -replace $regex_translated_source, ''
#Write-Host $value_translated_source
$data_original_destination=@($lines) -match $regex_original_destination
$value_original_destination = $data_original_destination -replace $regex_original_destination, ''
#Write-Host $value_original_destination
$data_translated_destination=@($lines) -match $regex_translated_destination
$value_translated_destination = $data_translated_destination -replace $regex_translated_destination, ''
#Write-Host $value_translated_destination
$data_original_service=@($lines) -match $regex_original_service
$value_original_service = $data_original_service -replace $regex_original_service, ''
#Write-Host $value_original_service
$data_translated_service=@($lines) -match $regex_translated_service
$value_translated_service = $data_translated_service -replace $regex_translated_service, ''
#Write-Host $value_translated_service
$data_comment=@($lines) -match $regex_comment
$value_comment = $data_comment -replace $regex_comment, ''
#Write-Host $value_comment
#Create string for variable assignment and print
$string = "add nat-rule position $value_index enabled true original-source `"$value_original_source`" translated-source `"$value_translated_source`" original-destination `"$value_original_destination`" translated-destination `"$value_translated_destination`" original-service `"$value_original_service`" translated-service `"$value_translated_service`" comments `"$value_comment`"
Write-Host $string
Upvotes: 0
Reputation: 61068
To parse a file like that, you indeed need to do some splitting and replacing.
When that is done, I think it would be easiest to use the ConvertFrom-StringData cmdlet to get all the values in a Hashtable and fill a template string using the values in that hash to build your command string.
Something like this:
$filepath = 'C:\test.txt'
$content = Get-Content -Path $filepath -Raw
# build a template string for the NAT rules
$natRule = 'position {0} enabled {1} original-source "{2}" translated-source "{3}" ' +
'original-destination "{4}" translated-destination: "{5}" '+
'original-service "{6}" translated-service: "{7}" comment "{8}"'
# do some text splitting and replacing to create a Hashtable of values in each text block
$content -split 'IP version' | Where-Object { $_ -match '\S' } | ForEach-Object {
# for each text block, take off the stuff starting at "----------Advanced----------",
# remove the line "----------General----------",
# replace the colons (:) with equal signs (=),
# and convert this data into a Hashtable
# the final replacement doubles any backslash because
# ConvertFrom-StringData regards them as regex escape characters
$ht = 'IP version' + ($_ -split '\r?\n-+Advanced-+')[0] -replace
'\r?\n-+General-+' -replace ':', '=' -replace
'\\', '\\' | ConvertFrom-StringData
# next build your nat rule command from the template using the values in the Hashtable
$command = $natRule -f $ht.Index,
($ht.'Enable NAT Policy').ToLower(), # not sure if "True" needs to be lowercase here..
$ht.'Original Source',
$ht.'Translated Source',
$ht.'Original Destination',
$ht.'Translated Destination',
$ht.'Original Service',
$ht.'Translated Service',
$ht.Comment
# show the command we've built
Write-Host "add nat-rule $command"
# execute the command via API
# Uncomment if you know what you're doing ;)
# add nat-rule $command
}
The resulting commands on screen wil look like:
add nat-rule position 1 enabled true original-source "Any" translated-source "ORIGINAL" original-destination "192.168.1.1" translated-destination: "ORIGINAL" original-service "IKE" translated-service: "ORIGINAL" comment "IKE NAT"
add nat-rule position 2 enabled true original-source "Source" translated-source "COPY" original-destination "192.168.1.2" translated-destination: "ORIGINAL" original-service "IKE&TINA" translated-service: "ORIGINAL" comment "IKE NOT"
P.S. The code -replace '\\', '\\'
seems rediculous perhaps, but since -replace
uses Regex, we need to escape the backslash in the first part with yet another backslash. What is does is doubling all backslashes
Upvotes: 1