Найти gpo в gpresult (для /find/findstr)

Мне не нужны некоторые конкретные правила для разных gpo, если я использую: "gpresult /r /scope user", я получаю информацию о том, какие GPO (группы безопасности) активны. Теперь, как я могу отфильтровать некоторые из этих активных объектов групповой политики в мой пакетный файл? Это часть результата моего gpresult:

De gebruiker is lid van de volgende beveiligingsgroepen
      Domain Users
      Iedereen
      SophosAdministrator
      SophosUser
      BUILTIN\Administrators
      Gebruikers
      INTERACTIEF
      AANMELDEN OP DE CONSOLE
      Geverifieerde gebruikers
      Deze organisatie
      LOKAAL
      Iedereen
      GS_08_cv's
      Tekenkamer
      GS_03_verslagen_openbaar
      GS_07_overeenkomsten
      GS_01_facturen
      GS_04_Functieprofielen
      GS_00_documenten
      AEC
      GS_02_functioneringsgesprekken
      GS_06_offertes
      GS_05_Arbeidsovereenkomsten
      GS_09_ aanbevelingsbrieven
      GS_03_verslagen_beperkt
      Systeembeheer
      Hoog verplicht niveau

Я знаю, что могу найти определенное имя (строку?) С помощью findstr, т.е.

gpresult /r /scope user | findstr /L /i "SysteemBeheer" > nul 2>&1
REM *alternative* gpresult /r /scope user | FIND /i "SysteemBeheer" > nul 2>&1
IF %ERRORLEVEL% EQU 0 (ECHO Sys.Beheer) ELSE ECHO NO.sys.beheer

Но как я могу изменить это так, чтобы несколько строк читалось?

то есть (заимствовал код только для примера)

systeminfo | find "Microsoft Windows" > %TEMP%\osname.txt
FOR /F "usebackq delims=: tokens=2" %%i IN (%TEMP%\osname.txt) DO set vers=%%i

echo %vers% | find "Windows 7" > nul
if %ERRORLEVEL% == 0 goto ver_7

echo %vers% | find "Windows Server 2008" > nul
if %ERRORLEVEL% == 0 goto ver_2008

echo %vers% | find "Windows Vista" > nul
if %ERRORLEVEL% == 0 goto ver_vista

goto warnthenexit

Я имею в виду, что это ищет несколько переменных. Я надеюсь, что некоторые найдут несколько групп безопасности (GPO) из функции gpresult (или, может быть, лучше?)

Я бы хотел, чтобы это было сделано примерно так: если систейма существует для Blaat1, если AEC существует для Blaat2, если Tekenkamer существует для Blaat3, НО может быть несколько GPO, так что скрипт / поиск не должен останавливаться, если существует 1 из вышеперечисленных, это все еще должно посмотреть, существует ли один из других также.

*** Может быть, немного больше, как это?

@echo off
CLS
setlocal enabledelayedexpansion

for %%i in (systeembeheer tekenkamer aec) do (
    gpresult /r /scope user | findstr /L /i %%i
    if errorlevel 0 if not errorlevel 1 echo %%i ok process found !errorlevel!
    if errorlevel 1 if not errorlevel 2 echo %%i no process found !errorlevel!
)

:exit
pause

И поменял это буквально:

@ECHO OFF
CLS
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

for %%i in (SysteemBeheer Administratie PersoneelsZaken TeamPlan) do (
    gpresult /r /scope user | findstr /L /i %%i > nul 2>&1
    if errorlevel 0 if not errorlevel 1 Set "GPO_%%i=True"
    if errorlevel 1 if not errorlevel 2 Set "GPO_%%i=False"
REM if errorlevel 0 if not errorlevel 1 echo %%i ok process found !errorlevel! *debug lines*
REM if errorlevel 1 if not errorlevel 2 echo %%i no process found !errorlevel! *debug lines*
)

if "%GPO_systeemBeheer%" == "True" (Echo GPO_SysteemBeheer=%GPO_systeemBeheer%) else Echo GPO_SysteemBeheer Not Found!
if "%GPO_Administratie%" == "True" (Echo GPO_Administratie=%GPO_Administratie%) else Echo GPO_Administratie Not Found!
if "%GPO_PersoneelsZaken%" == "True" (Echo GPO_PersoneelsZaken=%GPO_PersoneelsZaken%) else Echo GPO_PersoneelsZaken Not Found!
if "%GPO_TeamPlan%" == "True" (Echo GPO_TeamPlan=%GPO_TeamPlan%) else Echo GPO_TeamPlan Not Found!

:exit
echo.
echo.
PAUSE

Кажется, это делает то, что я хочу, но я не уверен, что это лучший или правильный способ сделать это???

1 ответ

Я не уверен, как я пропустил этот вопрос раньше - лучше поздно, чем никогда, я надеюсь:-)

Ваша основная стратегия является разумной. Есть несколько вещей, которые вы можете сделать, чтобы улучшить и / или упростить.

Для выполнения команды GPRESULT требуется значительное время. Я бы захватил результаты в файл один раз, а затем искать файл. Это должно улучшить производительность.

При определении "логической" переменной проще отменить определение переменной для FALSE и установить значение в любое значение, представляющее TRUE. (Я склонен использовать значение 1). Тогда вы можете просто использовать IF DEFINED VARIABLE для проверки на TRUE или FALSE. Одним из основных преимуществ является то, что вы можете установить значение и протестировать результат в блоке кода без необходимости отложенного расширения. Одним из ограничений оператора IF DEFINED является то, что он не может легко поддерживать переменные с пробелом в имени (см. Какой синтаксис проверит, определено ли имя переменной, содержащее пробелы?).

Вы явно ищете ERRORLEVEL 0 как успех (найдено) и ERRORLEVEL 1 как сбой (не найдено). Я не знаю ни о каком другом ERRORLEVEL, который мог бы быть возвращен, и вы не беспокоитесь об обработке любого другого значения, так почему бы просто не посмотреть на ERRORLEVEL 0 как успешный и трактовать любое другое значение как неудачный?

Еще лучше, вы можете использовать && Оператор условно запустить блок команд в случае успеха, и || условно запустить блок команд при неудаче.

У групп безопасности могут быть пробелы в имени. Такое имя не будет соответствовать вашему коду. Было бы лучше использовать опцию FINDSTR /C, чтобы указать строку поиска. Строка должна быть заключена в кавычки, если она содержит пробелы. Параметр / C по умолчанию обрабатывает строку как литерал, поэтому параметр /L не требуется.

Вот как я бы написал ваш оригинальный код:

@echo off
setlocal
cls
set "file=%temp%\gpresult%random%.txt"
gpresult /r /scope user >"%file%"
for %%i in (SysteemBeheer Administratie PersoneelsZaken TeamPlan "Group with space") do (
  findstr /i /c:%%i "%file%" >nul 2>&1 && (
    echo Group %%i OK
  ) || (
    echo Group %%i Not Found
  )
)
del "%file%"
pause

Если вы хотите установить и проверить "логические" переменные и знаете, что имена никогда не будут содержать пробелов, я бы использовал следующее:

@echo off
setlocal
cls
set "file=%temp%\gpresult%random%.txt"
gpresult /r /scope user >"%file%"
for %%i in (SysteemBeheer Administratie PersoneelsZaken TeamPlan) do (
  set "GPO_%%i="
  findstr /i /l %%i "%file%" >nul 2>&1 && set "GPO_%%i=1"
)
del "%file%"

if defined GPO_systeemBeheer (Echo GPO_SysteemBeheer Found) else Echo GPO_SysteemBeheer Not Found!
if defined GPO_Administratie (Echo GPO_Administratie Found) else Echo GPO_Administratie Not Found!
if defined GPO_PersoneelsZaken (Echo GPO_PersoneelsZaken Found) else Echo GPO_PersoneelsZaken Not Found!
if defined GPO_TeamPlan (Echo GPO_TeamPlan Found) else Echo GPO_TeamPlan Not Found!
pause

Если имя группы может содержать пробелы, я бы вернул тест IF к чему-то более похожему на ваш второй набор кода. Если вы используете значения TRUE и FALSE вместо undefined и 1, вы можете избавиться от заключенных в кавычки операторов IF.

@echo off
setlocal
cls
set "file=%temp%\gpresult%random%.txt"
gpresult /r /scope user >"%file%"
for %%i in (SysteemBeheer Administratie PersoneelsZaken TeamPlan "Group with spaces") do (
  set "GPO_%%i="
  findstr /i /c:%%i "%file%" >nul 2>&1 && set "GPO_%%i=1"
)
del "%file%"

if "%GPO_systeemBeheer%"=="1" (Echo GPO_SysteemBeheer Found) else Echo GPO_SysteemBeheer Not Found!
if "%GPO_Administratie%"=="1" (Echo GPO_Administratie Found) else Echo GPO_Administratie Not Found!
if "%GPO_PersoneelsZaken%"=="1" (Echo GPO_PersoneelsZaken Found) else Echo GPO_PersoneelsZaken Not Found!
if "%GPO_TeamPlan%"=="1" (Echo GPO_TeamPlan Found) else Echo GPO_TeamPlan Not Found!
if "%GPO_Group with spaces%"=="1" (Echo GPO_Group with spaces Found) else Echo GPO_Group with spaces Not Found!
pause
Другие вопросы по тегам