Files

403 lines
12 KiB
XML

<job id="ZTIGroups">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript">
' // ***************************************************************************
' //
' // Copyright (c) Microsoft Corporation. All rights reserved.
' //
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File: ZTIGroups.wsf
' //
' // Version: 6.3.8456.1000
' //
' // Purpose: Capture and restore local group membership
' //
' // Usage: cscript ZTIGroups.wsf [/capture] [/restore]
' //
' // ***************************************************************************
Option Explicit
RunNewInstance
'//----------------------------------------------------------------------------
'// Global Constants
'//----------------------------------------------------------------------------
'// No global constants
'//----------------------------------------------------------------------------
'// Main Class
'//----------------------------------------------------------------------------
Class ZTIGroups
'//------------------------------------------------------------------------
'// Class variable declarations
'//------------------------------------------------------------------------
Public iRetVal
'//------------------------------------------------------------------------
'// Constructor to initialize needed global objects
'//------------------------------------------------------------------------
Private Sub Class_Initialize
End Sub
'//------------------------------------------------------------------------
'// Main routine
'//------------------------------------------------------------------------
Function Main
' Local Variables
Dim oGroupList
Dim oGroup
Dim oGroups
Dim sGroup
iRetVal = Success
'//--------------------------------------------------------------------
'// See what we need to do
'//--------------------------------------------------------------------
' Get the list of groups (if it exists)
Set oGroups = oEnvironment.ListItem("Groups")
' Find out what we need to do.
If oUtility.Arguments.Exists("capture") then
oLogging.CreateEntry "====== Capturing Groups ======", LogTypeInfo
' Figure out if we need to capture groups, or if we need to build the list of groups to capture.
Select Case UCase(oEnvironment.Item("CaptureGroups"))
Case "NO"
oLogging.CreateEntry "Group capturing bypassed by CaptureGroups=NO", LogTypeInfo
Main = Success
Exit Function
Case "ALL"
Set oGroupList = GetObject("WinNT://.")
oGroupList.Filter = Array("group")
For each oGroup in oGroupList
If not oGroups.Exists(oGroup.Name) and not oGroups.Exists(oGroup.Name & "," & oGroup.Description) then
oLogging.CreateEntry "Adding " & oGroup.Name & " to the list of groups to capture.", LogTypeInfo
oGroups.Add oGroup.Name & "," & oGroup.Description, ""
End if
Next
End Select
If oGroups.Count = 0 then
oLogging.CreateEntry "Adding ""Administrators"" to the list of groups to capture.", LogTypeInfo
oGroups.Add "Administrators", ""
oLogging.CreateEntry "Adding ""Power Users"" to the list of groups to capture.", LogTypeInfo
oGroups.Add "Power Users", ""
End if
' Perform the capture of each group
For each sGroup in oGroups.Keys
CaptureGroup GetGroupName(sGroup)
Next
' Persist the list of groups
Set oEnvironment.ListItem("Groups") = oGroups
ElseIf oUtility.Arguments.Exists("restore") then
oLogging.CreateEntry "====== Restoring Groups ======", LogTypeInfo
If oGroups.Count = 0 then
oLogging.CreateEntry "Adding ""Administrators"" to the list of groups to restore.", LogTypeInfo
oGroups.Add "Administrators",""
oLogging.CreateEntry "Adding ""Power Users"" to the list of groups to restore.", LogTypeInfo
oGroups.Add "Power Users", ""
End if
For each sGroup in oGroups.Keys
If not IsGroupPresent ( sGroup ) then
CreateGroup sGroup
End if
PopulateGroup GetGroupName(sGroup)
Next
Else
oLogging.CreateEntry "No valid command line option was specified", LogTypeError
End if
oLogging.CreateEntry oUtility.ScriptName & " COMPLETED. Return Value = " & iRetVal, LogTypeInfo
Main = iRetval
' All done
End Function
'//---------------------------------------------------------------------------
'// Function: CaptureGroup()
'// Purpose: Captures the current members of the specified group
'//---------------------------------------------------------------------------
Function CaptureGroup(sGroup)
Dim oGroup, oMember, sName, arrParts
Dim dicMembers
Dim sTrimmedGroup
Dim sTranslated
oLogging.CreateEntry "------ Capturing Group " & sGroup & " ------", LogTypeInfo
' See if we can translate the group name to a localized value
sTranslated = TranslateLocalGroup(sGroup)
If sTranslated <> sGroup then
oLogging.CreateEntry "Membership of the localized " & sTranslated & " group will be captured.", LogTypeInfo
End if
' See if we have an object to hold the group membership. If not, create one.
sTrimmedGroup = Trim(sGroup)
While Instr(sTrimmedGroup, " ") > 0
sTrimmedGroup = Left(sTrimmedGroup, Instr(sTrimmedGroup, " ")-1) & Mid(sTrimmedGroup, Instr(sTrimmedGroup, " ")+1)
WEnd
Set dicMembers = oEnvironment.ListItem(sTrimmedGroup)
oLogging.CreateEntry "Members of group " & sGroup & " will be stored in property " & sTrimmedGroup, LogTypeInfo
' Get the group via ADSI
On Error Resume Next
Set oGroup = GetObject("WinNT://./" & sTranslated & ",group")
If Err then
oLogging.CreateEntry "Unable to retrieve members of " & sTranslated & " group: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
CaptureGroup = Failure
EXIT FUNCTION
End if
' Process each of the members
For each oMember in oGroup.Members
arrParts = Split(Mid(oMember.ADSPath,9),"/")
If UBound(arrParts) = 1 then
sName = arrParts(0) & "\" & arrParts(1)
Else
sName = oMember.Name
End if
oLogging.CreateEntry "Found " & sGroup & " member " & sName, LogTypeInfo
If not dicMembers.Exists(sName) then
dicMembers.Add sName, ""
End if
Next
' Persist the member list
Set oEnvironment.ListItem(sTrimmedGroup) = dicMembers
oLogging.CreateEntry "Finished capturing membership of the """ & sTranslated & """ group.", LogTypeInfo
End Function
'//--------------------------------------------------------------------------------------------------
'// Function: PopulateGroup()
'// Purpose: Instructs SMS to insert specified accounts or groups into the Administrators group.
'//--------------------------------------------------------------------------------------------------
Function PopulateGroup(sGroup)
Dim sElement, oGroup, sTmp, re
Dim dicAdditions
Dim sTrimmedGroup
Dim sTranslated
Set re = new regexp
re.IgnoreCase = True
re.Global = True
oLogging.CreateEntry "------ Populating Group " & sGroup & " ------", LogTypeInfo
PopulateGroup = Success
' See if we can translate the group name to a localized value
sTranslated = TranslateLocalGroup(sGroup)
If sTranslated <> sGroup then
oLogging.CreateEntry "Membership of the localized " & sTranslated & " group will be restored.", LogTypeInfo
End if
' Make sure we need to do something
sTrimmedGroup = Trim(sGroup)
While Instr(sTrimmedGroup, " ") > 0
sTrimmedGroup = Left(sTrimmedGroup, Instr(sTrimmedGroup, " ")-1) & Mid(sTrimmedGroup, Instr(sTrimmedGroup, " ")+1)
WEnd
Set dicAdditions = oEnvironment.ListItem(sTrimmedGroup)
oLogging.CreateEntry "Number of members in property " & sTrimmedGroup & " to restore to group " & sGroup & ": " & dicAdditions.Count, LogTypeInfo
If dicAdditions.Count = 0 then
oLogging.CreateEntry "No groups or users to add to the """ & sGroup & """ group were specified.", LogTypeInfo
Exit Function
End if
' Get the group via ADSI
Set oGroup = GetObject("WinNT://./" & sTranslated & ",group")
' Try to add each specified group or user
On Error Resume Next
For each sElement in dicAdditions.Keys
re.Pattern = "\\"
sTmp = re.Replace(sElement,"/")
oGroup.Add "WinNT://" & sTmp
If Err.Number = -2147023518 then
oLogging.CreateEntry "Group or user '" & sElement & "' is already a member of the group.", LogTypeInfo
ElseIf Err.Number = -2147023509 then
oLogging.CreateEntry "Group or user '" & sElement & "' could not be added because it does not exist (possibly an obsolete local account).", LogTypeInfo
ElseIf Err then
oLogging.CreateEntry "WARNING - Unable to add group or user '" & sElement & "' to the group: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
Else
oLogging.CreateEntry "Successfully added group or user '" & sElement & "' to the group.", LogTypeInfo
End if
Next
On Error Goto 0
Err.Clear
oLogging.CreateEntry "Finished adding groups and users to the """ & sTranslated & """ group.", LogTypeInfo
End Function
'//---------------------------------------------------------------------------
'// Function: TranslateLocalGroup()
'// Purpose: Converts an English group name to the appropriate localized
'// or renamed value.
'//---------------------------------------------------------------------------
Function TranslateLocalGroup(sGroupName)
Dim sSid, re, oGroups, oGroup
' Fallback: return the passed-in group name so we don't return blank
TranslateLocalGroup = sGroupName
' Check to make sure WMI is available. If not, we can't translate the group
If (objWMI is Nothing) then
oLogging.CreateEntry "Warning: Unable to translate local groups because WMI is unavailable. Defaulting to untranslated name.", LogTypeWarning
Exit Function
End if
' Well-known local groups
Select Case sGroupName
Case "Administrators"
sSid = "^S-1-5-32-544$"
Case "Users"
sSid = "^S-1-5-32-545$"
Case "Guests"
sSid = "^S-1-5-32-546$"
Case "Power Users"
sSid = "^S-1-5-32-547$"
Case Else
oLogging.CreateEntry "Unable to translate local group name " & sGroupName & " because the SID is not known. Assuming no translation is required.", LogTypeInfo
Exit Function
End Select
' Look at all local groups until a match is found
Set re = New RegExp ' Create regular expression.
re.IgnoreCase = False ' Set case sensitivity.
Set oGroups = objWMI.ExecQuery("select * from Win32_Group where Domain = '" & oEnvironment.Item("Hostname") & "' or Domain = 'BUILTIN'")
For each oGroup in oGroups
re.Pattern = sSid
If re.Test(oGroup.SID) then
TranslateLocalGroup = oGroup.Name
Exit Function
End if
Next
oLogging.CreateEntry "Unable to translate local group name '" & sGroupName & "' because it wasn't found in WMI. Assuming the name does not require translation (or the group does not exist).", LogTypeInfo
End Function
Function CreateGroup ( sGroup )
' Where sGroup is a comma delimited string representing the Group Name and the Group Description.
Dim oWinNT
Dim oGroup
Set oWinNT = GetObject("WinNT://.")
oLogging.CreateEntry "Adding Group [" & sGroup & "] to the system.", LogTypeInfo
Set oGroup = oWinNT.Create("group", GetGroupName( sGroup ))
oGroup.SetInfo
If instr(1, sGroup, ",", vbTextCompare ) <> 0 then
oGroup.Description = mid( sGroup, instr(1, sGroup, ",", vbTextCompare ) + 1 )
oGroup.SetInfo
End if
End function
Function GetGroupName( sGroup )
' Where sGroup is a comma delimited string representing the Group Name and the Group Description.
If instr(1, sGroup, ",", vbTextCompare ) <> 0 then
GetGroupName = left( sGroup, instr(1, sGroup, ",", vbTextCompare ) - 1 )
Else
GetGroupName = sGroup
End if
End function
Function IsGroupPresent ( sGroup )
Dim oGroupList
Dim oGroup
Dim sGroupName
IsGroupPresent = false
sGroupName = trim(GetGroupName( sGroup ))
Set oGroupList = GetObject("WinNT://.")
oGroupList.Filter = Array("group")
For each oGroup in oGroupList
If trim(ucase(oGroup.Name)) = ucase(sGroupName) then
IsGroupPresent = true
exit function
ElseIf trim(ucase(oGroup.Name)) = ucase(TranslateLocalGroup(sGroupName)) then
IsGroupPresent = true
exit function
End if
next
End function
End class
</script>
</job>