My script is probably way overkill, but it’s my generic group membership management script that I’ve used from several different tools including BigFix. You can put this entire content into a createfile, rename it to localgroup.vbs, then call it via cscript.
The script depends on WMI, and if you are adding Domain members it depends on the ADSI COM interface for vbscript (which should be present by default on Win2000 or higher); if used in a non-domain environment ensure you specify the Member as “.\username” to avoid trying to lookup the domain name.
createfile until EOF_EOF_EOF
strUsage="Usage: cscript " & WScript.ScriptFullName & " [/GROUP:<groupname>] [/member:<member>] [/operation:<add|remove|check|create|delete]> [/DEBUG]" _
& VbCrLf & "Group must be a group on this computer" _
& VbCrLf & "Member assumes current machine domain; override with MYDOMAIN\user or ""NT AUTHORITY\user""" _
& VbCrLf & "Success or already correct add/delete returns 0; successful check returns 0" _
& VbCrLf & vbTab & "add/remove/check: add,remove, or check MEMBER from GROUP" _
& VbCrLf & vbTab & "create/delete: Create or delete the GROUP as a whole" _
& VbCrLf & " Some member definitions are senstive. There are distinctions that may require forms like:" _
& VbCrLf & vbTab & " BUILTIN\Users ""NT AUTHORITY\SYSTEM"" DOMAIN\username .\groupname" _
& VbCrLf & "/DEBUG: Show extra debugging output" _
& VbCrLf & VbCrLf _
& "Examples:" _
& VbCrLf & vbTab & " cscript //nologo " & WScript.ScriptFullName & " /Group:Administrators /member:User1 /operation:add" _
& VbCrLf & vbTab & " cscript //nologo " & WScript.ScriptFullName & " /Group:Administrators /member:.\User1 /operation:add" _
& VbCrLf & vbTab & " cscript //nologo " & WScript.ScriptFullName & " /Group:Group2 /member:MYDOMAIN\User1 /operation:add" _
& VbCrLf & vbTab & " cscript //nologo " & WScript.ScriptFullName & " /Group:Group2 /member:""NT AUTHORITY\NETWORK SERVICE"" /operation:add" _
& VbCrLf & vbTab & " cscript //nologo " & WScript.ScriptFullName & " /Group:Users /member:S-1-5-21-123456789-123456789-123456789 /operation:remove"
If WScript.Arguments.Named.exists("?") Then
Die strUsage,1
End If
blnDebug=WScript.Arguments.Named.Exists("Debug")
DebugMsg "Debug output enabled"
'Define Variables
Dim strOperation,strGroup,strMember,blnMemberRequired,strUsage,Mydomain,oNet,sComputer,vbCaseInsensitive,colAccounts,strGroupPath
Dim oLocalGroup, tmpDomain
vbCaseInsensitive=1
strOperation=Null
strGroup=Null
strMember=Null
blnMemberRequired=False
' Implicit argument handlers - "group" "member" "operation"
If WScript.Arguments.Unnamed.Count > 0 Then strGroup=WScript.Arguments.Unnamed(0)
If WScript.Arguments.Unnamed.Count > 1 Then strMember=WScript.Arguments.Unnamed(1)
If WScript.Arguments.Unnamed.Count > 2 Then strOperation=WScript.Arguments.Unnamed(2)
' Implicit argument handlers - /add, /remove, /check, /create, /delete
If WScript.Arguments.Named.exists("add") Then strOperation="add"
If WScript.Arguments.Named.exists("remove") Then strOperation="remove"
If WScript.Arguments.Named.exists("check") Then strOperation="check"
If WScript.Arguments.Named.exists("create") Then strOperation="create"
If WScript.Arguments.Named.exists("delete") Then strOperation="delete"
If WScript.Arguments.Named.exists("list") Then strOperation="list"
' Explicit argument handlers
If WScript.Arguments.Named.Exists("Operation") Then strOperation=WScript.Arguments.Named("Operation")
If WScript.Arguments.Named.Exists("Group") Then strGroup=WScript.Arguments.Named("Group")
If WScript.Arguments.Named.Exists("Member") Then strMember=WScript.Arguments.Named("Member")
If isNull(strOperation) Then Die strUsage,1
If isNull(strGroup) Then Die strUsage,1
If StrComp(strOperation,"add",vbCaseInsensitive)=0 Then blnMemberRequired=True
If StrComp(strOperation,"remove",vbCaseInsensitive)=0 Then blnMemberRequired=True
If StrComp(strOperation,"check",vbCaseInsensitive)=0 Then blnMemberRequired=True
DebugMsg "strGroup is " & strGroup
DebugMsg "strMember is " & strMember
DebugMsg "strOperation is " & strOperation
On Error Resume Next
DebugMsg "Connecting to WScript.Network object"
Set oNet = WScript.CreateObject("WScript.Network")
If Not IsObject(oNet) Then Set oNet=Nothing
If oNet Is Nothing Then Die "Error:Could not bind to Network object, cannot continue",1
sComputer = oNet.ComputerName
DebugMsg "sComputer is " & sComputer
DebugMsg "Connecting to WinNT://" & sComputer
Set colAccounts = GetObject("WinNT://" & sComputer)
If Err.Number<>0 Then Die "Could not bind to accounts using WinNT://" & sComputer,2
If blnMemberRequired Then
DebugMsg "...this operation requires a Member defined"
DebugMsg "starting with strMember " & strMember
' Needs to have sComputer defined
If isNull(strMember) Then Die strUsage,1
' Parse strMember into a WMI Path String
DebugMsg "Determining member domain name"
'strMember MAY include DOMAIN\
DebugMsg "Comparing to WinNT: " & strcomp(Left(strMember,8),"WinNT://",1)
if (strcomp(Left(strMember,8),"WinNT://",1) = 0) Then
' No need to manipulate strMember at all
' This allows for things like SIDs using WinNT://S-1-5-21-xxxxx
DebugMsg "Member supplied in form WinNT://, no manipulation necessary"
myDomain=""
elseif (strcomp(Left(strMember,9),"S-1-5-21-",1) = 0) Then
' This allows for things like SIDs using WinNT://S-1-5-21-xxxxx
DebugMsg "Member supplied in form of a SID, prepending WinNT://"
myDomain=""
strMember="WinNT://" & strMember
Else
If InStr(strMember,"\") Then
DebugMsg "Determining domain name based on parameter entry"
Mydomain=Left(strMember,InStr(strMember,"\")-1)
strMember=Mid(strMember,InStr(strMember,"\")+1)
Else
' If the machine is not a member of an AD domain, GetDomainName will fail
DebugMsg "Domain of member not specified, assuming computer domain"
On Error Resume Next
Mydomain=GetDomainName("NT4")
If Err.number<>0 Then
Die "Error looking up domain name; try supplying one in the form DOMAIN\user",2
End If
End If
' If the domain is specified as ".\" or "COMPUTERNAME\", then *try* to convert it to fully-qualified name form
' i.e. WinNT://DOMAIN/computername/username
' - That's needed for group membership comparisons later as it's the form in which Membership is tracked
' If we are NOT on a domain, this will fail, hopefully silently
If (Mydomain=".") Or (StrComp(Mydomain,sComputer,vbCaseInsensitive)=0) Then
On Error Resume Next
tmpDomain=GetDomainName("NT4")
If Err.number=0 Then
Mydomain=tmpDomain & "/" & sComputer
Else
Err.Clear
End If
End If
' Need to have faith in the user's selection for member; can't bind to dynamic members like "NT AUTHORITY\Interactive"
strMember="WinNT://" & Mydomain & "/" & strMember
end if
DebugMsg "Member is " & strMember
End If
On Error goto 0
' Convert Group into a WMI Path String
strGroupPath="WinNT://" & sComputer & "/" & strGroup
DebugMsg "Group path is " & strGroupPath
' Attempt to bind to the Local Group; it may not exist (yet)
On Error Resume Next
Set oLocalGroup = GetObject(strGroupPath & ",group")
If Err.number<>0 Then Set oLocalgroup = Nothing
Err.Clear
On Error Resume Next
Select Case lcase(strOperation)
Case "list"
DebugMsg "Attempting to list members of local group"
if oLocalGroup Is Nothing Then
Die "Could not bind to local group " & strGroup & " : " _
& err.number & " : " & Err.Description, 2
end if
set oMembers=oLocalGroup.Members
for each Member in oMembers
wscript.echo Member.Name & ";" & Member.Class & ";" & Member.ADSPath
Next
Case "add"
DebugMsg "Attempting to add member to local group"
if oLocalGroup Is Nothing Then
DebugMsg "Local group does not exist, attempting to create it"
Set oLocalGroup = CreateGroup(strGroup,colAccounts)
End If
If Err.number<>0 Then
Die "Could not bind to or create group " & strGroup & " : " _
& Err.Number & " : " & Err.Description, 2
End If
DebugMsg "Bound to local group, checking existing membership"
if oLocalGroup.IsMember(strMember) Then
Die "True: " & strMember & " is already in group " & oLocalGroup.adsPath, 0
Else ' Group is bound, but user is not a member of it
On Error Resume Next
oLocalGroup.Add(strMember)
If Err.number<>0 Then
Die "Error: failed to add " & strMember & " to group " & oLocalGroup.adsPath & " : " _
& Err.Number & " : " & Err.Description, 2
Else
Die "Success: added " & strMember & " to group " & oLocalGroup.adsPath, 0
End if
End If
Case "remove"
If oLocalGroup Is Nothing Then Die "Success: local group " & strGroup & " does not exist",0
If oLocalGroup.IsMember(strMember) Then
On Error Resume next
oLocalGroup.Remove(strMember)
If Err.number<>0 Then
Die "Error: failed to delete " & strMember & " from group " & oLocalGroup.adsPath & " : " _
& Err.Number & " : " & Err.Description, 2
Else
Die "Success: deleted " & strMember & " from group " & oLocalGroup.adsPath, 0
End if
Else
Die "Success: " & strMember & " is already not a member of " & oLocalGroup.adsPath, 0
End If
Case "check"
If oLocalGroup Is Nothing Then Die "False: Local group " & strGroup & " does not exist",1
if oLocalGroup.IsMember(strMember) Then
Die "True: " & strMember & " is in group " & oLocalGroup.adsPath, 0
Else
Die "False: " & strMember & " is not in group " & oLocalGroup.adsPath, 1
End If
Case "create"
On Error Resume Next
If Not oLocalGroup Is Nothing Then Die "Success: local group " & strGroup & " already exists",0
' Set oLocalGroup = colAccounts.Create("group", strGroup)
' oLocalGroup.SetInfo
Set oLocalGroup=CreateGroup(strGroup,colAccounts)
If Err.number=0 Then
Die "Success: " & strGroup & " created",0
Else
Die "Error: Could not create group " & strGroup,2
End If
Case "delete"
On Error Resume Next
If oLocalGroup Is Nothing Then Die "Success: group " & oLocalGroup & " already does not exist",0
colAccounts.Delete "group",strGroup
If Err.number=0 Then
Die "Success: " & strGroup & " deleted",0
Else
Die "Error: Could not delete group " & strGroup,2
End If
Case Else
Die "Invalid OPERATION specified, cannot continue",1
End Select
Function CreateGroup(strGroup,colAccounts)
On Error Resume Next
DebugMsg "Entered CreateGroup()"
If strGroup="" Then
DebugMsg "CreateGroup: strGroup is blank"
Exit Function
End If
If Not IsObject(colAccounts) Then
DebugMsg "CreateGroup: colAccounts is not an object"
Exit Function
End If
DebugMsg "CreateGroup: Creating group " & strGroup
Set CreateGroup = colAccounts.Create("group", strGroup)
If Err.number<>0 Then
DebugMsg "CreateGroup:Could not bind to or create group " & strGroup & " : " _
& Err.Number & " : " & Err.Description
End If
CreateGroup.SetInfo
If Err.number<>0 Then
DebugMsg "CreateGroup:Could not SetInfo on new group " & strGroup & " : " _
& Err.Number & " : " & Err.Description
End If
End Function
Function Die (strString, iErrorCode)
WScript.Echo strString
WScript.Quit iErrorCode
End Function
Function GetDomainName(strType)
' NameTranslate constants
Const ADS_NAME_TYPE_1779 = 1
Const ADS_NAME_TYPE_CANONICAL = 2
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_DISPLAY = 4
Const ADS_NAME_TYPE_DOMAIN_SIMPLE = 5
Const ADS_NAME_TYPE_ENTERPRISE_SIMPLE = 6
Const ADS_NAME_TYPE_GUID = 7
Const ADS_NAME_TYPE_UNKNOWN = 8
Const ADS_NAME_TYPE_USER_PRINCIPAL_NAME = 9
Const ADS_NAME_TYPE_CANONICAL_EX = 10
Const ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME = 11
Const ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME = 12
Const ADS_NAME_INITTYPE_GC = 3
Dim strName
set objRootDSE=GetObject("LDAP://RootDSE")
defaultNC=objRootDSE.Get("defaultNamingContext")
Set objTrans=CreateObject("NameTranslate")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_1779, defaultNC
Select Case UCASE(strType)
Case "DNS","ADS_NAME_TYPE_CANONICAL_EX"
strName=objTrans.Get(ADS_NAME_TYPE_CANONICAL_EX)
strName=Left(strName,Len(strName)-1)
Case "LDAP","DN"
strName=defaultNC
Case "GUID"
strName=objTrans.Get(ADS_NAME_TYPE_GUID)
Case "NETBIOS","NT4","NT"
strName=objTrans.Get(ADS_NAME_TYPE_NT4)
strName=Left(strName, Len(strName) -1)
Case Else
On Error Resume Next
For i=1 To 12
WScript.Echo i & " """ & objTrans.Get(i) & """"
strName=strName & i & ":" & objTrans.Get(i)
Next
On Error goto 0
End Select
GetDomainName=strName
End Function
Function DebugMsg(strString)
If blnDebug Then
If IsObject(WScript.StdErr) Then
WScript.StdErr.WriteLine strString
Else
WScript.Echo strString
End If
End If
End Function
EOF_EOF_EOF
delete localgroup.vbs
move __createfile localgroup.vbs
waithidden cscript //nologo localgroup.vbs /group:Administrators /member:"MYDOMAIN\account_with_a_really_really_long_name" /operation:remove