'INPUT		    : Path to registry keys/values 
' OUTPUT	    : Searches specified keys/values in every user's HKCU, if found deletes it.
' USAGE 	    : Instruction have been provided at two places.  Search this script for "RemoveLoad" and "RemovePath"
' BASE SCRIPT NAME : NA
'=============================================================================================================================






Option Explicit
'On Error Resume Next


'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*DO NOT EDIT ANY PART OF THIS CLASS*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

' This class has been designed to handle array operations in an object oriented fashion. This class may be used in other scripts
'as well, but copy the class completely. The methods defined in the class can be inter-dependent.


Class ArrayOp
	Public Name
	Public Length
	Public DType
	Public Message
	Public Code
	Private Sorted


'========================================================
'========================================================
'	Property Processing
'========================================================
'========================================================

	Public Property Get assign_Name
		assign_Name=Name
	End Property

	Public Property Let assign_Name (arrName)
		Name=arrName
	End Property

	Public Property Get assign_Length ()
		assign_Length=Length
	End Property

	Public Property Let assign_Length (intLength)
		Length=intLength
	End Property

	Public Property Get assign_DType ()
		assign_DType=DType
	End Property

	Public Property Let assign_DType (intType)
		DType=intType
	End Property

	Public Property Get assign_Message ()
		assign_Message=Message
	End Property

	Public Property Get assign_Code ()
		assign_Code=Code
	End Property

	Private Property Get assign_SOrted ()
		assign_Sorted=Sorted
	End Property

	Private Property Let assign_Sorted (blnStatus)
		Sorted=blnStatus
	End Property

'========================================================
'========================================================
'	End Property Processing
'========================================================
'========================================================


	Private Sub Class_Initialize
		Name=""
		Length=-1
		DType=-1
		Message=""
		Code=-1
		Sorted=False
	End Sub


	Public Sub Add (varData)
		Length=Length+1
		Redim Preserve Name (Length)
		Name (Length)=varData
		if (Sorted) Then Sort 0,Length
	End Sub

	Public Sub AddDistinct (varData)
		if (Contains (varData)) Then
			Message="Not Added"
			Code=1
			Exit Sub
		End If

		Add (varData)
		Message="Add success"
		Code=0
	End Sub

	Public Function AtIndex (intIndex)
		AtIndex=Name (intIndex)
	End Function

	Public Sub GetRidOf (intIndex)
		if (UBound (Name)=0) Then
			Name (0)=""
		End If
		dim intOutLoop
		For intOutLoop=intIndex To Length
			If (uBound (Name)<>intOutLoop) Then _
			Name (intOutLoop)=Name (intOutLoop+1)
		Next
		Length=Length-1
		Redim Preserve Name (Length)	
	End Sub

	Public Sub InsertAt (varData, intIndex)
		dim intOutLoop
		Length=Length+1
		Redim Preserve Name (Length)
		For intOutLoop=intIndex To Length
			If (Length<>intOutLoop) Then _
			Name (intOutLoop+1)=Name (intOutLoop)
		Next
		Name (intIndex)=varData
	End Sub

	Public Sub Sort (intLowBound,intHighBound)
		  Dim varPivot,intLowSwap,intHighSwap,varTemp
		  If (intHighBound-intLowBound=0) Then Exit Sub

		  if intHighBound - intLowBound = 1 then
			  if Name(intLowBound) > Name(intHighBound) then
				varTemp=Name(intLowBound)
				Name(intLowBound) = Name(intHighBound)
				Name(intHighBound) = varTemp
			   End If
		   End If


		  varPivot = Name(int((intLowBound + intHighBound) / 2))
		  Name(int((intLowBound + intHighBound) / 2)) = Name(intLowBound)
		  Name(intLowBound) = varPivot
		  intLowSwap = intLowBound + 1
		  intHighSwap = intHighBound
  
		  do

		    while intLowSwap < intHighSwap and Name(intLowSwap) <= varPivot
			      intLowSwap = intLowSwap + 1
		    wend

		    while Name(intHighSwap) > varPivot
			      intHighSwap = intHighSwap - 1
		    wend

		    if intLowSwap < intHighSwap then
			      varTemp = Name(intLowSwap)
			      Name(intLowSwap) = Name(intHighSwap)
			      Name(intHighSwap) = varTemp
		    End If
		  Loop while intLowSwap < intHighSwap
  
  		  Name(intLowBound) = Name(intHighSwap)
		  Name(intHighSwap) = varPivot
  
		  if intLowBound < (intHighSwap - 1) then Sort intLowBound,intHighSwap-1

		  if intHighSwap + 1 < intHighBound then Sort intHighSwap+1,intHighBound
		  if (Not Sorted) Then Sorted=True
	End Sub

	Public Function Contains (varData)
		If (Length=-1) Then
			Contains=False
			Exit Function
		End If
		dim arrTemp, Found:arrTemp=Name:Found=False
		dim intLowIndex, intHighIndex, intMidIndex, intPrevVal
		Sort 0,Length

		intLowIndex=0:intHighIndex=Length
		do While (intMidIndex>=0 And intMidIndex<=Length)
			intMidIndex = CInt ((intLowIndex+intHighIndex)/2)
			if (varData=Name (intMidIndex)) Then
				Contains=true
				Exit Function
			End If
			If(varData<Name (intMidIndex)) Then
				intHighIndex=intMidIndex-1
			Else
				intLowIndex=intMidIndex+1
			End If
			if (intLowIndex=intHighIndex) Then
				if (Name (intLowIndex))=varData Then 
					Contains=True
					Exit Function
				End If
				Exit Do
			End If
			if (intMidIndex=intLowIndex) Then
				if (Name (intLowIndex))=varData Then 
					Contains=True
					Exit Function
				End If
				Exit Do
			End If
			if (intMidIndex=intHighIndex) Then
				if (Name (intMidIndex))=varData Then 
					Contains=True
					Exit Function
				End If
				Exit Do
			End If
		Loop
		Name=arrTemp
		Contains=False
	End Function

End Class




CONST HKU=&H80000003


dim arrSID(), arrProfiles (), objSID

EnumerateSID ()
RemoveKeys ()



'========================================
'Begin: RemoveKeys
'
' This subroutine prepares the payload 
' to process. Actual deletion does not
' happen here.
'========================================




Private Sub RemoveKeys ()
	dim strSID, arrRegPath (), intLoop, intOutLoop

	
	'RemoveLoad
	'=================================================
	'Change the value in paranthesis to the number of 
	'registry keys/values to be deleted.

	Redim arrRegpath (0)

	'=================================================


	'RemovePath
	'=================================================
	'Modify the registry paths below For Values,
	'append "_IsValue" at the end of each registry value
	'Replicate registry path format exactly as demonstrated
	'below. Retain initial back-slashes.

	arrRegPath (0)="\Software\DeIcer"
	
	'DO NOT EDIT ANY OTHER PART OF THIS SCRIPT
	'=================================================

	For intOutLoop = 0 to objSID.Length
		For intLoop=0 to UBound (arrRegPath)
			DeleteKeys HKU, objSID.AtIndex (intOutLoop) & arrRegPath (intLoop)
		Next
	Next
End Sub


'========================================
'End: RemoveKeys
'========================================


'========================================
'Begin: DeleteKeys
'
' This subroutine performs actual deletion
' of registry kesy and values recursively.
'========================================

Private Sub DeleteKeys (Hive, strRegPath)



	dim arrSubKeys, strSubKey, objReg, strComputer
	strComputer="."
	Set objReg=GetObject ("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")


	if (Instr (strRegPath,"_IsValue")>0) Then 
		strRegPath=Replace (strRegPath,"_IsValue","")
		dim strValueName,intPos, strKeyName
		intPos=Instrrev (strRegPath,"\")
		strValueName=Mid (strRegPath,intPos+1,Len (strRegPath)-intPos)
		strKeyName = Left (strRegPath,intPos-1)
		objReg.DeleteValue Hive,strKeyName,strValueName
	End If


	objReg.EnumKey Hive, strRegPath, arrSubkeys 

	If IsArray(arrSubkeys) Then 
		For Each strSubkey In arrSubkeys 
			Deletekeys Hive, strRegPath & "\" & strSubkey 
		Next 
	End If 

	objReg.DeleteKey Hive, strRegPath
End Sub


'========================================
'End: DeleteKeys
'========================================



'========================================
'Begin: EnumerateSID
'
' This subroutine enumerates SID keys of
' all active users.
'========================================

Private Sub EnumerateSID ()
	dim objReg, strRegPath, strSID, strComputer, intIndex:intIndex=-1
	dim intLoop
	strComputer="."
	strRegPath=""
	Set objReg=GetObject ("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
	objReg. EnumKey HKU, strRegPath, arrSID
	Set objSID=new ArrayOp
	objSID.Name=arrSID
	objSID.Length=UBound (arrSID)

	do Until intLoop>objSID.Length
	For intLoop = 0 To objSID.Length
		If (objSID.AtIndex (intLoop)="S-1-5-18" Or objSID.AtIndex (intLoop)="S-1-5-19" Or _
			objSID.AtIndex (intLoop)="S-1-5-20" Or Instr (Lcase (objSID.AtIndex (intLoop)),"_classes")>0 Or _
			(Instr (Lcase (objSID.AtIndex (intLoop)),"S-1-5-21-") >0 And Right (Lcase (objSID.AtIndex (intLoop)),4)="-500")) Then 

			objSID.GetRidOf (intLoop)
			Exit For

		End If
	Next
	Loop
End Sub


'========================================
'End: RemoveKeys
'========================================