Member_2_761121
asked on
Script works in test but not in live site, why??
Have this script to remove hidden mailbox accounts from distribution groups (both Security & Universal) in Active Directory. Tested ok in lab conditions the only difference being the number of accounts in the distribution group about 10 in lab and approx 3,500 in live. Also single Domain Controller in test and 3 in Live.
Also how do I specify in the LDAP search an OU with spaces in it?? As this would save me moving the groups to run the script then moving them back.
Script runs through ok without errors, it creates the text file but doesn't remove any accounts??????? and text file is empty
This is the script
Option Explicit
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "Removed All Staff Members.txt"
Set objFSO = CreateObject("Scripting.Fi leSystemOb ject")
set objFile = objFSO.OpenTextFile(strFil e,ForAppen ding, True)
Set objContainer = GetObject("LDAP://OU=Peopl e,dc=domai n,dc=co,dc =uk")
Set objGroup = objContainer.GetObject("gr oup","CN=A ll Staff Members")
objContainer.Filter = Array("user")
For Each objUser in objContainer
Set objExUser = GetObject(objUser.adspath)
If objExUser.msExchHideFromAd dressLists =TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
Call objGroup.Remove(objUser.ad spath)
End If
Next
objFile.Close
Wscript.Echo "Finished"
Also how do I specify in the LDAP search an OU with spaces in it?? As this would save me moving the groups to run the script then moving them back.
Script runs through ok without errors, it creates the text file but doesn't remove any accounts??????? and text file is empty
This is the script
Option Explicit
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "Removed All Staff Members.txt"
Set objFSO = CreateObject("Scripting.Fi
set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = objContainer.GetObject("gr
objContainer.Filter = Array("user")
For Each objUser in objContainer
Set objExUser = GetObject(objUser.adspath)
If objExUser.msExchHideFromAd
objFile.WriteLine "Removing: "& objUser.Name
Call objGroup.Remove(objUser.ad
End If
Next
objFile.Close
Wscript.Echo "Finished"
ASKER
Thanks for the response, unfortunately it doesn't appear to be as easy as just entering the space, have tested this on test lab and it fails (runs script, creates txt file, doesn't remove anyone) if OU has space in it. Move Group to OU without a space and update script and works great??? But not that concerned with this as just need to get the users out of the group
Not sure why add objExuser, as got some help of this site with the script, didn't really question it as it worked :)
The major problem is why it will not run on live site, its now urgent purpose is to remove approx 1200 accounts from 2 groups
Thought I was on to a winner as it worked as expected on test lab??
Not sure why add objExuser, as got some help of this site with the script, didn't really question it as it worked :)
The major problem is why it will not run on live site, its now urgent purpose is to remove approx 1200 accounts from 2 groups
Thought I was on to a winner as it worked as expected on test lab??
Is the test environment identical to the live? Windows 2003 domains, for example, have no problem dealing with the space in the LDAP connection - I admit I haven't tested the same against Windows 2000.
I take it all the accounts you want to remove are in one OU?
It would be possible to use the WinNT method to remove the users from the group after pulling a list from LDAP. Let me know what you're looking to achieve anyway, I'm sure we can come up with something that works.
Chris
ASKER
Test & Live both native w2k domains, test is single DC with all 5 FSMO roles, Live is 3 DC's with roles split between them.
The actual accounts could be in 3 different OU's, however the Group is in one OU called People, there are some accounts in here and some in sub OU's
The goal is to remove 1200 user accounts from a distribution group based on the attribute of them being hidden from the address list. Thus leaving an up to date group for people to email to
The actual accounts could be in 3 different OU's, however the Group is in one OU called People, there are some accounts in here and some in sub OU's
The goal is to remove 1200 user accounts from a distribution group based on the attribute of them being hidden from the address list. Thus leaving an up to date group for people to email to
Makes sense...
I think the main problem is going to be:
objExUser.msExchHideFromAd
If that were returning properly you'd get something written into your output file - the fact that you get nothing in there implies that the If statement is never running.
Could you try this? Afriad I don't have an exchange server here so the properties just aren't present. But this attempts both methods to see what there is there.
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro
If Err.Number <> 0 Then
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
booHidden = objUser.msExchHideFromAddr
If booHidden <> TRUE Then
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
End If
End If
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.Remove(objUser.ad
End If
Next
ASKER
Thanks, tried this and got an error on line 32 character 6 ?
Line 32 is "If booHidden = TRUE"?
And is the error Type Mismatch?
Chris
ASKER
When run script it shows a single window saying it was unable to retireve information from a single account and then show error Variable is undifined 'boohidden'
Ahh you either need to turn off Option Explicit or Dim booHidden.
Then it should at least run...
ASKER
ok, now it runs through script and writes out text file with members that it should remove, doesn't remove them and returns error Line 34 CHar 11 the server is unwilling to process the request?
Could you post Line 34?
And I take it you don't get anything posting from these two:
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
ASKER
Here is what I'm running, will try the other options now
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi leSystemOb ject")
set objFile = objFSO.OpenTextFile(strFil e,ForAppen ding, True)
Set objContainer = GetObject("LDAP://OU=Peopl e,dc=domai n,dc=co,dc =uk")
Set objGroup = objContainer.GetObject("gr oup","cn=A ll Staff")
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro mAddressLi sts")
If Err.Number <> 0 Then
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
booHidden = objUser.msExchHideFromAddr essLists
If booHidden <> TRUE Then
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
End If
End If
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.Remove(objUser.ad spath)
End If
Next
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi
set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = objContainer.GetObject("gr
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro
If Err.Number <> 0 Then
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
booHidden = objUser.msExchHideFromAddr
If booHidden <> TRUE Then
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
End If
End If
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.Remove(objUser.ad
End If
Next
Okay, it looks like 34 refers to "objGroup.Remove(objUser.a
It's a slight improvement as it seems it's actually entering the If Statement and ending up with the right value for msExchHideFromAddressLists
Can we change the connection to the group to this?
Set objGroup = GetObject("LDAP://cn=All Staff,ou=People,dc=domain,
Just to see if it can connect to that.
ASKER
so rather than
Set objContainer = GetObject("LDAP://OU=Peopl e,dc=domai n,dc=co,dc =uk")
Set objGroup = objContainer.GetObject("gr oup","cn=A ll Staff")
Have it as just Set objGroup = GetObject("LDAP://cn=All Staff,ou=People,dc=domain, dc=co,dc=u k")?
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = objContainer.GetObject("gr
Have it as just Set objGroup = GetObject("LDAP://cn=All Staff,ou=People,dc=domain,
You'll still need objContainer, it gets the list of users from there.
But the change applies to objGroup yes.
ASKER
ok script now looks like this , is htis how you think it should look?
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi leSystemOb ject")
set objFile = objFSO.OpenTextFile(strFil e,ForAppen ding, True)
Set objContainer = GetObject("LDAP://OU=Peopl e,dc=domai n,dc=co,dc =uk")
Set objGroup = GetObject("LDAP://cn=All Staff,OU=People,DC=domain, dc=co,dc=u k")
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro mAddressLi sts")
If Err.Number <> 0 Then
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
booHidden = objUser.msExchHideFromAddr essLists
If booHidden <> TRUE Then
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
End If
End If
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.Remove(objUser.ad spath)
End If
Next
Script runs and creates empty txt file and returns error Line 32 Char11 The server is unwilling to process the request
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi
set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = GetObject("LDAP://cn=All Staff,OU=People,DC=domain,
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro
If Err.Number <> 0 Then
wscript.echo "Unable to retrieve value from " & objUser.Name & " with Get"
booHidden = objUser.msExchHideFromAddr
If booHidden <> TRUE Then
wscript.echo objUser.Name & " is either not hidden or query failed - " & booHidden
End If
End If
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.Remove(objUser.ad
End If
Next
Script runs and creates empty txt file and returns error Line 32 Char11 The server is unwilling to process the request
Okay I think I have the cause now. There's just a difference between the AD Group Object and the Local Group Object. So to make things more complicated a different remove function has to be used.
Can you try this modification (I also removed some of the bits I added to check it was working):
Dim objFSO, objFile, objContainer, objGroup, objUser
Dim strFile
Dim booHidden
Const ForAppending = 8
Const ADS_PROPERTY_DELETE = 4
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi
Set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = GetObject("LDAP://cn=All Staff,OU=People,DC=domain,
For Each objUser in objContainer
On Error Resume Next
Err.Clear
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.PutEx ADS_PROPERTY_DELETE, _
"member", Array(objUser.ADsPath)
objGroup.SetInfo
End If
Set objUser = Nothing
Next
objFile.Close
Set objGroup = Nothing
Set objContainer = Nothing
Set objFSO = Nothing
ASKER
ok it runs creates txt with one entry of a hidden group in the People OU, then errors on Line 27 char 11 , The server is unwilling to process the request
D'oh sorry... think I forgot to put the filter back in... here's an ammendment:
Dim objFSO, objFile, objContainer, objGroup, objUser
Dim strFile
Dim booHidden
Const ForAppending = 8
Const ADS_PROPERTY_DELETE = 4
strFile = "All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi
set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = GetObject("LDAP://cn=All Staff,OU=People,DC=domain,
objContainer.Filter = Array("user")
For Each objUser in objContainer
On Error Resume Next
booHidden = FALSE
booHidden = objUser.Get("msExchHideFro
On Error Goto 0
If booHidden = TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
objGroup.PutEx ADS_PROPERTY_DELETE, _
"member", Array(objUser.ADsPath)
objGroup.SetInfo
End If
Next
One more thing... it may throw up a complaint if the user isn't a member of the group but you try to remove them - it would be possible to compare with the current membership of the group, but that can be quite timeconsuming for large groups (another set of For Each).
The quick and dirty fix is to remove the "On Error Goto 0" line above (originally there to disable error suppression after getting the msExch attribute).
Hope that makes sense.
Chris
ASKER
ok script runs and writes txt file with a single entry of the first person that it should remove but doesn't actually remove them from the group? and errors with Line 27 Char 11 The server is unwilling to process the request?
That's basically a permissions problem as far as I can tell. I take it you're running the script as domain administrator?
Going to have another look around anyway to see what can be done...
ASKER
running as administrator in domain admins group on domain controller. The following script works on test lab creates file with removed members and actually removes them, it just doesn't work on live system for some reason???? It does run just doesn't write anything to the txt file or remove them??
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "Removed All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi leSystemOb ject")
set objFile = objFSO.OpenTextFile(strFil e,ForAppen ding, True)
Set objContainer = GetObject("LDAP://OU=Peopl e,dc=domai n,dc=co,dc =uk")
Set objGroup = objContainer.GetObject("gr oup","CN=A ll Staff")
objContainer.Filter = Array("user")
For Each objUser in objContainer
Set objExUser = GetObject(objUser.adspath)
If objExUser.msExchHideFromAd dressLists =TRUE Then
objFile.WriteLine "Removing: "& objUser.Name
Call objGroup.Remove(objUser.ad spath)
End If
Next
objFile.Close
Wscript.Echo "Finished"
thanks for looking into this its greatly appreciated!
Dim objContainer
Dim objGroup
Dim objUser
Dim objExUser
Dim strFile
Dim objFSO
Dim objFile
Const ForAppending = 8
strFile = "Removed All Staff.txt"
Set objFSO = CreateObject("Scripting.Fi
set objFile = objFSO.OpenTextFile(strFil
Set objContainer = GetObject("LDAP://OU=Peopl
Set objGroup = objContainer.GetObject("gr
objContainer.Filter = Array("user")
For Each objUser in objContainer
Set objExUser = GetObject(objUser.adspath)
If objExUser.msExchHideFromAd
objFile.WriteLine "Removing: "& objUser.Name
Call objGroup.Remove(objUser.ad
End If
Next
objFile.Close
Wscript.Echo "Finished"
thanks for looking into this its greatly appreciated!
ASKER
ok looking it at from the other side I have a txt or csv file with the names on of the people that I want to remove from the group. What would the script look like to read the file and remove from group? Could bind direct to a specific domain controller and the group?
Are both the test and live versions running at the same functional level?
That will have an effect on how objects can be retrieved from the user account and could explain why you can do "objExUser.msExchHideFromA
ADSI scripting is always a bit of a complex one because there is little standardisation in how and what you can access in an object.
Just for the sake of testing... does the altered script work on the test environment at all?
As an alternative approach it shoud be possible to approach it from the other way, by altering the memberOf list on the user account.
Give me a few moments and I'll see what I can do with the csv file input as well.
ASKER
both native 2000 mode, the only difference is test lab has 2 DC and live has 3, the altered script has run abd created txt file but I don't recall it removing anyine from the group.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Comma is the delimiter for LDAP connections, so to specify an OU with spaces in it is simply a case of including the space.
e.g.
Set objRootDSE = GetObject("LDAP://rootDSE"
Set objContainer = GetObject("LDAP://ou=The One With Spaces,ou=TheOneWithout," & objRootDSE.Get("defaultNam
Check that it enters this If statement - it's the most likely point of failure:
If objExUser.msExchHideFromAd
objFile.WriteLine "Removing: "& objUser.Name
Call objGroup.Remove(objUser.ad
End If
Easiest way to do that is just throw in some wscript.echo statements...
Why did you add objExUser? You already have a connection to each user object with objUser.
Chris