About the Author

Source Code

Important Note:
This script has not been checked by Spiceworks. Please understand the risks before using it.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

'---- Start Global Objects ----'These objects and constants help to speed-up subsequent'searches. They need to be defined in your script before'you use the functions (eg. at the top of the script)'Constants for NameTranslateConstADS_NAME_INITTYPE_GC=3ConstADS_NAME_TYPE_NT4=3ConstADS_NAME_TYPE_1779=1'Network and NameTranslate are defined here to stop'memory and time from being wasted redefining them'over and over each time the functions are called.DimoNetworkSetoNetwork=WScript.CreateObject("WScript.Network")DimoNameTranslateSetoNameTranslate=CreateObject("NameTranslate")'This Dictionary is defined as global so it can store'all of the results from each group search. This'allows subsequent searches to run much faster.dimoInGroupsSetoInGroups=WScript.CreateObject("Scripting.Dictionary")oInGroups.CompareMode=vbTextCompare'---- End Global Objects ----'---- Start Main Script ----ifInGroup("TestGroup")=falsethenWScript.echo"False"elseWScript.echo"True"endif'----End Main Script ----'---- Start Functions ----'This is the search starter function. It gets the'objects needed to do the search, starts the search'and returns the result.PrivateFunctionInGroup(ByValsGroupName)onerrorresumenextDimoGroupdimoUserdimsLDAPerr.clear'This block gets the full LDAP name from the much'simpler WINNT name. 'First the group LDAP.oNameTranslate.InitADS_NAME_INITTYPE_GC,""oNameTranslate.SetADS_NAME_TYPE_NT4,GetDomainName()&"\"&sGroupNamesLDAP=oNameTranslate.Get(ADS_NAME_TYPE_1779)sLDAP=Replace(sLDAP,"/","\/")'Now get the group object from the LDAP name.SetoGroup=GetObject("LDAP://"&sLDAP)'Now get the user LDAP from the WINNT name.oNameTranslate.InitADS_NAME_INITTYPE_GC,""oNameTranslate.SetADS_NAME_TYPE_NT4,GetDomainName()&"\"&GetUserName()sLDAP=oNameTranslate.Get(ADS_NAME_TYPE_1779)sLDAP=Replace(sLDAP,"/","\/")'now get the user object from the LDAP namesetoUser=GetObject("LDAP://"&sLDAP)'Start the search and return the results. ifEnumGroup(oGroup,oUser,True)=truethenInGroup=trueelseInGroup=falseendif'If any errors occurred above, auto fail the result.iferr.number<>0thenInGroup=falseendifEndFunction'This is the search function. It takes the group'object and the user object and searches through'nested groups to find if the user is a member of'the group.PrivateFunctionEnumGroup(byrefoGroup,byrefoUser,byrefbRecord)onerrorresumenextdimoSubGroupdimbTemp'First we check if the group membership has'already been found and returned the stored'result. 'If bRecord is given as false then skip the 'stored values and do a full search.ifbRecord=TruethenIf(oInGroups.Exists(lcase(oGroup.Name))=True)Thenif(oInGroups.Item(lcase(oGroup.Name))=True)ThenEnumGroup=TrueelseEnumGroup=falseendifexitFunctionendifendif'Next we check if the user is a direct member of'the group or if the user’s primary group is set'to the group. 'If true for ether, we can skip the longer sub 'searches.err.clearbTemp=oGroup.IsMember(oUser.ADsPath)ifbTemptheniferr.number<>0thenbTemp=falseelsebTemp=trueendififbRecord=TruethenoInGroups.addlcase(oGroup.Name),bTempEnumGroup=bTempexitfunctionelseerr.clearoGroup.GetInfoExArray("PrimaryGroupToken"),0ifoUser.PrimaryGroupID=oGroup.PrimaryGroupTokentheniferr.number<>0thenbTemp=falseelsebTemp=trueendififbRecord=TruethenoInGroups.addlcase(oGroup.Name),bTempEnumGroup=bTempexitfunctionendifendif'Lastly if we haven’t found a match yet we do 'subgroup searches.err.clearForEachoSubGroupInoGroup.Membersiflcase(oSubGroup.class)="group"thenifEnumGroup(oSubGroup,oUser,bRecord)=truetheniferr.number<>0thenbTemp=falseelsebTemp=trueendififbRecord=TruethenoInGroups.addlcase(oGroup.Name),bTempEnumGroup=bTempexitfunctionendifendifNextifbRecord=TruethenoInGroups.addlcase(oGroup.Name),FalseEnumGroup=falseEndFunction'This function gets the WINNT version of the Domain'name for the current logged on userPrivateFunctionGetDomainName()OnErrorResumeNextdimtemptemp=""temp=lcase(oNetwork.UserDomain)GetDomainName=tempEndFunction'This function gets the users WINNT usernamePrivateFunctionGetUserName()OnErrorResumeNextdimtemptemp=""temp=lcase(oNetwork.UserName)GetUserName=tempEndFunction