Solved

remove specific users from specific groups

Posted on 2013-01-02
25
724 Views
Last Modified: 2013-01-03
Hey all,

I have a task to remove specific users from specific groups from a list.  

the script needs to use sAMAccountName's of the users and groups from a list formatted as follows:

groupname1;username1
groupname2;username2

i have a script that adds the users to the groups, but now i need to reverse it. As a noob to scripting, any help would be appreciated. Thanks all.
0
Comment
Question by:MD187
[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
  • 9
  • 9
  • 7
25 Comments
 
LVL 23

Expert Comment

by:yo_bee
ID: 38738438
Can you post your script?
0
 

Author Comment

by:MD187
ID: 38738457
Sure thing,


Here is what i have for adding users:


ON ERROR RESUME NEXT

Dim DisplayEcho
Const ADS_PROPERTY_APPEND = 3

'---------------------------------------------------------------------------
'      User Variables
'---------------------------------------------------------------------------
'OU where groups are located
strOU="ou=temp,ou=test,dc=somewhere,dc=com"

'text file groups & users
'line format:  Group Name;User Name1;User Name2;
strTextFilename="C:\Groups.txt"

strLogFileName="C:\results.txt"

'True to display echos, false to hide
DisplayEcho = True
'---------------------------------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")

If DisplayEcho=True then
      'Force CSCRIPT
      If instr(lcase(wscript.fullname),"wscript") then
            wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
            wscript.quit
      End If
End If

Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

Set oFile=fso.OpenTextFile(strTextFilename,1)
text=oFile.ReadAll
oFile.close

arrText=split(text,vbCrLf)


For each line in arrText
      arrLine=split(line,";")
      strGroup=arrLine(0)
      err.Clear
      strGroupPath=GetADsPath(strGroup,"group")
     
      If strGroupPath = "" then
            Output "ERROR: Could not find group:  " & strGroup
            err.clear
      Else
                  Set objGroup = GetObject(strGroupPath)
            For i = 1 to ubound(arrLine)
                  strUser=arrLine(i)
                  strADsPath_user=GetADsPath(strUser,"user")
                  Set objUser=GetObject(strADsPath_user)
                  strUserDN=objUser.DistinguishedName
                  If strUserDN="" then
                        Output strGroup & "... Could not find user:  " & strUser
                  Else
                        objGroup.PutEx ADS_PROPERTY_APPEND, _
                              "member", Array(strUserDN)
                        objGroup.SetInfo
           
                        If err.number <> 0 then
                              If err.number="-2147019886" then
                                    Output strGroup & " <-- " & strUser & " (Already a member)"
                              Else
                                    Output "ERROR adding " & strUser & " to " & strGroup & vbCrLf & _
                                          vbTab & err.number & " " & err.description
                              End If
                              err.clear
                        Else
                              'show successful additions
                              Output strGroup & " <-- " & strUser
                        End If
                  End If
                  strUser=""
                  strUserDN=""
                  strADsPath_user=""
                  Set objUser=Nothing
            Next
           
      End If

      Set objGroup=Nothing
      arrLine=""
      strGroup=""

Next

oLogFile.close

Output ""
Output "Operation complete.  See Log:  " & strLogFileName


Sub Output(txt)
      If DisplayEcho=True then wscript.echo txt
      oLogFile.writeLine txt
End Sub



Function GetADsPath(myName,myType)
      Const ADS_SCOPE_SUBTREE = 2

      strADsPath=""

      Set objRootDSE = GetObject("LDAP://rootDSE")
      strRootDSE = objRootDSE.Get("defaultNamingContext")      

      Set objConnection = CreateObject("ADODB.Connection")
      Set objCommand =   CreateObject("ADODB.Command")
      objConnection.Provider = "ADsDSOObject"
      objConnection.Open "Active Directory Provider"
      Set objCommand.ActiveConnection = objConnection
     
      objCommand.Properties("Page Size") = 1000
      objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
     
      objCommand.CommandText = _
            "SELECT ADsPath FROM 'LDAP://" & strRootDSE & "' WHERE objectCategory='" & myType & "' " & _
                  "AND Name ='" & myName & "' "
     
      Set objRecordSet = objCommand.Execute
     
      objRecordSet.MoveFirst
      strADsPath = ""
      strADsPath= objRecordSet.Fields("ADsPath").value

      GetADsPath=strADsPath
     
      Set objConnection=Nothing
      Set objCommand=Nothing
      Set objRecordSet=Nothing
End Function
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38738788
Try this since you have a working Add User script.
Add Const ADS_PROPERTY_DELETE = 4
then replace ADS_PROPERTY_APPEND

I recommend trying this against a test group for confirmation.

Where did you get this script from.  Is seems pretty complex for a noob?
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 
LVL 40

Expert Comment

by:Subsun
ID: 38739183
In case you are interested in PowerShell, you can try this script..
#<Sample CSV format
Group,Member
groupname1;username1
groupname2;username2
#>
Import-module activedirectory
Import-Csv c:\test.csv | %{
Remove-ADGroupMember -Identity $_.Group -Members $_.Member -Confirm:$false}

Open in new window

0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38739754
@Subsun

The PS Import-CSV needs the -Delimiter ";" switch to address his ; format. If that is not there it will not work. I put together a post last night, but must not have pushed submit.
The script was identical to yours accept for the -delimiter switch.
0
 
LVL 40

Expert Comment

by:Subsun
ID: 38739785
Thanks for pointing out.. I just copy pasted the group name and user name from the user post but forgot change the semicolon to comma.. If you use coma the you don’t require the parameter -Delimiter with import-csv..

Correct CSV format
Group,Member
groupname1,username1
groupname2,username2

Open in new window

BTB  -Delimiter ";" will not work for the sample file mentioned in my post because the header is separated with comma..
0
 
LVL 23

Assisted Solution

by:yo_bee
yo_bee earned 167 total points
ID: 38740024
I have tested with my PS Script and it worked having th delimter ;

#<Sample CSV format
Group;Member
groupname1;username1
groupname2;username2
#>

import-module activedirectory
$csv = import-csv "FileName.txt" -Delimiter ';'
ForEach ($line in $csv)
{
remove-adgroupmember -Identity $line.Group -member $line.User  -Confirm:$false
}

Open in new window

0
 
LVL 40

Expert Comment

by:Subsun
ID: 38740066
Spot the difference my friend.. :-)  

My script input Group,Member (This will not work with -Delimiter ';', and that's why I posted Correct CSV format)

You modified the script input Group;Member (This will work with -Delimiter ';')

That's what I said in my previous comment "BTB  -Delimiter ";" will not work for the sample file mentioned in my post because the header is separated with comma.. "
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38740627
Sorry.
0
 
LVL 40

Expert Comment

by:Subsun
ID: 38740868
That's fine.. I just wanted to printout the difference.. :-)
0
 

Author Comment

by:MD187
ID: 38741136
Thank you both for the work on this, PS is a much more "elegant" solution over VB.  Yo_bee, the script was put together by myself, with a lot of help from a former college who has since left my organization.  I may go back and change the "add user VB script" to PS.  

Can that be done by changing:  
Remove-ADGroupMember -Identity $_.Group -Members $_.Member -Confirm:$false}

to:
Add-ADGroupMember -Identity $_.Group -Members $_.Member -Confirm:$false}, looks like that works.

The .csv format may present a problem, as the file is generated by an application as i had posted.  I hope not a huge problem for the Apps' guys, but it may make it easier if both the "Add" and "Remove" .csv's are formatted the same way.

Can i include:  $results | export-csv C:\results.txt to export the results to a file?
0
 
LVL 40

Expert Comment

by:Subsun
ID: 38741173
just Add-ADGroupMember -Identity $_.Group -Members $_.Member will work. no need of  -Confirm.

You can modify the script based on csv format however if you have a input file as mentioned above, then things will be much easy..

What result you want to export?
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38741197
We are looking to remove correct?
Doesn't prompt you Yes, Yes To All, No, No To All?
0
 

Author Comment

by:MD187
ID: 38741232
Thanks Subsun,

I am hopeful that i can have the input file modified, easy is good :)

As to the results, i would like a file that shows the account that were added and/or removed. Not crucial, but would be helpful for the Apps Guys.

Thanks
0
 
LVL 40

Expert Comment

by:Subsun
ID: 38741236
I may go back and change the "add user VB script" to PS.  
Now we are talking about adding.. adding will not prompt..
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38741238
@MD

That is what it used to be like, but as you can see PS has many one liners Verb Noun processes that make it easier on everyone.
0
 
LVL 40

Expert Comment

by:Subsun
ID: 38741246
For reporting you can use Try Catch method in PowerShell, do you want to generate a log file or just want to display it in screen?
0
 

Author Comment

by:MD187
ID: 38741301
A log file.
0
 
LVL 40

Accepted Solution

by:
Subsun earned 333 total points
ID: 38741344
Try this..
<#Sample CSV format
Group,Member
groupname1,username1
groupname2,username2
#>
$logfile = "scriptlog.txt"
Import-module activedirectory
Import-Csv c:\test.csv | %{
	Try 
		{Remove-ADGroupMember -Identity $_.Group -Members $_.Member -Confirm:$false
		Add-Content -path $logfile -value "Successfully removed $($_.Member) from $($_.Group)"}
	Catch 
		{Add-Content -path $logfile -value "Failed to remove $($_.Member) from $($_.Group)"}
}

Open in new window

0
 

Author Comment

by:MD187
ID: 38741556
Works perfectly, is there a way to overwtie the logfile, instead of append?
0
 
LVL 40

Assisted Solution

by:Subsun
Subsun earned 333 total points
ID: 38741598
After $logfile = "scriptlog.txt"
Add following line, this line will remove the old log file if it exist..
If (Test-Path $logfile) {Remove-Item $logfile}
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38741655
$logfile = New-Item "Filepath\name.txt" -Force
0
 

Author Closing Comment

by:MD187
ID: 38741755
Thank you all for the help, errr, doing this for me. I have learned quite a bit and it has helped in understanding why the solutions you both presented work.  At the very least, yet another nail in the VB coffin for me.  

Again, thank you for the expertise in resolving my issue, Happy New Years!
0
 
LVL 23

Expert Comment

by:yo_bee
ID: 38741906
Did you try the New-Item method over the Remove-Item?
Just one less step for the script.
0
 

Author Comment

by:MD187
ID: 38742048
I did, thank you. I tried to give both you guys some points for all the colaberation.  Again thank you!

Take care all!
0

Featured Post

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Suggested Solutions

A project that enables an administrator to perform actions within a user session context not just at the time of login but any time later on day(s) or week(s) later.
Recently, Microsoft released a best-practice guide for securing Active Directory. It's a whopping 300+ pages long. Those of us tasked with securing our company’s databases and systems would, ideally, have time to devote to learning the ins and outs…
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

739 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