1

I am working on a powershell script to edit a text file generated from registry.pol. The end goal is achieving CIS L1 benchmark. In order for CIS L1 to work in AWS EC2-image-builder as described in this link the following sections need removed:

Computer
Software\Policies\Microsoft\Windows NT\Terminal Services
fPromptForPassword
DWORD:1

Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalPolicyMerge
DWORD:0

Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalIPsecPolicyMerge
DWORD:0

Here is my code so far to pipe everything but these 3 sections to output file:

Get-Content -Path C:\MS-L1.txt -Raw | where -notmatch {
  if( $_.StartsWith("Computer") ) {
    $section = select-string -pattern Computer -context 0,3
    if( ($section -like "fPromptForPassword") and ($section -like "AllowLocalPolicyMerge") and ($section -like "AllowLocalIPsecPolicyMerge") ){
    }
  } | Out-File c:\MS-L1.txt

I am trying to figure out how to select certain sections whose first line is "Computer" but not all the sections whose first line is "Computer", only if the lines following "computer" also match what needs removed:

  1. check for "computer" in a line

  2. store current line and next 3 lines as a section

  3. check the section for the unique registry setting (i.e. fPromptForPassword)

  4. repeat for section 2 (starting at "computer")

  5. repeat for section 3 " "

  6. Pipe the remaining(unselected) output to MS-L1.txt

I believe using -context to examine the 3 lines following "computer" is feasible but am not confident in the formatting of my nested if statement, thank you for any guidance !

1 Answers1

0

Since you're using Get-Content -Raw to read the input file in full anyway, it is more efficient to use a single -replace operation:

(Get-Content -Raw C:\MS-L1.txt) -replace '(?m)^Computer\r?\n.+\r?\n(?:fPromptForPassword|AllowLocalPolicyMerge|AllowLocalIPsecPolicyMerge)\r?\n.+(?:\r?\n)?'

Note: If you know you're always dealing with CRLF newlines (Windows-style), you can use \r\n instead of \r?\n; if you're always dealing with LF newlines (Unix-style), \n will do.

For an explanation of the regex used above, including the ability to experiment with it, see this regex101.com page.


As for what you tried:

Syntax problem:

Your Where-Object (where) command mixes simplified syntax with passing a script block, which isn't supported; in the abstract you have two choices:

  • Simplified syntax: ... | where someProperty -notmatch $someRegex

    • Note that implicitly operating on the input object as a whole instead of on one of its properties is - unfortunately - not supported as of PowerShell 7.2, but GitHub issue #8357 proposes to fix that in the future. With this enhancement, you could then do something like 1..5 | Where -gt 2, which currently fails.
  • Script-block syntax: ... | where { $_.someProperty -notmatch $someRegex }

Conceptual problems:

  • Your command is designed to be line-oriented (though you'd have to remove the -Raw switch to actually send the input file's lines one by one through the pipeline), so you'd have keep track across multiple lines in your Where-Object script block in order to exclude blocks of lines from your input.

  • While direct use of Select-String with its -NotMatch switch offers excluding matching lines in principle, you cannot meaningfully combine this with the -Context parameter, because the additional lines captured as context are not subject to this exclusion.

mklement0
  • 382,024
  • 64
  • 607
  • 775