Security Automation by Hand - Batch/Bash/FOR

Tuesday, May 15, 2012

Damion Waltermeyer


This series of articles will be entry points and ideas on how to manage your environment quickly, easily, and cheaply (Free). To focus on that, this article’s scripts will each be one command-line entry long.

This series will break things apart and expand upon useful tools and techniques, getting more advanced and complex as we go.  

We’ll also tackle some scripting languages: Batch, Bash, VBScript, Python and Powershell being the most likely candidates for simplicity and compatibility with environments.  

N = 1;
Part = N;

Today’s fun: Simple Uses for “For” loops using Batch and Bash

For an example, suppose we have an asset number on the outside of each workstation; sometimes we need to reconcile it to a pcname.  Normally, this is not a big deal, but when getting a request involving lots of machines, it can be a pain to look up if given asset numbers instead of pcnames.

This request could be anything; perhaps it is a list of machines to be patched, or that need a scan run on them. Here is a script to take a tag from a list of tags in a file and compare it do another large file/datastore and pull the lines you need and then trim it for the data you want.

First, take your list of Tags and put them in “assets.txt”. Name your masterlist “AssetList.txt”. Keep in mind you can always change the code to just reflect your own file names.

You say in the following line of code that for each entry in assets.txt, the computer will perform a search for the line with that entry in the datastore and output it to the file “listofpcnames.txt”. If you’ve got Grep & Cut available you can also cut each entry down by a delimiter (I am using | in the example) and select only the bit of text you need.



for /f %i in (assets.txt) do find “ %i” AssetList.txt  >> listofpcnames.txt

MS With MinGW:

for /f %i in (assets.txt) do grep %i AssetList.txt  |cut -d"|" -f 6 >> listofpcnames.txt


For pcname in $(cat assets.txt); do grep $pcname Assetlist.txt |cut  -d”|” –f6 >> listofpcnames.txt

Now, any time you want to find multiple pieces of text in a large file like a .csv or .xls you can use this technique.  


You can also use this technique for processing network logs.  Have a series of IPs you want to find or compare against a list of computer names?  Fill your “assets.txt” with the IP addresses you want to compare.  If it’s messy you could run the following if you have Grep & Cut.

Pretend your data looks like the following; What you want is the 3rd and 9th field.

Date1, time1, mac1, ip1, code, field3, field17, gibberish1, klingon1, cat1, furball
Date2, time2, mac2, ip2, code, field3, field17, gibberish2, klingon2, cat2, furball
Date3, time3, mac3, ip3, code, field3, field17, gibberish3, klingon3, cat3, furball

You run the above script and in the do section you change it to read :

MS With MinGw:

for /f %i in (assets.txt) do grep %i  masterpclist.csv |cut -d"," -f3,9 >> listofpcnames.txt

For Linux:

For ip in $(cat assets.txt); do grep $ip MasterPcList.csv |cut  -d”,” –f3,9|sort -u >> listofpcnames.txt

If you run this, you’ll get:

  • mac1, klingon1
  • mac2, klingon2
  • mac3, klingon3


Perhaps you need to put a file on all pcs in a list; you are placing a patch, distributing something to all users desktops like an icon, or just placing a key/reference file for later.

For us to place a file in “all users\desktops” (XP), we’ll do the following script.

Place all computer names in copy.txt
MS with or Without MinGW

for /f %i in (copy.txt) do Copy c:\scripts\Keyfile.txt ”\\%i\C$ \Documents and Settings\All Users\Desktop”

This can take a while, so if you are stuck using this method because you don’t have some sort of patch management software and you have a large amount of machines, I recommend using 5-10 instances of this script with the list broken up into parts and running them simultaneously.


Without Samba or something else handling the exchange of files, this doesn’t work. 


I’m just going to give one example set here. You can tweak this to suit your needs pretty easily.

You can stop a service on the list of machines, and then restart it. What you do in the middle is up to you. If you have a lot of machines, this can also be broken up into multiple instances just like the copy script above.

for /f %i in (listofpcs.csv) do sc \\%i\ stop "Service name"
for /f %i in (listofpcs.csv) do sc \\%i\ start "Service name"


I’m happy to take suggestions for future articles. You can reach me either here or on Linkedin:

A good reference on modifying the Batch FOR command is:

Network->General Operating Systems
Post Rating I Like this!
The views expressed in this post are the opinions of the Infosec Island member that posted this content. Infosec Island is not responsible for the content or messaging of this post.

Unauthorized reproduction of this article (in part or in whole) is prohibited without the express written permission of Infosec Island and the Infosec Island member that posted this content--this includes using our RSS feed for any purpose other than personal use.