用于在多行中查找模式并回显与模式匹配的计算机名称的脚本

时间:2016-12-14 14:29:00

标签: batch-file vbscript

我有一个文本文件,其中包含从PowerShell脚本传输的数据。数据是域笔记本电脑上BitLocker的状态。文本文件包含的示例如下:

var str = "10M225S"
var m = str.split("M")[0];
var s = str.split("M")[1].split("S")[0];

console.log("m >>> " + m);
console.log("s >>> " + s);

我正在寻找的是一个脚本,它将搜索两个特定行彼此相邻的所有实例。因此,例如,在文本文件中,我需要脚本来查找行的位置"转换状态:完全加密"和"保护状态:保护关闭"是。然后,一旦满足该要求,则需要将位于这两行之上的计算机的名称回显或传送到文本文件中。在上面的例子中,它将是Computer2。需要考虑的一件事是,某些系统有多个硬盘驱动器或分区,它们具有不同的BitLocker状态。因此,在上面的示例中,一个系统可能在文本文件中有两个条目,如Computer3。

我想要的最终结果是一个文本文件,其中只包含具有"转换状态:完全加密"的计算机名称。和"保护状态:保护关闭"作为他们的国家。我的脚本技能非常有限,但我能够搞清楚这些事情。这个让我和我合作的其他管理员一样难过。任何帮助或方向将不胜感激。

4 个答案:

答案 0 :(得分:1)

我过去常常不回答那些没有表现出来自OP的努力的问题;但是,这个问题很有意思!

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%a in (input.txt) do (
   set "line=%%a"
   for /F "tokens=1,2 delims=:" %%b in ("!line: =!") do (
      if "%%b" equ "ComputerName" set "ConversionStatus="
      if "%%b" equ "ConversionStatus" set "ProtectionStatus="
      set "%%b=%%c"
   )
   if "!ConversionStatus!+!ProtectionStatus!" equ "FullyEncrypted+ProtectionOff" (
      echo !ComputerName!
   )
)

答案 1 :(得分:0)

如果您希望逐行处理文件并根据多行的内容执行某些操作,则需要记住/保持之前看到的行的状态。要评估可能复杂的布尔表达式(看到这个或那个但不是这个......),Select Case True/False会派上用场。

演示代码:

Option Explicit

Function qq(s) : qq = """" & s & """" : End Function

Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim oTS : Set oTS = oFS.OpenTextFile("..\data\41145072.txt")
Dim sLine, aParts, sKey, sVal, sCom, sCon, sProt
Do Until oTS.AtEndOfStream
   sLine  = oTS.ReadLine()
   aParts = Split(sLine, ":")
   If 1 = UBound(aParts) Then
        sKey   = Left(sLine, 3)
        sVal   = Trim(aParts(1))
'       WScript.Echo qq(sLine), qq(sVal)
        Select Case True
          Case sKey = "Com"
            sCom = sVal
          Case sKey = "Con"
            sCon = sVal
          Case sKey = "Pro" And sCon = "Fully Encrypted" And sVal = "Protection Off"
            WScript.Echo "****", sCom, sCon, sVal
        End Select
   Else
        WScript.Echo oTS.Line, qq(sLine), "Parse Error"
   End If
Loop
oTS.Close

输出:

cscript 41145072.vbs
**** Computer2 Fully Encrypted Protection Off

答案 2 :(得分:0)

包含两个RegExes的PowerShell解决方案。 第一个将文件拆分为以Computer Name

开头的块

第二个使用命名的捕获组来grep计算机名称并检查条件。

$InFile = ".\41145072.txt"

$Delimiter = 'Computer Name:'
$Escaped   = [regex]::Escape($Delimiter)
$Split     = "(?!^)(?=$Escaped)"
$Search = [RegEx]'(?smi)Computer Name:\s+(?<ComputerName>[0-9a-z_-]+).*Fully Encrypted\r\nProtection Status:\s+Protection Off'

(Get-Content $InFile -Raw) -split $Split | ForEach-Object {
    If ($_ -match $Search){
      $matches.ComputerName
    }
}

答案 3 :(得分:0)

@ECHO Off
SETLOCAL
SET "namefound="
SET "convstatfullenc="
SET "protstatoff="

SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q41141572.txt"
FOR /f "usebackqtokens=1,2*delims=: " %%a IN ("%filename1%") DO (
 SET "lineprocessed="
 IF /i "%%a"=="computer" IF /i "%%b"=="name" (
  SET "namefound=%%c"
  SET "convstatfullenc="
  SET "protstatoff="
  SET "lineprocessed=Y"
 )
 IF /i "%%a"=="protection" (
  SET "protstatoff="
  IF /i "%%b"=="status" IF /i "%%c"=="protection off" (
   SET "protstatoff=Y"
   SET "lineprocessed=Y"
  )
 )
 IF /i "%%a"=="conversion" (
  SET "convstatfullenc="
  SET "protstatoff="
  IF /i "%%b"=="status" IF /i "%%c"=="fully encrypted" (
   SET "convstatfullenc=Y"
   SET "lineprocessed=Y"
  )
 )
 IF DEFINED lineprocessed IF DEFINED namefound IF DEFINED convstatfullenc IF DEFINED protstatoff (
  CALL ECHO %%namefound%%
  SET "lineprocessed="
 )
 IF NOT DEFINED lineprocessed (
  SET "convstatfullenc="
  SET "protstatoff="
 )
)

GOTO :EOF

您需要更改sourcedir的设置以适合您的具体情况。

我使用了一个名为q41141572.txt的文件,其中包含我的测试数据。

仅处理第一个单词,如果单词为computername,则会分配一个新的namefound,并标记两个标记convstatfullencprotstatoff被清除并且标记为读取的行。因此,只要遇到新的computer name,就会清除控制标志。

如果遇到conversion,则清除控制标记,并且仅当行标记为已处理时,如果该行包含convstatfullencstatus,则仅设置fully encrypted

如果遇到protection,则只有当该行还包含protstatoff时才会设置status,并且当该行再次被标记为处理时,protection off将被设置。

如果已处理该行并且已设置每个标志,则表示已满足每个条件,因此显示存储的名称。清除lineprocessed可确保在下一步清除两个控制标志。

因此,如果找到不是三个目标行的行,则该行未设置为已处理,因此将清除这两个控制标志。

如果找到conversion行,则会清除protstatoff并设置convstatfullenc

如果找到protection行,则可以设置protstatoff

可以设置两个控件标志的唯一方法是protection行直接位于conversion之后通过全面测试。