Jump to content

Welcome to MSFN Forum
Register now to gain access to all of our features. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more. This message will be removed once you have signed in.
Login to Account Create an Account


Photo

For loop problem

- - - - -

  • Please log in to reply
9 replies to this topic

#1
brian873

brian873

    Advanced Member

  • Member
  • PipPipPip
  • 335 posts
Hi,

I have a CMD file which extracts users from an Active Directory group then trims it so only the username is displayed in the output file GroupMemberTrim.txt.

It works fine, however I would like to use dynamic file names instead of static

GroupMemberExtract.txt -> %groupname%-Extract.txt
GroupMemberTrim.txt -> %groupname%-Trim.txt

When I change this it breaks the FOR loop so the %%a variable does not read in the contents of %groupname%-Extract.txt instead it reads the filename %groupname%-Extract.txt as the %%a variable.

Does anyone have any ideas how this could be fixed?

Thanks :)

@echo off
CLS

:GroupsMembersExtract
echo.
set /p groupname=enter groupname:
echo.
echo.
dsquery * domainroot -filter "(&(objectClass=group)(name=""%groupname%""))" -l -d DomainName -attr member >>GroupMemberExtract.txt


:GroupsMembersTrim
CLS
setlocal enabledelayedexpansion
FOR /F "tokens=1 delims=," %%a IN ( GroupMemberExtract.txt ) DO (
set oldName=%%a
set newName=!oldName:~3!
echo !%newName!>>GroupMemberTrim.txt
)
SETLOCAL DISABLEEXTENSIONS


:END



How to remove advertisement from MSFN

#2
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,281 posts
  • OS:none specified
  • Country: Country Flag

Does anyone have any ideas how this could be fixed?

Yes.
http://homepage.ntlw...no-answers.html

I am not sure to have understood the issue (actually I am sure to have it not understood) :ph34r:

Please post the .cmd that work and the one that doesn't and an example of the file to be parsed (GroupMemberExtract.txt).

What is this?:
!%newName!

jaclaz

#3
brian873

brian873

    Advanced Member

  • Member
  • PipPipPip
  • 335 posts
Hi Jaclaz, thanks for the reply

Sorry !%newName! was a typo, it should be !newName!

Ok here is the information you asked for.

When the CMD file prompts for input at the line

set /p groupname=enter groupname:

I am entering Accounts

Working CMD file
@echo off
CLS

echo.
set /p groupname=enter groupname:
echo.
echo.
dsquery * domainroot -filter "(&(objectClass=group)(name=""%groupname%""))" -l -d DomainName -attr member >>GroupMemberExtract.txt

CLS
setlocal enabledelayedexpansion
FOR /F "tokens=1 delims=," %%a IN ( GroupMemberExtract.txt ) DO (
set oldName=%%a
set newName=!oldName:~3!
echo !newName!>>GroupMemberTrim.txt
)
SETLOCAL DISABLEEXTENSIONS

:END

GroupMemberExtract.txt

CN=Joe Bloggs,OU=Accounts,OU=User Accounts,DC=DomainName,DC=company,DC=co,DC=uk


GroupMemberTrim.txt

Joe Bloggs



Non working CMD file with vairables
@echo off
CLS

echo.
set /p groupname=enter groupname:
echo.
echo.
dsquery * domainroot -filter "(&(objectClass=group)(name=""%groupname%""))" -l -d DomainName -attr member >>"%groupname%Extract.txt"

CLS
setlocal enabledelayedexpansion
FOR /F "tokens=1 delims=," %%a IN ( "%groupname%Extract.txt" ) DO (
set oldName=%%a
set newName=!oldName:~3!
echo !newName!>>"%groupname%Trim.txt"
)
SETLOCAL DISABLEEXTENSIONS

:END

AccountsExtract.txt

CN=Joe Bloggs,OU=Accounts,OU=User Accounts,DC=DomainName,DC=company,DC=co,DC=uk


AccountsTrim.txt

AccountsExtract.txt


So as you see, using the variables in this example throws out the %%a in the for loop and instead of phrasing the contents it uses the filename.

#4
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,532 posts
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

Before looking at the latter script I'd suggest you start by 'improving' the first one.

Get rid of everything below the DSQUERY line and replace it with something like this:
FOR /F "TOKENS=2 DELIMS==," %%# IN (
	'FINDSTR/B "CN=" GroupMemberExtract.txt') DO ECHO=%%#>>GroupMemberTrim.txt

<EDIT />
You will then see your problem which was caused by the inclusion of double quotes around the file name will have gone.
FOR /F "TOKENS=2 DELIMS==," %%# IN (
	'FINDSTR/B "CN=" "GroupMemberExtract.txt"') DO ECHO=%%#>>GroupMemberTrim.txt

Edited by Yzöwl, 04 October 2012 - 10:53 AM.
see <EDIT />


#5
jaclaz

jaclaz

    The Finder

  • Developer
  • 14,281 posts
  • OS:none specified
  • Country: Country Flag

So as you see, using the variables in this example throws out the %%a in the for loop and instead of phrasing the contents it uses the filename.

Yes/No.
The contents of AccountsTrim.txt after the:
set oldName=%%a
set newName=!oldName:~3!
should be:

ountsExtract.txt


But as Yzöwl posted it is easier/better to change the actual code/method.

If I get it right, you are using the for loop to "post process" the "integral" output of the dsquery command, you should be able to directly go to "GroupMemberTrim.txt" without having to pass through the "GroupMemberExtract.txt".

There might be the need to add more than a efw ESCAPE characters but including the:
dsquery * domainroot -filter "(&(objectClass=group)(name=""%groupname%""))" -l -d DomainName -attr member
inside a for loop seems to me like possible and "better".
Let's say that (once having the special character being escaped properly) the above code is just "%Command%"

FOR /F "tokens=2 delims=,=" %%A IN ('%Command%') DO ECHO %%A
it should work, see this as an example (working for me):
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
ECHO CN=Joe Bloggs,OU=Accounts,OU=User Accounts,DC=DomainName,DC=company,DC=co,DC=uk>test.txt
TYPE test.txt
FOR /F "tokens=2 delims=,=" %%A IN ('TYPE test.txt') DO ECHO %%A
SET dsquery=CN=Joe Bloggs,OU=Accounts,OU=User Accounts,DC=DomainName,DC=company,DC=co,DC=uk>test.txt
FOR /F "tokens=3 delims=,=" %%A IN ('SET dsquery') DO ECHO %%A

jaclaz

#6
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,532 posts
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

Just to prevent you getting confused with all of the suggestions for changing things, I'd just like to show you the difference betweeen your working and non working scripts.

FOR /F "tokens=1 delims=," %%a IN ( GroupMemberExtract.txt ) DO (
FOR /F "tokens=1 delims=," %%a IN ( "%groupname%Extract.txt" ) DO (

The former is looking at a file whilst the latter is looking at a string.

FOR /F ["options"] %%variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %%variable IN ("string") DO command [command-parameters]

This means that your non working script was parsing the string AccountsExtract.txt not the content of a file named AccountsExtract.txt.

The result you should have seen as jaclaz pointed out above should have been ountsExtract.txt and not that which you posted and therefore potentially prevented others from solving your issue.

#7
brian873

brian873

    Advanced Member

  • Member
  • PipPipPip
  • 335 posts
Thanks jaclaz & Yzöwl

OK that makes sense now.

I cant test it at the moment, will do it tomorrow. My only concern would be that %groupname% in some cases will contain spaces. I think omitting the " " will cause a problem. I will report what I find. :)

FOR /F "tokens=1 delims=," %%a IN ( "%groupname%Extract.txt" ) DO (



#8
allen2

allen2

    Not really Newbie

  • Member
  • PipPipPipPipPipPipPip
  • 1,812 posts
I wouldn't do that task like this because:
- the way you do it, if groups are members of the group you're trying to get members, you won't see the users members of those groups.
- if the DN (you're parsing it in your script) doesn't contain the same "display name", you might end up getting wrong accounts. Usually i prefer extracting the samid or samaccountname (login for a user account) as they are unique and they can't contain space or special character.
- for the same reason, i replaced a query on the samid of the group instead of its name.
@echo off
CLS

echo.
set /p groupname=enter groupname:

dsquery group -samid %groupname% |dsget group -members -expand |dsget user -display >%groupname%Extract.txt

Depend on your task, you might prefer using adfind as it is a lot more powerful and can format properly the output.

#9
Yzöwl

Yzöwl

    Wise Owl

  • Super Moderator
  • 4,532 posts
  • OS:Windows 7 x64
  • Country: Country Flag

Donator

Thanks jaclaz & Yzöwl

OK that makes sense now.

I cant test it at the moment, will do it tomorrow. My only concern would be that %groupname% in some cases will contain spaces. I think omitting the " " will cause a problem. I will report what I find. :)

FOR /F "tokens=1 delims=," %%a IN ( "%groupname%Extract.txt" ) DO (

For such a scenario you could try:
FOR /F "USEBACKQ TOKENS=2 DELIMS==," %%# IN ("%groupname%Extract.txt") DO ECHO=%%#>>"%groupname%Trim.txt"

I would also suggest you use DSQUERY GROUP piping the results through DSGET as suggested above by allen2, it may seem a little OTT for you but it was the first approach I considered when I saw your initial post.

#10
brian873

brian873

    Advanced Member

  • Member
  • PipPipPip
  • 335 posts
Thanks everyone I have it working the way I need it now.

@allen2 - thats a fair point and a good one to look out for. However in this environment there are no nested groups and all usernames are generated from another system so should be fine with the current task.

@Yzöwl - I have used the line you provided, thanks very much :)

FOR /F "USEBACKQ TOKENS=2 DELIMS==," %%# IN ("%groupname%Extract.txt") DO ECHO=%%#>>"%groupname%Trim.txt"


I will take a look at the other methods tools mentioned, but I can get what I need for now!

Cheers




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users



How to remove advertisement from MSFN