Link to home
Start Free TrialLog in
Avatar of washy16
washy16Flag for Canada

asked on

Need help with a XP Shell script to create local groups based on a file

Hi Experts! I've never done scripting in the Windows Shell before and I need some help.

Based on a .txt file I need to make a script that creates local groups but only creates a group if it doesn't already exist. I can create groups without a hitch, but I'm stuck on how to only make it if it doesn't exist part. The sample txt file I'm working with looks like this:

**************************************************************
New Employees
**************************************************************

LastName       FirstName      employeeID      Department
--------------------------------------------------------------
Doe                       John               A003            News
Smith             Dave                 B005            Distribution

The code I have to create the group so far is this:

FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO NET LOCALGROUP %%a /add



Any help would be appreciated.

Thanks.
Washy
Avatar of t0t0
t0t0
Flag of United Kingdom of Great Britain and Northern Ireland image

Please try:

FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO (
   net localgroup %%a 2>nul
   if not %errorlevel%==0 (
      echo Usergroup %%a does not exist. Adding %%a
      NET LOCALGROUP %%a /add
   ) else (
      echo Usergroup %%a already exists.
   )
)
The following code (modified from above) suppresses system output to the screen...


@echo off
FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO (
   net localgroup %%a 1>nul 2>nul
   if not %errorlevel%==0 (
      echo Usergroup %%a does not exist. Adding %%a
      NET LOCALGROUP %%a /add 1>nul
   ) else (
      echo Usergroup %%a already exists.
   )
)


NOTE: I'm not fully aware of the errorlevel values for NET but you could try replacing the line:

    if not %errorlevel%==0 (

with

    if %errorlevel%==2 (

as this might be specific to the non-existent usergroup.
Avatar of washy16

ASKER

Thanks for your quick response. Unfortunately I'm unable to redirect output to 'nul'. Its an assignment for school and he said its possible to do this without nul using 2 or 3 scripts successfully.

I'm sorry, I should of mentioned that in the original post.

Do you have any other suggestions? I really appreciate it.

Washy
you don't have to redirect output .... you could just as well have output print to the screen - as far as functionality is concerned it will still work okay.

However, if you DO want to to the whole thing without displaying stuff on the screen let us know however, it might be tricky unless there's something Im not familiar with regarding the use of NET.

One thing that springs to mind is using REG to do it directly with the registry file. At least REG provides a QUERY option for pre-testing conditions....
Avatar of washy16

ASKER

Is there someway of using a 'IF' command with group creation? eg.

FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO IF NET "LOCALGROUP"=="" NET LOCALGROUP %%a

I know this doesn't work, I've tried. But you kind of get the idea. Can you elaborate on using REG?

Thanks,

Washy
Nope, you can't do something like...

    if net localgroup something == something then do whatever...

You have to do the test first and assign the result to a variable for example, such as....

    set variable = net localgroup or something similar....
    if variable==condition then do whatever

Which what I did above - only, I didn't have to actually have to set a variable as the system automatically sets the system ERRORLEVEL depending on the result of certain commands. Most commands don't effect the system ERRORLEVEL - that's just the way DOS was designed.

The following test goes along the line: display the details for the usergroup XXX. if no such usergroup exists then DOS sets ERRORLEVEL to >0 (in my tests it set it to 2) otherwise it gets set to 0. Then test for the ERRORLEVEL condition and do whatever depending on the result.

    net localgroup %%a
    if not %errorlevel%==0


Avatar of washy16

ASKER

I'm starting to understand what you were doing. However when I just paste your code and try and run it, it just displays
Usergroup News already exists.
Usergroup Distribution already exists.
Usergroup Distribution already exists.
Usergroup Distribution already exists.
Usergroup News already exists.

But none of them got created. Would that mean that in the error level isn't 0?
Avatar of washy16

ASKER

I should mention that neither News or Distribution actually don't exist even though the script say they do.
Avatar of washy16

ASKER

If I change the errorlevel line to:
if not %errorlevel%==1 (  
I get:  

Usergroup News does not exist. Adding News
Usergroup Distribution does not exist. Adding Distribution
Usergroup Distribution does not exist. Adding Distribution
System error 1379 has occurred.

The specified local group already exists.

Usergroup Distribution does not exist. Adding Distribution
System error 1379 has occurred.

The specified local group already exists.

Usergroup News does not exist. Adding News
System error 1379 has occurred.

The specified local group already exists.
sorry, i was away from my pc

no, you have to test for 'zero' errorlevels.... zero signifies 'okay' whereas 'non-zero' signifies 'not okay'. you can get olots of 'non-zero' conditions which is why we must ONLY test for the one 'zero' condition.

if there's a problem with the command it will return a non-zero result in errorlevel. so,

   if not errorlevel == 0

in other words, if the errorlevel ISN'T zero (meaning all is okay) then do whatever.

   net localgroup %%a 1>nul 2>nul

should return a '0' in errorlevel if the usergroup already exists. try it on the command line. type:

   NET LOCALGROUP news

then immediately afterwards, type:

   ECHO %ERRORLEVEL%

you will either get a '0' or a 'non-0'. you can then check this with:

   NET LOCALGROUP news

if you get an error then you should have got a non-zero from the previous command (could be a 2 maybe?). if on the otherhand you don't get an error ie, it displays properties for 'news', then you'll have got a '0' from the previous command.

Hope i'm making sense here....

The next line:

   if not %errorlevel%==0 (

means, if there was a problem ie, the usergroup does not exist, then do whatever... in this case, we followed it with....

   echo Usergroup %%a does not exist. Adding %%a
   NET LOCALGROUP %%a /add 1>nul

to create the usergroup.

what you could do is remove all the redirections to NUL while you're testing the logic. you could even insert the following ECHO line directly after the NET LOCALGROUP line, as in:

   net localgroup %%a 1>nul 2>nul
   ECHO [%ERRORLEVEL]

and continue onto the IF statement. that way, you'll be able to predict what part of the IF statement it should do from the result displayed by the ECHO command.

Avatar of washy16

ASKER

I completely understand how the errorlevel works now, thanks a lot!

Only problem is when I type what you entered,

@echo off
FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO (
   net localgroup %%a 1>nul 2>nul
   if not %errorlevel%==0 (
      echo Usergroup %%a does not exist. Adding %%a
      NET LOCALGROUP %%a /add 1>nul
   ) else (
      echo Usergroup %%a already exists.
   )
)

the command prompt ins't recognizing the errors. Is it a typo? If I take out the nul, this is what's returned:

The specified local group does not exist.

Usergroup News already exists.
System error 1376 has occurred.

=(

That's interesting....

Let me just try in mine for a mo.... I may have got my logic backwards....

(it sometimes happens to the best of us...)
Avatar of washy16

ASKER

Haha,

It happens to everyone =]

Would you happen to know if you can append the %%a variable in this case to a txt file but instead of listing it like this in the text file:

News
Distribution

Listing it like this:

News Distribution

That way I would be able to use FOR /f and give each one a variable from the outcome of a token.

Thanks again for your continued support.

Washy

You can append to lines. There are two tchniques.

The first is to read the line in, append to the line, then echo the line out to a temporary file (which is then renamed back to the original file later on)

The other way, a bit trickier though, is to suppress the carriage return and line feed characters at the end of the line, so that when you redirect the next output, it appends it to the prveious line rather than onto a new line.
Avatar of washy16

ASKER

Would you be able to create an example for both techniques for me? You lost me.

Were you successful testing the errorlevel==0?

I'm quite surprised at the testing... My logic was good however, XP is not behaving as it should be. I'll explain in my write-up after further tests into why I'm getting the results I'm getting.
Avatar of washy16

ASKER

Sounds great!
i'm away for a little while now... what's your current local time? I'm in the UK so I've got to drag myself away to make preparations for tomorrow. it's 8pm here now.
Avatar of washy16

ASKER

Its almost 3pm here, (Eastern Time)

sorry to have left you in the lurch. I've had car worries which won't be resolved until tomorrow night.
I amy be able to complete my write-up later this evening....
Again, i do apologise
Avatar of washy16

ASKER

I actually found a work around.

I called another .cmd file and used a replaceable variable.

The code in the first batch file is:

SET lastGroup=NOBODY
FOR /F %%i IN (sorteddepartments.txt) DO CALL MakeGroupListADD.cmd %%i
SET lastGroup=

and in the MakeGroupListADD.cmd file there is:

@ECHO OFF
IF %lastGroup%==%1 GOTO :EOF
NET LOCALGROUP %1 /ADD
SET lastGroup=%1

Everything works without any error messages at all.

Thanks for your help though,

Washy
ASKER CERTIFIED SOLUTION
Avatar of t0t0
t0t0
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
washy16

I have spent much time with you on this question. Please could we bring this to a conclusion.
Sorry for being late to this question - as I didn't see it listed yesterday for some reason... Then answer is very simple. Too bad the points went to a non-solution.

Justin Chandler
net localgroup > grouplist.txt
FOR /f "tokens=4 skip=6" %%a IN (HiredPersonnelTest.txt) DO call :proc_checkExistence %%a
del grouplist.txt
goto :eof
 
:proc_checkExistence
find /i "%1" grouplist.txt
if %errorlevel% equ 0 goto :eof
NET LOCALGROUP %1 /add
goto :eof

Open in new window

24230420-Create-local-groups-bas.txt