[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Add members in one group to another group via script

Posted on 2015-02-04
15
Medium Priority
?
180 Views
Last Modified: 2015-02-25
Hey Experts!!  As part of an on-going migration, I need to migrate users from group-x to group-y but this will be an on-going event so I need to be able to change the AD path for group-x.

How could I do this with a batch script where it will prompt me for "group-x" and output who was moved into a log file?

Thanks for your help!
0
Comment
Question by:samiam41
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
  • 2
  • +3
15 Comments
 
LVL 37

Expert Comment

by:Jian An Lim
ID: 40590636
you do this with powershell scripts.

install the required AD tools on windows 7
then you can run powershell

import-module activedirectory
$input = read-host "what is your group-x?"

$members = Get-ADGroupMember $input | select samaccountname

foreach ($member in $members){
add-adgroupmember -identity "group-y" -add $member
}

(coding are write on fly without really verify)

is this what you are looking for?
(i can write a better coding when i have back to work)
0
 
LVL 38

Expert Comment

by:Mahesh
ID: 40590754
What do you mean by change AD path ?

If you want to add users from one domain to another over trust, you do need domain local group \ universal group as target group and then you can copy group members from one domain to domain local \ universal group in another domain.

$group = Get-ADGroupMember -Identity "CN=Sourcegroup,dc=sourcedomain,dc=com"
Foreach ($member in $group)
{ Add-ADGroupMember -Identity "CN=targetgroup,DC=targetdomain,dc=com" $member}

# Replace source group with one from which you want to copy members

# Target group must be domain local group \ universal in target domain

Open in new window

0
 
LVL 9

Author Comment

by:samiam41
ID: 40591417
Thanks for the replies.  Let me try to explain it a little further.

Groups are in the same domain.  The OU's are different, such as:

Department (OU)
>Admin (OU)
>>Groups (OU)
>>>GroupABC

>Finance (OU)
>>Groups (OU)
>>>GroupDEF

>Research (OU)
>>Groups (OU)
>>>GroupGHI

I need to copy the users in GroupABC (the variable that I would like the script to prompt me with) into GroupGHI (the constant in the script).  When I run the script again, I would like to have the script prompt me for the name of the group (variable) and then begin copying those users to GroupGHI (the constant hardcoded into the script).

I would prefer to use batch as that is what all of my other scripts are and I don't have time to get into PS at the moment.  Thank you!
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 
LVL 38

Expert Comment

by:Mahesh
ID: 40592025
Then script would work as below
It will ask you simple name of source group and target group you have to enter one time in script as per your requirement
Import-Module ActiveDirectory
$GroupName = Read-Host -Prompt "Please Enter Source Group Name"
$group = Get-ADGroupMember -Identity $GroupName
Foreach ($member in $group)
{ Add-ADGroupMember -Identity "TargetGroupName" $member}

# Shell will prompt you for source group name from which you want to copy members

# Target group you have to enter one time only in a script)

Open in new window


U have to call this script on Windows 2008 R2 and above server with elevated PowerShell
Do not forget to set Executionpolicy to remotesigned OR unrestricted
In order to do that run below commands on 2008 R2 DC in elevated PowerShell
Set-Executionpolicy RemoteSigned
when prompted, type yes

Actually then limjianan code should work, however, $input variable is not acceptable by PowerShell and -add parameter is also not available
Hence I modified those TWO parameters

If you do not want to use PowerShell, Probably some expert might help you in another scripting language.
0
 
LVL 25

Expert Comment

by:NVIT
ID: 40592144
Here's a .bat version.
Note: I put an ECHO prefix for testing reasons. Remove the prefix to run it for real:
@echo off
set Grp=GroupGHI

:GetGroup
SET /P Grp=What group to add to %Grp%? 
set FNMembers=Members.txt
net group %Grp% /domain>%FNMembers%
if %errorlevel% neq 0 (echo Invalid group. Try again. & pause & goto :GetGroup)

for /f "tokens=* skip=8" %%a in (%FNMembers%) do (
  call :AddToGroup "%%a"
)
goto :eof

:AddToGroup
if %1 equ "The command completed successfully." goto :eof
for %%a in (%~1) do (
  echo net group %Grp% %%a /add /domain
)

Open in new window

0
 
LVL 16

Expert Comment

by:cantoris
ID: 40592175
You don't need to use a foreach construction.

Just pipe Get-ADGroupMember to Add-ADPrincipalGroupMembership
You will see reference to this latter cmdlet in the help documentation for Add-ADGroupMember

ie based on the above
$dstGrp = "Destination Group Name"
$srcGrp = Read-Host -Prompt "Please Enter Source Group Name"
Get-ADGroupMember $srcGrp | Add-ADPrincipalGroupMembership -MemberOf $dstGrp

Open in new window


You can also use the output of the Get-ADGroupMember cmdlet to view the list of users too that you were adding.
0
 
LVL 37

Expert Comment

by:Jian An Lim
ID: 40592650
wowow, i think there are more experts helping since my initial conversation :)
0
 
LVL 85

Expert Comment

by:oBdA
ID: 40598785
Plain batch; uses dsquery.exe, dsget.exe, and dsmod.exe from the RSAT AD tools; will create a log file in csv format in the script's folder. Doesn't complain when run several times against the same group.
@echo off
setlocal enabledelayedexpansion
set LogFile=%~dpn0.csv
set CsvDelim=,
set GroupTarget=GroupGHI
set GroupSource=&set /p "GroupSource=Please enter the name of the source group without quotes: "
if "%GroupSource%"=="" goto :eof
set GroupTargetDN=&for /f "delims=" %%a in ('dsquery.exe group -samid "%GroupTarget%"') do (set GroupTargetDN=%%~a)
if "%GroupTargetDN%"=="" (echo ERROR: Target group '%GroupTarget%' not found in AD.&exit /b 1)
set GroupSourceDN=&for /f "delims=" %%a in ('dsquery.exe group -samid "%GroupSource%"') do (set GroupSourceDN=%%~a)
if "%GroupSourceDN%"=="" (echo ERROR: Source group '%GroupSource%' not found in AD.&exit /b 1)
if not exist "%LogFile%" (
	>"%LogFile%" echo "Object DN"%CsvDelim%"Source Group"%CsvDelim%"Target Group"%CsvDelim%"Copy Date"%CsvDelim%"Copy Time"%CsvDelim%"Result"
)
for /f "tokens=2 delims=,=" %%a in ("%GroupSourceDN%") do set GroupSource=%%a
echo Source DN: %GroupSourceDN%
echo Target DN: %GroupTargetDN%
echo Log file:  %LogFile%
echo Retrieving target group members ...
set /a TargetCount = 0
for /f "delims=" %%a in ('dsget.exe group -members "%GroupTargetDN%"') do (
	set /a TargetCount += 1
	set Target[!TargetCount!]=%%~a
)
set /a SkippedCount = 0
set /a SuccessCount = 0
set /a ErrorCount = 0
for /f "delims=" %%a in ('dsget.exe group -members "%GroupSourceDN%"') do (call :AddMember "%%~a")
echo Done; added %SuccessCount% accounts, skipped %SkippedCount% accounts, encountered %ErrorCount% errors.
if not %ErrorCount%==0 (exit /b 1)
goto :eof

:AddMember
set ObjectDN=%~1
echo Processing '%ObjectDN%' ...
for /l %%i in (1, 1, %TargetCount%) do (
	if /i "!Target[%%i]!"=="%ObjectDN%" (
		echo ... already member of the target group.
		set /a SkippedCount += 1
		goto :eof
	)
)
for /f "delims=" %%a in ('dsmod.exe group "%GroupTargetDN%" -addmbr "%ObjectDN%" 2^>^&1') do (set Result=%%a&goto :Next)
:Next
if "%Result:~0,16%"=="dsmod succeeded:" (
	set Result=OK
	set /a SuccessCount += 1
) else (
	set /a ErrorCount += 1
)
echo ... %Result%
>>"%LogFile%" echo "%ObjectDN%"%CsvDelim%"%GroupSource%"%CsvDelim%"%GroupTarget%"%CsvDelim%"%Date%"%CsvDelim%"%Time%"%CsvDelim%"%Result%"
goto :eof

Open in new window

0
 
LVL 9

Author Comment

by:samiam41
ID: 40603229
Hey everyone.  I'm back on this mini-project after working on a HVAC and VMWare issue.

I will update the group when I try out the suggestions you posted.  Thanks Experts.
0
 
LVL 9

Author Comment

by:samiam41
ID: 40603464
@oBdA, that script works amazing!  I have two questions about it.  The first is that the log file is the name of the script which causes problems.  Is it possible to name of the log file to match the name of the source group?  And the object DN path in the log file looks like this:

CN=Name\, User,OU=Users,OU=Dept,OU=Depts,OU=X,DC=Domain,DC=Domain1,DC=Domain2,DC=Domain3

Can the log file contain just CN=Name\, User ?

Thanks for the hard work.

@NewVillageIT, I'm testing your suggestion now.
0
 
LVL 9

Author Comment

by:samiam41
ID: 40603471
I haven't tried the powershell options yet.  I'm not familiar with PS so it will be awhile, if I get to them but I appreciate your help and posting your suggestions.
0
 
LVL 85

Accepted Solution

by:
oBdA earned 1400 total points
ID: 40603574
@echo off
setlocal enabledelayedexpansion
set CsvDelim=,
set GroupTarget=GroupGHI
set GroupSource=&set /p "GroupSource=Please enter the name of the source group without quotes: "
if "%GroupSource%"=="" goto :eof
set LogFile=%~dp0%GroupSource%.csv
set GroupTargetDN=&for /f "delims=" %%a in ('dsquery.exe group -samid "%GroupTarget%"') do (set GroupTargetDN=%%~a)
if "%GroupTargetDN%"=="" (echo ERROR: Target group '%GroupTarget%' not found in AD.&exit /b 1)
set GroupSourceDN=&for /f "delims=" %%a in ('dsquery.exe group -samid "%GroupSource%"') do (set GroupSourceDN=%%~a)
if "%GroupSourceDN%"=="" (echo ERROR: Source group '%GroupSource%' not found in AD.&exit /b 1)
if not exist "%LogFile%" (
	>"%LogFile%" echo "Object CN"%CsvDelim%"Source Group"%CsvDelim%"Target Group"%CsvDelim%"Copy Date"%CsvDelim%"Copy Time"%CsvDelim%"Result"
)
for /f "tokens=2 delims=,=" %%a in ("%GroupSourceDN%") do set GroupSource=%%a
echo Source DN: %GroupSourceDN%
echo Target DN: %GroupTargetDN%
echo Log file:  %LogFile%
echo Retrieving target group members ...
set /a TargetCount = 0
for /f "delims=" %%a in ('dsget.exe group -members "%GroupTargetDN%"') do (
	set /a TargetCount += 1
	set Target[!TargetCount!]=%%~a
)
set /a SkippedCount = 0
set /a SuccessCount = 0
set /a ErrorCount = 0
for /f "delims=" %%a in ('dsget.exe group -members "%GroupSourceDN%"') do (call :AddMember "%%~a")
echo Done; added %SuccessCount% accounts, skipped %SkippedCount% accounts, encountered %ErrorCount% errors.
if not %ErrorCount%==0 (exit /b 1)
goto :eof

:AddMember
set ObjectDN=%~1
echo Processing '%ObjectDN%' ...
for /l %%i in (1, 1, %TargetCount%) do (
	if /i "!Target[%%i]!"=="%ObjectDN%" (
		echo ... already member of the target group.
		set /a SkippedCount += 1
		goto :eof
	)
)
for /f "delims=" %%a in ('dsmod.exe group "%GroupTargetDN%" -addmbr "%ObjectDN%" 2^>^&1') do (set Result=%%a&goto :Next)
:Next
if "%Result:~0,16%"=="dsmod succeeded:" (
	set Result=OK
	set /a SuccessCount += 1
) else (
	set /a ErrorCount += 1
)
echo ... %Result%
for /f "tokens=2 delims==" %%a in ("%ObjectDN%") do (set ObjectCN=%%a)
set ObjectCN=%ObjectCN:~0,-3%
set ObjectCN=%ObjectCN:\,=,%
>>"%LogFile%" echo "%ObjectCN%"%CsvDelim%"%GroupSource%"%CsvDelim%"%GroupTarget%"%CsvDelim%"%Date%"%CsvDelim%"%Time%"%CsvDelim%"%Result%"
goto :eof

Open in new window

0
 
LVL 9

Author Comment

by:samiam41
ID: 40630538
Closing this question out today.  Thanks everyone for your help (and patience)!
0
 
LVL 25

Assisted Solution

by:NVIT
NVIT earned 600 total points
ID: 40630587
My first .bat post has errors. FWIW, here's an updated version.

Regarding this revision, if you enter a wrong group name, it shows the groups in your domain in another window. This is for convenience. If you'd rather not have that, erase the text: "& start "Groups" cmd /k net group /domain".
@echo off
setlocal
cls

set AddToGrp=CAD

:GetGroup
REM set Grp=GroupGHI
SET /P Grp=What group to add to %AddToGrp%? 
set FNMembers=Members.txt
net group "%Grp%" /domain>%FNMembers%
if %errorlevel% neq 0 (echo Invalid group. Try again. & pause & start "Groups" cmd /k net group /domain & goto :GetGroup)

for /f "tokens=* skip=8" %%a in (%FNMembers%) do (
  call :AddToGroup "%%a"
)
goto :eof

:AddToGroup
if %1 equ "The command completed successfully." goto :eof
for %%a in (%~1) do (
  echo net group "%AddToGrp%" %%a /add /domain
)

Open in new window

0
 
LVL 9

Author Closing Comment

by:samiam41
ID: 40631273
Thanks experts!!

I didn't have a chance to dive into the powershell portion of the suggestions as the project timeline changed, so my apologies for not being able to give them the time they deserved.

I look forward to working with you all again soon.  Thanks everyone!
0

Featured Post

Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

While working, an annoying popup showing below will come and we cannot cancel or close it form the screen. The error message will come again and again.
This is a fine trick which I've found useful many times, when you just don't want to accidentally run a batch script or the commands needs administrator rights.
This Micro Tutorial will teach you how to change your appearance and customize your Windows 7 interface to your unique preference. This will be demonstrated using Windows 7 operating system.
This Micro Tutorial will give you a basic overview of Windows DVD Burner through its features and interface. This will be demonstrated using Windows 7 operating system.
Suggested Courses

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question