Batch Script Help: Scan multiple systems and report which ones have a specified Local Group Admin account

phil1429
phil1429 used Ask the Experts™
on
I would like to scan a list of networked systems for a Security Group in the systems' Local Admin's Group. This list will contain aprox. 300 systems and will report if the scan flat out failed to run (if system was powered off, etc.) to one Log file (FaildScan.log) and a successful scan to add a line "Detected ser_1650_admins on %computername%" to a log named something like GOODscan.log

I already have a way to execute this script on the list of 300 systems, but the script fails on the FOR statement and I'm not sure if I've written it correctly or if I can even achieve what I what from an FOR statement...

So basically, here is my current script:
@echo off
REM Write list of local administrators groups to text file to read later
net localgroup administrators >>C:\TEMP\ADMINS.txt
 
if NOT exist C:\TEMP\ADMINS.txt goto QUIT
if exist C:\TEMP\ADMINS.txt goto NEXT
 
:NEXT
REM If any of the lines 
SET FILE=C:\TEMP\ADMINS.txt
FOR /F "usebackq" %%A IN ("%FILE%") DO IF %%A==SER_1641_ADMINS ECHO %COMPUTERNAME% IS DIRTY! >>\\Susoca1000\users\TEMP\Scan1650grouplocal\GOODscan.log
GOTO DONE
 
:QUIT
ECHO ERROR SCANNING %COMPUTERNAME% at %TIME%, %DATE% >>\\Susoca1000\users\TEMP\Scan1650grouplocal\FAILScan.log
 
:DONE
EXIT

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Not sure where you're getting %computername% from.

Without being near a compatible machine to test this on this is probably close to what you're looking for
computername must be a !...!-type variable (for delayed expansion) and must also include ENABLEDELAYEDEXPANSION at the start of code. Variables that do not change inside the FOR loop can be expanded at parse time ie, use %..%-type variables.


@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET adminfile=c:\temp\admins.txt
SET logpath=\\susoca1000\users\temp\scan1650grouplocal

NET LOCALGROUP ADMINISTRATOR >>%adminfile%
 
IF EXIST %adminfile% (
   FOR /F %%a IN ("%adminfile%") DO (
      IF "%%a"=="ser_1641_admins" (
         ECHO !computername! is dirty! >>%logpath%\goodscan.log
      )
   )
) ELSE (
   ECHO ERROR Scanning %computername% at %TIME%, %DATE% >>%logpath%\failScan.log
)
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
t0t0,
%computername% is a static variable of the local environment, set by the system. Using Delayed Expansion doesn't make it useful.


phil1429,
I think you mess up several things, that script does not make sense. You have to apply the script locally on each computer, so if the script runs, the box is running anyway. net localgroup will succeed in any case.
You didn't show how you attempt to apply the list of network computers in this script. I assume you want to do something like this (using psexec from www.sysinternals.com to execute commands remotely):


@echo off
for /F %%C in (list-of-pcs.txt) do (
  set answer=
  ping -n 1 -w 100 %%C | find "Reply from" >nul && set answer=y
  if not defined answer (
    echo ERROR SCANNING %%C at %date%, %time% >>\\Susoca1000\users\TEMP\Scan1650grouplocal\FAILScan.log
  ) else (
    psexec \\%%C net localgroup | find "ser_1641_admins" > nul && (
      ECHO %%C IS DIRTY! >>\\Susoca1000\users\TEMP\Scan1650grouplocal\GOODscan.log
    )
  )
)

Open in new window

Author

Commented:
Close...
I was using psexec but now I am using an Enterprise software called Altiris to perform the deployment of this script to each workstation. So each workstation will essentially be running this script locally. I just have to give Altiris the liist of computers to run this for (so I won't need to script execution on remote PC's).
I just need a script that will run locally... Hope that makes sense. I tried a few variations of both tOtO and Olemo's responses, but no luck so far!
Announcing the Winners!

The results are in for the 15th Annual Expert Awards! Congratulations to the winners, and thank you to everyone who participated in the nominations. We are so grateful for the valuable contributions experts make on a daily basis. Click to read more about this year’s recipients!

"Batchelor", Developer and EE Topic Advisor
Top Expert 2015
Commented:
All right, local execution then, but that way you do not get the "no response" case.

@echo off
set answer=
(net localgroup | find /i "ser_1641_admins" > nul && (
    ECHO %ComputerName% IS DIRTY! [%date% %time%]
  ) || (
    ECHO %ComputerName% is clean [%date% %time%}
  )  
) >> \\Susoca1000\users\TEMP\Scan1650grouplocal\GOODscan.log

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
(the brace in line 6 should be a square bracket, of course).

Author

Commented:
Thanks Olemo! I like that this code is short and to the point. I was unaware of the double Pipe function, could you give a brief explicnation of it?  I also really dig the "no response" case and will probably elect to use it down the road... Could you also give me a brief description on how it works? Thanks Again! Have a great day!
ping -n 1 -w 100 %%C | find "Reply from" >nul && set answer=y
  if not defined answer (
    echo ERROR SCANNING
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
&& is "logical AND". Special meaning: If errorlevel / result code  of the previous command is  0, execute the following command.
|| has the opposite meaining. If any error or result code, execute the next command.

&& and || are executed from left to right. If you have a command chain like this
a && b && c || d
a is executed in any case,
b is executed if a returns 0 (a = 0),
c is executed if b returns 0, and only if b has been executed ( a = 0 AND b = 0)
d is executed if
   a != 0,
   OR a = 0 AND b != 0
   OR a = 0 AND b = 0 AND c != 0

Or "simplyfied":
If the left part of || is != 0, the right part is executed.
If the left part of && is = 0, the right part is executed.

As you can see, you can build rather complex chains with simply looking code.


find (and findstr) result in 0 if they find something:
echo y | find "x" || echo x not found
echo x | find "x" && echo x found

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial