【问题标题】:Delete multiple, specific lines from text file using PowerShell使用 PowerShell 从文本文件中删除多个特定行
【发布时间】:2021-11-01 19:10:52
【问题描述】:

我正在编写一个 powershell 脚本来编辑从 registry.pol 生成的文本文件。最终目标是达到 CIS L1 基准。为了使 CIS L1 能够如 this link 中所述在 AWS EC2-image-builder 中工作,需要删除以下部分:

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

到目前为止,这是我将所有内容但通过管道传输到输出文件的代码:

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

我试图弄清楚如何选择第一行是“计算机”的某些部分,但不是所有第一行是“计算机”的部分,前提是“计算机”后面的行也匹配需要删除的内容:

  1. 在一行中检查“计算机”

  2. 将当前行和接下来的 3 行存储为一个部分

  3. 检查该部分的唯一注册表设置(即 fPromptForPassword)

  4. 重复第 2 部分(从“计算机”开始)

  5. 重复第 3 节“”

  6. 将剩余(未选择的)输出通过管道传输到 MS-L1.txt

我相信使用 -context 检查“计算机”后面的 3 行是可行的,但我对嵌套 if 语句的格式没有信心,谢谢您的指导!

【问题讨论】:

    标签: powershell windows-server-2019


    【解决方案1】:

    由于您使用Get-Content -Raw 来完整读取输入文件,因此使用单个-replace 操作更有效:

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

    注意:如果你知道你总是在处理 CRLF 换行符(Windows 风格),你可以使用\r\n 而不是\r?\n;如果你总是处理 LF 换行符(Unix 风格),\n 就可以了。

    有关上面使用的正则表达式的说明,包括对其进行试验的能力,请参阅this regex101.com page。


    至于你尝试了什么:

    语法问题:

    您的Where-Object (where) 命令将simplified syntax 与传递脚本块 混合在一起,这是不受支持的;在摘要中,您有两个选择:

    • 简化语法:... | where someProperty -notmatch $someRegex

      • 请注意,对输入对象 作为一个整体而不是对其一个 属性 进行隐式操作 - 不幸的是 - 自 PowerShell 7.2 起不支持,但 GitHub issue #8357建议在未来解决这个问题。通过此增强功能,您可以执行 1..5 | Where -gt 2 之类的操作,但目前失败了。
    • 脚本块语法:... | where { $_.someProperty -notmatch $someRegex }

    概念问题:

    • 您的命令设计为面向行(尽管您必须删除-Raw 开关才能真正逐一发送输入文件的行管道),因此您可以跟踪 Where-Object 脚本块中的多行,以便从输入中排除 blocks 行。

    • 虽然直接使用Select-String 及其-NotMatch 开关原则上提供排除匹配行,但您不能将其与-Context 参数有意义地结合起来,因为捕获为上下文的附加行是不受此排除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2011-08-13
      相关资源
      最近更新 更多