Solved

remove specific users from specific groups

Posted on 2013-01-02
25
710 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
  • 9
  • 9
  • 7
25 Comments
 
LVL 21

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 21

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
 
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 21

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 21

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 21

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 21

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 21

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 21

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 21

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

Join & Write a Comment

Utilizing an array to gracefully append to a list of EmailAddresses
Is your Office 365 signature not working the way you want it to? Are signature updates taking up too much of your time? Let's run through the most common problems that an IT administrator can encounter when dealing with Office 365 email signatures.
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…

759 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now