List users from specific groups - vbscript

Good morning all,
I am currentlycovering my line manager. And I need to modify an existing to VBScript, to pull users from specific groups in AD (Commercial, Finance, HR, IT, Marketing, Operations, and Property):
Const ForReading = 1,ForWriting = 2,ForAppending = 8
StartFilename = "AD groups.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(StartFilename,ForAppending, True)
strDomainName = inputbox("Enter Domain Name","AD Billing","")
Set objDomain = GetObject("WinNT://" & strDomainName)
For each objDomainObject in objDomain
If objDomainObject.class = "Group" Then
Set objGroup = GetObject("WinNT://"& strDomainName & "/" & objDomainObject.Name)
objTextFile.writeline("")
objTextFile.writeline("Domain: " & strDomainName & " Group: " & objDomainObject.Name)
objTextFile.writeline("")
Set objMemberList = objGroup.Members
For Each objGroupMember In objMemberList
Set objMember = objGroupMember
objTextFile.writeline ("Group member: " & objMember.Name)
Next
End If
Next
objTextFile.close
Any help is greatly appriciated
Kind regards
Justin

Just add another If after the If where you find out that it's a Group, but instead of comparing on the class, compare on the `Name.
So amending your original code it would be something like this:
Const ForReading = 1,ForWriting = 2,ForAppending = 8
StartFilename = "AD groups.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(StartFilename,ForAppending, True)
strDomainName = inputbox("Enter Domain Name","AD Billing","")
strGroupName = inputbox("Enter Group Name","AD Billing","")
Set objDomain = GetObject("WinNT://" & strDomainName)
For each objDomainObject in objDomain
If objDomainObject.class = "Group" Then
If objDomainObject.Name = strGroupName Then
Set objGroup = GetObject("WinNT://"& strDomainName & "/" & objDomainObject.Name)
objTextFile.writeline("")
objTextFile.writeline("Domain: " & strDomainName & " Group: " & objDomainObject.Name)
objTextFile.writeline("")
Set objMemberList = objGroup.Members
For Each objGroupMember In objMemberList
Set objMember = objGroupMember
objTextFile.writeline ("Group member: " & objMember.Name)
Next
End If
End If
Next
objTextFile.close
I assumed that you wanted to ask each time which group using a InputBox, otherwise you could hardcode those values in the If statement as
If objDomainObject.Name = "Commercial" Or objDomainObject.Name = "Finance" Or .... Then

You are missing this above the next statement (To reenumerate the objects after being in a container/OU.):
If objDomainObject.Class = "organizationalUnit" Or
objDomainObject.Class = "container" Then
enumMembers (objMember)
End If

Related

Split the output of GetNameSpace("MAPI") in VBscript

I'm learning VBscript to assist creating user forms in outlook. With this appointment form I'm attempting to create a pre-formatted email signed off with the name of the current user. I only want the output to be the current users first name. It is currently returning the full name.
How can I split the user name or get only the users first name?
Thanks in advance.
Sub commandbutton1_click()
Set MyApp = CreateObject("Outlook.Application")
Set MyItem = MyApp.CreateItem(0) 'olMailItem
set prop = item.userproperties.find("Mobile")
set currentuser = application.getNameSpace("MAPI").CurrentUser
Set prop1 = item.userProperties.find("Subject")
Set prop2 = item.userProperties.find("Location")
Set prop3 = item.userProperties.find("DateStart")
dteThen = dateAdd("h", -1, Now())
With MyItem
.To = prop & "#etxt.co.nz"
.Subject = ""
.Body = "Hi " & Subject & vbCrlf & vbCrlf & "This is a reminder about your meeting at " & Location & vbCrlf & vbCrlf & "Thanks" & currentUser
.DeferredDeliveryTime = DateStart + dteThen
End With
MyItem.Display
end sub
Fairly simple...
Sub commandbutton1_click()
Set MyApp = CreateObject("Outlook.Application")
Set MyItem = MyApp.CreateItem(0) 'olMailItem
set prop = item.userproperties.find("Mobile")
set currentuser = application.getNameSpace("MAPI").CurrentUser
Set prop1 = item.userProperties.find("Subject")
Set prop2 = item.userProperties.find("Location")
Set prop3 = item.userProperties.find("DateStart")
arrUserName = Split(currentUser, ",") 'Split the name using ","
strName = Trim(arrUserName(1)) 'Remove any space
dteThen = dateAdd("h", -1, Now())
With MyItem
.To = prop & "#etxt.co.nz"
.Subject = ""
.Body = "Hi " & Subject & vbCrlf & vbCrlf & "This is a reminder about your meeting at " & Location & vbCrlf & vbCrlf & "Thanks," & vbcrLF & strName 'use of strName
.DeferredDeliveryTime = DateStart + dteThen
End With
MyItem.Display
end sub

VBScript - Change Group Type

I am using the below VBscript to change group type of couple of groups to Security. I am getting an error "The server is unwilling to process the request" when executing objGroup.setinfo.
Appreciate if someone can help to resolve this.
Dim strOU, strGroup, objOU, objGroup
Dim strFile, objFile, objFSO
Const ADS_GROUP_TYPE_SECURITY_ENABLED = &H80000000
Const ForReading = 1
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
Const ADS_GROUP_TYPE_UNIVERSAL = &H8
strFile = "c:\Temp\GroupNames.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, ForReading)
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set objTrans = CreateObject("NameTranslate")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
strNetBIOSDomain = Left(strNetBIOSDomain, _
Len(strNetBIOSDomain) - 1)
Do Until objFile.AtEndOfStream
strNTName = Trim(objFile.ReadLine)
If (strNTName <> "") Then
On Error Resume Next
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strNTName
End If
' Use Get method to retrieve Distinguished Name.
strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)
wscript.echo strUSerDN
' Bind to user object in AD.
Set objGroup = GetObject("LDAP://servername
" & strUserDN)
objGroup.Put "groupType", ADS_GROUP_TYPE_SECURITY_ENABLED
objGroup.SetInfo
Loop
objFile.Close
You need to specify the group scope as well. Instead of just "ADS_GROUP_TYPE_SECURITY_ENABLED", you need "ADS_GROUP_TYPE_[type]_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED", where [type] is GLOBAL, LOCAL, or UNIVERSAL.

Find all photographs taken on a certain date

If have the following VBScript for recursively finding all the files in a set of folders. I simply found this on the web somewhere and can't take credit for it.
fileExtension = ".jpg"
folderPath = "C:\Pictures"
computerName = "."
arrFIL = Array()
If Right(folderPath,1) = "\" Then folderPath = Left(folderPath,Len(folderPath)-1)
Set wmiObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & computerName & "\root\cimv2")
Set folderObject = wmiObject.Get("Win32_Directory='" & folderPath & "'")
EnumFolders folderObject, wmiObject, arrFIL
strFIL = UBound(arrFIL) + 1 & " files found with extension '" & fileExtension & "':" & vbCrLf & vbCrLf
For intFIL = 0 To UBound(arrFIL)
Set objFile = objFSO.GetFile(arrFIL(intFIL))
strFIL = strFIL & arrFIL(intFIL) & vbCrLf
Next
WScript.Echo strFIL
Sub EnumFolders(folderObject, wmiObject, arrFIL)
On Error Resume Next
Dim objSD1
Dim objSD2
Dim objFI1
Dim objFI2
Set objSD1 = wmiObject.ExecQuery("Associators of {Win32_Directory.Name='" & fold erObject.Name & "'} Where AssocClass=Win32_SubDirectory ResultRole=PartComponent")
For Each objSD2 in objSD1
EnumFolders objSD2, wmiObject, arrFIL
Next
On Error Goto 0
Set objFI1 = wmiObject.ExecQuery("Associators of {Win32_Directory.Name='" & folderObject.Name & "'} Where ResultClass=CIM_DataFile")
For Each objFI2 in objFI1
If Right(objFI2.Name,Len(fileExtension)) = fileExtension Then
intFIL = UBound(arrFIL) + 1
ReDim Preserve arrFIL(intFIL)
arrFIL(intFIL) = objFI2.Name
End If
Next
End Sub
What I need to do is run this against a bunch of folders, within C:\Pictures, and have it return all files where the Date Taken property of the photo is the 23rd of the month. Is this possible? How would I achieve this?
Thanks
I'd use the Shell.Application object instead of WMI:
Const Name = 0
Const DateTaken = 12
folderPath = "C:\Pictures"
Set re = New RegExp
re.Pattern = "[^0-9:./ ]"
re.Global = True
Traverse CreateObject("Shell.Application").Namespace(folderPath)
Sub Traverse(fldr)
For Each obj In fldr.Items
If obj.IsFolder Then
Traverse obj.GetFolder
ElseIf LCase(obj.Type) = "jpeg image" Then
If Day(re.Replace(fldr.GetDetailsOf(obj, DateTaken), "")) = 23 Then
WScript.Echo fldr.GetDetailsOf(obj, Name)
End If
End If
Next
End Sub

Checking a users group memberships

I've been working quickly on a little script so that I can set and remove networks drives or create folders depending on a persons group membership, it doesn't seem to work and there are no error messages, could do with a second pair of eyes, I'd really appreciate it!
DIM CHS
SET CHS = CreateObject("Scripting.FileSystemObject")
SET CHSshell = CreateObject("WScript.Shell")
SET CHSnetwork = CreateObject("WScript.Network")
PRIVATE FUNCTION isMember( Group )
SET netCHS = CreateObject("WScript.Network")
Domain = netCHS.UserDomain
User = netCHS.UserName
isMember = false
SET userCHS = GetObject("WinNT://" & Domain & "/" & User & ",user")
FOR EACH Group in userCHS.Groups
IF (Group.Name = GroupName) THEN
isMember = true
EXIT FOR
END IF
NEXT
SET userCHS = NOTHING
SET netCHS = NOTHING
END FUNCTION
SET CHS = NOTHING
IF ( isMember("Domain Admins") = "True" ) THEN
CHSnetwork.RemoveNetworkDrive "z:"
WSript.Echo "CHSnetwork.UserName"
END IF
You call
isMember("Domain Admins")
The function
PRIVATE FUNCTION isMember( Group )
picks up the parameter in the name Group. But you (re/mis-)use Group in
FOR EACH Group in userCHS.Groups
to loop over the userCHS.Groups and in
IF (Group.Name = GroupName) THEN
to get the .Name to compare with GroupName. Where does GroupName come from?. Try to change the function's header to
PRIVATE FUNCTION isMember( GroupName )
and consider to use Option Explicit to avoid such mistakes.
This VBS script will show all groups the user belong to:
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim oNetwork: Set oNetwork = CreateObject("WScript.Network")
Dim sUserName: sUserName = oNetwork.UserDomain & "/" & oNetwork.UserName
sUserName = InputBox("Windows User Name","Enter Windows User Name", sUserName)
If sUserName <> "" Then
GetGroups
End If
Sub GetGroups
Const ADS_READONLY_SERVER = 4
Dim oGroup, oUser
Dim oShell: Set oShell = Wscript.CreateObject("WScript.Shell")
Dim sFolderPath: sFolderPath = GetFolderPath()
Dim oNS: Set oNS = GetObject("WinNT:")
Dim oList: Set oList = CreateObject("System.Collections.ArrayList")
Dim sFilePath: sFilePath = sFolderPath & "\" & Replace(Replace(sUserName,"\","-"),"/","-") & "_groups.txt"
Set oUser = oNS.OpenDSObject("WinNT://" & sUserName, "", "", ADS_READONLY_SERVER)
For Each oGroup In oUser.groups
oList.Add oGroup.Name
Next
oList.Sort()
Dim oLog: Set oLog = fso.CreateTextFile(sFilePath, True)
For Each sItem in oList
oLog.Write sItem & vbCrLf
Next
oLog.Close
oShell.Run sFilePath
End Sub
Function GetFolderPath()
Dim oFile 'As Scripting.File
Set oFile = fso.GetFile(WScript.ScriptFullName)
GetFolderPath = oFile.ParentFolder
End Function

Active Directory PSO fine grained passwords msDS-MaximumPasswordAge

Looking how to create a vbscript to pull the maximum number of days a PSO policy has set. It comes back as a value of ... and I do not know how to get the real value that was set.
This is what I have so far:
Option Explicit
Const ADS_UF_PASSWD_CANT_CHANGE = &H40
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
Dim strFilePath, objFSO, objFile, adoConnection, adoCommand, objCDOConf
Dim objRootDSE, strDNSDomain, strFilter, strQuery, adoRecordset, objMaxPwdAge
Dim strDN, objShell, lngBiasKey, lngBias, blnPwdExpire, strDept, strAdd
Dim objDate, dtmPwdLastSet, lngFlag, k, address, objAdd, objMessage
' Check for required arguments.
If (Wscript.Arguments.Count < 1) Then
Wscript.Echo "Arguments <FileName> required. For example:" & vbCrLf _
& "cscript PwdLastChanged.vbs c:\MyFolder\UserList.txt"
Wscript.Quit(0)
End If
strFilePath = Wscript.Arguments(0)
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Open the file for write access.
On Error Resume Next
Set objFile = objFSO.OpenTextFile(strFilePath, 2, True, 0)
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "File " & strFilePath & " cannot be opened"
Wscript.Quit(1)
End If
On Error GoTo 0
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Use ADO to search the domain for all users.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOOBject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
' Determine the DNS domain from the RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
' Filter to retrieve all user objects.
strFilter = "(&(objectClass=msDS-PasswordSettings))"
' Filter to retrieve all computer objects.
strQuery = "<LDAP://CN=PSO-Information Systems,CN=Password Settings Container,CN=System,DC=yrmc,DC=org>;" _
& ";cn,msDS-LockoutDuration,msDS-MaximumPasswordAge,msDS-
PasswordSettingsPrecedence;subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
objFile.WriteLine adoRecordset.Fields("cn").Value
adoRecordset.MoveNext
Loop
adoRecordset.Close
I can get a value for cn and even msDS-PasswordSettingsPrecedence but not for msDS-MaximumPasswordAge. Any help would be appreciated.
This is at best a partial answer but I did some searching and I believe you will need one or more of the following:
DSGet/DSQuery
LDIFDE to manage PSO's.
Quest's "Free PowerShell Commands for Active Directory"
Using Quest's free tools, you might find this link handy
Put square brackets around our Active Directory attribute name:
See the blog post "How can I retrieve the value of an active directory attribute that has a hyphen in its name" for more.
you have to find UsersPSO location in your AD like that
domainLookupString = ""CN=UsersPSO,CN=Password Settings Container,CN=System,DC=COMPAY,DC=ORG";
then run the ldap query
ldapFilterString = "(&(objectClass=msDS-PasswordSettings))";
at the end, get the ldap attribute with the Maximum Password Age of the current PSO policy
"msDS-MaximumPasswordAge"

Resources