Is there a way of exporting all the members of multiple Active Directory groups at once using a VBScript? Preferably the output would be the usernames listed under the group they are a member of.
I have the following which allows me to export the members of 1 AD Group at a time, but I am at a loss as to how to modify it to look at multiple groups.
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set outfile = fso.CreateTextFile("Members.csv")
Set objGroup = GetObject("LDAP://cn=*GROUPNAME*,OU=Groups,DC=domain,DC=local")
objGroup.GetInfo
arrMembersOf = objGroup.GetEx("member")
For Each GetObject in ObjGroup
outfile.WriteLine objGroup.Name
Next
For Each strMember in arrMembersOf
outfile.WriteLine strMember
Next
Any ideas?
Yeah, this is possible, but I think you might need to change your approach slightly. You need to write an LDAP query to query two groups at once, rather than just setting your scope to a particular group.
So, try reworking your script like this:
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set objRootDSE = Nothing
Set ad = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
ad.ActiveConnection = adoConnection
'Put the distinguishedname of your two groups here:
strFilter = "(|(memberof=CN=Group Name,OU=....)(memberof=CN=Group Name 2,OU=....))"
'Chose what you want to return here:
strAttributes = "samaccountname,cn"
strQuery = "<LDAP://" & strDNSDomain & ">" & ";" & strFilter & ";" & strAttributes & ";subtree"
ad.CommandText = strQuery
ad.Properties("SearchScope") = 2
ad.Properties("Page Size") = 1000
ad.Properties("Cache Results") = False
Set objRS = ad.Execute
Now you've got all the results in a recordset, you can work your way through them writing each one to a file or whatever you want to do. So something like:
Do Until objRS.EOF
'Do something with each value
objRS.Fields("samaccountname")
objRS.MoveNext
Loop
Any use? I'm assuming here you know a little bit about writing LDAP queries
The best place to find scripts for Active Directory is Microsoft's Script Center Repository.
You can find a script listing all groups and all group members here ("List all groups in the domain and all members of the groups").
Related
I'm fairly new to scripting and am in need of some help. I have come across a unique situation for a Non-Profit client of ours that requires us to compare two or more files in a specific folder and move the file with the lowest numerical value in the filename.
This organization runs a non-profit radio station which has content submitted from hundreds of volunteers that name their files (when they record more than one) with various numbers at the end that either represent the date or the order in which the files are to be aired.
Essentially I am looking to create a vbscript (because I think it can be done this way) that will run with windows task scheduler 30 minutes prior to the first air date of the content and move the file with the lowest value (if more than one file exists) to a folder where it will be automatically processed by the radio automation software.
Examples of files in a folder might look something like these:
Folder1: (in this instance, "news.mp3" is the lowest value)
news.mp3
news1.mp3
news2.mp3
Folder2:
entertainment24.mp3
entertainment26.mp3
Folder3:
localnews081420.mp3
localnews081520.mp3
Honestly, on this one, I'm not even sure where to start. I've found several scripts that can look at file date or a specific numerical or date format in the filename, but none that can parse numbers from a filename and move/copy a file based on the numerical value. I'm hoping there is someone out there smarter than me that can point me in the right direction. Thanks for looking at my problem!
One script I've been playing with (from the scripting guy) looks at specific years in a filename:
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colFiles = objWMIService.ExecQuery _
(“ASSOCIATORS OF {Win32_Directory.Name=’C:\Test’} Where ” _
& “ResultClass = CIM_DataFile”)
Set objRegEx = CreateObject(“VBScript.RegExp”)
For Each objFile in colFiles
objRegEx.Global = True
objRegEx.Pattern = “\d{4}”
strSearchString = objFile.FileName
Set colMatches = objRegEx.Execute(strSearchString)
strYear = colMatches(0).Value
strNewFile = “C:\Test\” & strYear & “\” & objFile.FileName & _
“.” & objFile.Extension
objFile.Copy(strNewFile)
objFile.Delete
Next
...but I can't seem to make the leap to regular numbers and then take a lowest value...
You can use FileSystemObject to Work with Drives, Folders and Files.
Also i used GETNUM function to get number.
Try my way :
sFolder = "C:\Test\"
Set oFSO = CreateObject("Scripting.FileSystemObject")
For Each objFile in oFSO.GetFolder(sFolder).Files
Number=GETNUM(objFile.Name)
strNewFile = sFolder & Number & "\" & objFile.Name
If NOT (oFSO.FolderExists(sFolder & Number)) Then
oFSO.CreateFolder(sFolder & Number)
End If
oFSO.MoveFile objFile, strNewFile
Next
Function GETNUM(Str)
For i=1 To Len(Str)
if IsNumeric(Mid(Str,i,1)) Then
Num=Num&Mid(Str,i,1)
End if
Next
GETNUM=Num
End Function
For understanding the used code and how they work, open these sites and read all pages very carefully.
MoveFile method
Vbs Script to check if a folder exist
I currently have this code that will compare between two files only if each file has one column:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile1 = objFSO.OpenTextFile("C:\Users\Downloads\Define Kickouts\Metadata_Account.txt", ForReading)
strCurrentDevices = objFile1.ReadAll
objFile1.Close
Set objFile2 = objFSO.OpenTextFile("C:\Users\Downloads\Define Kickouts\DataFile_Account.txt", ForReading)
Do Until objFile2.AtEndOfStream
strAddress = objFile2.ReadLine
If InStr(strCurrentDevices, strAddress) = 0 Then
strNotCurrent = strNotCurrent & strAddress & vbCrLf
End If
Loop
objFile2.Close
Wscript.Echo "Addresses without current devices: " & vbCrLf & strNotCurrent
Set objFile3 = objFSO.CreateTextFile("C:\Users\Downloads\Define Kickouts\Differences.txt")
objFile3.WriteLine strNotCurrent
objFile3.Close
However, I'm trying to figure out a way to create the script where the user can define which columns in the date file to compare against the same set of metadata files.
For example, in the data file, if we want to compare Account, Entity, and Department members, in the script, we would type in columns 1, 4, 5 based on the position in the headers...
Account, Project, Practice, Entity, Department
GL1000,P5000,PP2000,USA,D120
GL2000,P6000,PP3000,CANADA,D220
Then, the script will compare 'always' against the first column in each metadata file...
Account.csv
First column sample values:
GL5000,blah,blah,blah
GL1000,blah,blah,blah
Entity.csv
First column sample values:
ASIA,blah,blah,blah
CANADA,blah,blah,blah
Department.csv
First column sample values:
D100,blah,blah,blah
D200,blah,blah,blah
The output file will have kick-outs from the data file that aren't in the metadata files for each column.
Account Kickout.txt
GL2000
Entity Kickout.txt
USA
Department Kickout.txt
D120
D220
Any help would be appreciated!
This is my code. And while it sort of works, it for some reason does not add every group in the list I have pasted in. I think my ordering of statements is totally off and causing this. But I just can't get every single entry in the array to add to a user.
On Error Resume Next
'AD Path to the user container
strinput = "testuser"
memberPath = "LDAP://CN=" & strinput & ",OU=Users - Employee,OU=ALL USERS,DC=mydomain,DC=mycompany,DC=org"
'paths for relevant OUs in AD
strSecgrppath = ",OU=Security Groups,DC=mydomain,DC=mycompany,DC=org"
strDisgrppath = ",OU=Distribution Groups,DC=mydomain,DC=mycompany,DC=org"
strMEsecpath = ",OU=Microsoft Exchange Security Groups,DC=mydomain,DC=mycompany,DC=org"
strPrntrgrppath = ",OU=Printer Groups,OU=Security Groups,DC=mydomain,DC=mycompany,DC=org"
'Input for entry of array variables. This where we copy paste the Groups
strGroups = inputbox("Enter exact Group names separated by commas.", "Enter exact Group names separated by commas.")
'splits the array and iterates through it, calling the subroutine with
'each specific AD path variable
'I paste in the groups like: "Employees, Admins, Volunteers, Serviceaccounts, etc.
strSEC = Split(strGroups, ", ")
limit = UBound(strSEC)
' Go through the Sec Groups OU
For i=0 To limit
Call iterategroups (strSecgrppath)
Next
'No need to explain, goes through the next group.
For i=0 To limit
Call iterategroups (strDisgrppath)
Next
'etc.
For i=0 To limit
Call iterategroups (strMEsecpath)
Next
'etc.
For i=0 To limit
Call iterategroups (strPrntrgrppath)
Next
'the sub for going through each OU
Sub iterategroups(groupparam)
' ADsPath to the Security group container
groupPath = "LDAP://mydomain.mycompany.org/CN=" & strSEC(i) & groupparam
' Set the Group object
Set group = GetObject(groupPath)
' Set the Member object
Set member = GetObject(memberPath)
' adds the member to the group
group.Add(member.ADsPath)
End Sub
So I figured out a much easier way to do this by cloning the memberof attribute for an existing user in AD, which was the purpose of this script to begin with.
'Create the AD object
Set objSysInfo = CreateObject("ADSystemInfo")
strinput = "testuser"
'Enter the display name of the user whose permissions need to be cloned.
strUserDN = inputbox("Enter Display Name of User to be cloned.")
'LDAP Path for the new user
memberPath = "LDAP://CN=" & strinput & ",OU=Users - Employee,OU=ALL USERS,DC=mydomain,DC=mycompany,DC=org"
'LDAP Path for the user to be cloned.
oldmemberPath = "LDAP://CN=" & strUserDN & ",OU=Users - Employee,OU=ALL USERS,DC=mydomain,DC=mycompany,DC=org"
'resume next to avoid error if new user belongs to the same group already.
on error resume next
'sets the object for the user to be cloned
Set objUser = GetObject(oldmemberPath)
'Pulls a list of items from the memberof attribute of the user to be cloned and adds it to an array
arrGroups = objUser.memberOf
'For each group in the array, add Groups for new user
For Each strGroup In arrGroups
' Set the Group object
Set group = GetObject("LDAP://mydomain.mycompany.org/" & strGroup)
' Set the Member object
Set member = GetObject(memberPath)
' adds the new user to the group
group.Add(member.ADsPath)
Next
Using VBScript, how can I list all WMI classes that have methods?
Run a SELECT schema query to get a list of all classes in a namespace, and then check each class's Methods_.Count:
strComputer = "."
strNamespace = "root\cimv2"
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\" & strNamespace)
Set colClasses = oWMI.ExecQuery("SELECT * FROM meta_class")
For Each oClass in colClasses
If oClass.Methods_.Count > 0 Then
WScript.Echo oClass.Path_.Class
End If
Next
You may want to limit the results to dynamic and static classes only, like WMI Code Creator does. To do this, add an additional check for the corresponding class qualifiers.
...
For Each oClass in colClasses
For Each oQualifier In oClass.Qualifiers_
strQualName = LCase(oQualifier.Name)
If strQualName = "dynamic" OR strQualName = "static" Then
If oClass.Methods_.Count > 0 Then
WScript.Echo oClass.Path_.Class
End If
End If
Next
Next
I also suggest that you read the WMI Scripting Primer: Part 2 article. It explains the WMI concepts and infrastructure in detail and with examples, and may already hold answers to your future questions. :)
I'm gettinga n error message in line 8 when I try to call out the script to stop when it finds teh attribute in the Web page: field in AD.
Set objSysInfo = CreateObject("ADSystemInfo")
strUserDN = objSysInfo.UserName
Set objUser = GetObject("LDAP://" & strUserDN)
strwWWHomePage = objItem.Get("wWWHomePage")
If wWWHomePage 6 Then
wscript.quit
Else
Set ppt = CreateObject("PowerPoint.Application")
ppt.Visible = True
ppt.Presentations.Open "\\abngan01\tracking\ppt.pptx"
End If
You have:
If wWWHomePage 6 Then
I'm assuming you want it to say:
If wWWHomePage = 6 Then
Since the missing "=" will cause an error, but since that code really doesn't do anything anyway, other than just abort the script, you could simplify your code by only taking action if that value is not set, for example:
If objItem.Get("wWWHomePage") <> 6 Then
Set ppt = CreateObject("PowerPoint.Application")
ppt.Visible = True
ppt.Presentations.Open "\\abngan01\tracking\ppt.pptx"
End If
I'm also assuming "6" is some sort of flag you've set yourself, you might want to use something a little more descriptive like "PPTSTATUS006", or something along those lines.