1

I have a batch file which retrieves values of an Active Directory User and provides information such as

Name : John
Country : US

Name : Jacob
Country : UK

The output is then captured to a txt file. How can I restrict the batch file to output only the result if the country is UK.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Arshanaa
  • 35
  • 2
  • 5

3 Answers3

2

Active directory queries support filtering. Your process will be much more efficient if you indicate your intent by including the country filter into the query and avoid the somewhat complex workarounds suggested in the other answers.

If you provide an indication of the API used to query AD, then this could be answered more concretely.

The Search Filter Syntax describes how to identify countries in queries.

Some Powershell examples for reference

Community
  • 1
  • 1
Pekka
  • 3,529
  • 27
  • 45
1

Solution 1 using FINDSTR (native batch commands only)

There is an obscure/undocumented technique using FINDSTR to search across line breaks described at What are the undocumented features and limitations of the Windows FINDSTR command? under the heading "Searching across line breaks". It involves defining a variable to contain a linefeed character, and then including that in the search term.

Assuming you want to post-process the text file (I'll call it test.txt), then you could do something like:

@echo off
setlocal enableDelayedExpansion

:: Define LF to contain a linefeed (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Output any line that precedes "Country : UK"
findstr /c:"!LF!Country : UK" test.txt >UK.txt

You could pipe the results of your Active Directory query command to FINDSTR and directly write out the UK results, without an intermediate file. First I'll assume your script does not require delayed expansion. But the FINDSTR does need delayed expansion.

Each side of the pipe is executed in a new cmd.exe session (thread?) with delayed expansion off. FINDSTR must be executed via cmd with the /V:ON argument to turn on delayed expansion:

@echo off
setlocal disableDelayedExpansion

:: Define LF to contain a linefeed (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Query Active Directory and only preserve lines that precede "Country : UK"
yourActiveDirectoryCommand|cmd /v:on /c findstr /c:"!LF!Country : UK"

If your script requires delayed expansion, then you still must execute FINIDSTR via cmd and use the /V:ON option, but now you must also escape the delayed expansion so it doesn't expand too early

@echo off
setlocal enableDelayedExpansion

:: Define LF to contain a linefeed (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Output any line that precedes "Country : UK"
yourActiveDirectoryCommand|cmd /v:on /c findstr /c:"^!LF^!Country : UK"

Solution 2 using JREPL.BAT (hybrid JScript/batch utility)

JREPL.BAT is a hybrid JScript/batch utility that can easily perform regular expression search and replace across line breaks. It is pure script that runs natively on any Windows machine from XP onward.

You can post-process the file (again, I'm using test.txt)

call jrepl "^([^\r\n]*)\r?\nCountry : UK$" "$1" /jmatch /m /f test.txt /o UK.txt

Or you can pipe your Active Directory query result directly to JREN and avoid the need for an intermediate file:

yourActiveDirectoryCommand|jrepl "^([^\r\n]*)\r?\nCountry : UK$" "$1" /jmatch /m /o UK.txt
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Apologies I should have been more clear. Each response to the query contains more than just name i.e contains email address, phone number etc. How can I get them. The /v:on seems to work but only if I could get the rest of fields that match the country UK it would be excellent. – Arshanaa Jan 31 '15 at 05:23
1

Here is a batch code which requires your input block being written before into file ActiveDirectoryList.tmp located in the directory for temporary files.

@echo off
setlocal EnableDelayedExpansion
set "DataFile=%TEMP%\ActiveDirectoryList.tmp"
set "OutputFile=ActiveDirectoryListUK.txt"

rem Delete the output file if it exists already.
if exist "%OutputFile%" del "%OutputFile%"

rem Parse the data file line by line and split up each line with colon and
rem space as separator. Loop variable A contains for input data either the
rem string "Name" or the string "Country" and everything after " : " is
rem assigned to loop variable B. If loop variable A is "Name", keep string
rem of loop variable B in an environment variable. If loop variable A and B
rem build the string "Country UK", write value of environment variable Name
rem determined before into the output file.

for /F "useback tokens=1* delims=: " %%A in ("%DataFile%") do (
    if "%%A" == "Name" (
        set "Name=%%B"
    ) else if "%%A %%B" == "Country UK" (
        echo Name: !Name!>>"%OutputFile%"
    )
)

del "%TEMP%\ActiveDirectoryList.tmp"
endlocal

It is of course also possible to directly parse output of the active directory query with for command.

Mofi
  • 46,139
  • 17
  • 80
  • 143