;NAME delprof.kix
;
;DESCRIPTION This is a script to delete the admin user local
; profiles (not local administrator) and roaming profiles from
; a workstation. Note: If you think you need to save a particular
; profile, copy it to c:\temp before running this script!
; This will only delete files that are pointed to by the location
; specified in the registry for a given profile. So, there may
; be some directories left under "documents and settings" that will
; need to be manually deleted.
;
;AUTHOR Brad Van Orden
;
;VERSION 1.1
;
;HISTORY Created 21 Aug 07
; 23 Oct 07 - Added checking free space before and afterward.
;
Break On
;
Dim $SO
;
; These are just programming options for me.
; One forces me to define all variables and the
; other doesn't allow a kixtart macro within a string.
;
$SO = SetOption('Explicit', 'On')
$SO = SetOption('NoMacrosInStrings', 'On')
;
DIM $strWks, $strProfReg, $arrProfs, $strProf, $strDisk
DIM $strSID, $strPath, $strUser, $strFile, $intRetCode, $arrSize[3]
;
$strWks = ""
While $strWks == ""
? "Please enter the name of the workstation you wish to delete profiles from: "
Gets $strWks
Loop
;
; Make sure no leading or trailing spaces were accidently added to the name.
$strWks = Trim($strWks)
;
$strFile = ExpandEnvironmentVars(%USERPROFILE%) + "\Desktop\" + $strWks + "_profiles.ini"
;
; Enumerate the keys under:
; HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
; The local administrator key ends with "-500"
; Domain profiles from a domain that is different than the domain the computer
; belongs to will have the domain listed after the last period of the data in the value ProfileImagePath.
; Roaming profiles have the server share listed as the data in the value: CentralProfile
;
$strProfReg = "\\" + $strWks + "\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
;
If RedirectOutput(ExpandEnvironmentVars(%USERPROFILE%) + "\Desktop\" + $strWks + "_log.txt") = 0
? "Opened the log!"
EndIf
;
; Get the disk free space before we start.
$arrSize = FreeSpace($strWks)
? "The current free space on " + $strWks + " is: " + $arrSize[0] + " " + $arrSize[1]
? "The total disk size on " + $strWks + " is: " + $arrSize[2] + " " + $arrSize[3]
$intRetCode = WriteProfileString($strFile,"Disk","FreeBefore",$arrSize[0] + " " + $arrSize[1])
;
; Get a list of all the profiles.
$arrProfs = ArrayEnumKey($strProfReg)
For Each $strProf In $arrProfs
? "Starting on profile: " + $strProf
If Len($strProf) > 8
; The local accounts are short. System is S-1-5-18. Local Service is S-1-5-19.
; Network Service is S-1-5-20. We are only interested in the "longer" SIDs.
; Grab the last portion of the SID (after the last hyphen).
$strSID = Right($strProf,Len($strProf)-InStrRev($strProf,"-"))
If $strSID <> "500"
; The profile ending with -500 is the local administrator.
$strPath = ExpandEnvironmentVars(ReadValue($strProfReg + "\" + $strProf, "ProfileImagePath"))
$strUser = Right($strPath,Len($strPath)-InStrRev($strPath,"\"))
If Left($strUser, 4) <> "SMSC"
; This should be a user to delete
? "Deleting user profile: " + $strUser
? "Deleting files for " + SIDtoName($strProf)
$strDisk = Left($strPath,1)
$strPath = "\\" + $strWks + "\" + $strDisk + "$" + Right($strPath,Len($strPath)-2)
? "Deleting path " + $strPath
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"Path",$strPath)
; For some reason, RD /s didn't work. I'll have to research that.
; RD $strPath /s
$intRetCode = DelDir($strPath)
If $intRetCode = 0
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"PathDelete","0")
Else
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"PathDelete",$intRetCode)
EndIf
; The directory is now gone, delete the regsitry entry.
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"Profile",$strProfReg + "\" + $strProf)
$intRetCode = DelTree($strProfReg + "\" + $strProf)
If $intRetCode = 0
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"RegDelete","0")
Else
$intRetCode = WriteProfileString($strFile,SIDtoName($strProf),"RegDelete",$intRetCode)
EndIf
EndIf
EndIf
EndIf
Next
; Get the disk free space afterwards.
$arrSize = FreeSpace($strWks)
? "The current free space on " + $strWks + " is: " + $arrSize[0] + " " + $arrSize[1]
$intRetCode = WriteProfileString($strFile,"Disk","FreeAfter",$arrSize[0] + " " + $arrSize[1])
;
If RedirectOutput("") <> 0
? "Could not re-enable the console!"
EndIf
;
? "All finished!"
;
Function ArrayEnumKey($strRegKey)
;
;NAME ArrayEnumKey
;
;ACTION This function will build an array of subkeys by enumerating a key.
; If they key does not exist, exit with value 2.
;
;AUTHOR Jens Meyer
; Modified by Brad Van Orden
;
;VERSION 2.0
;
;HISTORY Created 5 Dec 01
; My mods 21 Aug 07
;
;SYNTAX ArrayEnumKey($strRegKey)
;
;PARAMETERS strRegKey - A string containing the registry key to enumerate.
;
;RETURNS An array of keys.
;
;DEPENDENCIES None
;
;EXAMPLE $arrKey = ArrayEnumKey($strRegKey)
; ...
Dim $intIndex, $arrOfKeys[0], $strKey
;
If KeyExist($strRegKey)
;
$intIndex = 0
$strKey = EnumKey($strRegKey,$intIndex)
While @Error = 0
ReDim Preserve $arrOfKeys[$intIndex]
$arrOfKeys[$intIndex] = $strKey
$intIndex = $intIndex + 1
$strKey = EnumKey($strRegKey,$intIndex)
Loop
$ArrayEnumKey = $arrOfKeys
Else
$ArrayEnumKey = ""
EndIf
EndFunction
;
Function FreeSpace($strWks)
;
;NAME FreeSpace
;
;ACTION This function will return the free space and total size of the c drive
; on the given computer.
;
;AUTHOR Kholm
; Modified by Brad Van Orden
;
;VERSION 1.5
;
;HISTORY Created 17 Dec 03
; My mods 23 Aug 07
;
;SYNTAX FreeSpace($strWks)
;
;PARAMETERS strWks - A string containing the name of the computer to query.
;
;RETURNS An array.
; The first element is the free space number.
; The second element is the magnitude of the number.
; The third element is the total size.
; The fourth element is the magnitude of the total size.
;
;DEPENDENCIES None
;
;EXAMPLE $arrSize = FreeSpace($strWks)
;
DIM $objWMIService, $colDisks, $objDisk, $intFreeSpace, $intTotalSpace, $arrSize[1], $arrSiz[3]
;
$objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" + $strWks + "\root\cimv2")
;
; The following reports on just the c drive:
$colDisks = $objWMIService.ExecQuery("Select * from Win32_LogicalDisk where DeviceID = 'C:'")
;
For Each $objDisk in $colDisks
$intFreeSpace = $objDisk.FreeSpace
$intTotalSpace = $objDisk.Size
$arrSize = MagQ($intFreeSpace)
$arrSiz[0] = $arrSize[0]
$arrSiz[1] = $arrSize[1]
$arrSize = MagQ($intTotalSpace)
$arrSiz[2] = $arrSize[0]
$arrSiz[3] = $arrSize[1]
Next
$FreeSpace = $arrSiz
EndFunction
;
Function MagQ($intSize)
;
;NAME MagQ
;
;ACTION Takes in a number and returns it quantified to the appropriate unit and prefix.
;
;AUTHOR Brad Van Orden
;
;VERSION 1.0
;
;HISTORY Created 23 Aug 07
; 24 Oct 07 - Fixed a problem where the comparisons were being done in character mode.
;
;SYNTAX MagQ($intSize)
;
;PARAMETERS intSize - The number we wish to quantify.
;
;RETURNS Two-dimensional array as follows:
; 0 - Computed Size
; 1 - Size Prefix and Unit
;
;DEPENDENCIES None
;
;EXAMPLE $arrSize = MagQ($intSize)
;
Dim $arrRes[1], $TERA, $GIGA, $MEGA, $KILO
;
$KILO = 1024.
$MEGA = $KILO * $KILO
$GIGA = $MEGA * $KILO
$TERA = $GIGA * $KILO
;
Select
Case (0. + $intSize) >= (0. + $TERA)
$arrRes[0] = (1. * CINT((CDBL($intSize)/$TERA)*100))/100.
$arrRes[1] = "TB"
Case (0. + $intSize) >= (0. + $GIGA)
$arrRes[0] = (1. * CINT((CDBL($intSize)/$GIGA)*100))/100.
$arrRes[1] = "GB"
Case (0. + $intSize) >= (0. + $MEGA)
$arrRes[0] = (1. * CINT((CDBL($intSize)/$MEGA)*100))/100.
$arrRes[1] = "MB"
Case (0. + $intSize) >= (0. + $KILO)
$arrRes[0] = (1. * CINT((CDBL($intSize)/$KILO)*100))/100.
$arrRes[1] = "KB"
Case 1
$arrRes[0] = $intSize
$arrRes[1] = "B"
EndSelect
$MagQ = $arrRes
EndFunction
;
Function DelDir($strPath)
;
;NAME DelDir
;
;ACTION This function will delete the given directory.
;
;AUTHOR not known
; Modified by Brad Van Orden
;
;VERSION 1.1
;
;HISTORY Created ?
; 27 Sep 07 - Fixed a flaw in the logic that did not delete the parent
; directory.
;
;SYNTAX DelDir($strPath)
;
;PARAMETERS strPath - A string containing the directory to delete.
;
;RETURNS Error Code.
;
;DEPENDENCIES None
;
;EXAMPLE $intRetCode = DelDir($strPath)
;
Dim $strFilename, $intRetCode
;
; Enumerate the directory.
$strFilename = Dir($strPath + "\*.*")
;
While $strFilename <> "" And @ERROR = 0
; We don't need to process the current or parent directory placeholders.
If $strFilename <> "." And $strFilename <> ".."
; If the returned file name is a directory, process it.
If (GetFileAttr($strPath + "\" + $strFilename) & 16)
$intRetCode = DelDir($strPath + "\" + $strFilename)
Else
; It's not a directory. So, let's delete it!
SetFileAttr($strPath + "\" + $strFilename, 128)
Del $strPath + "\" + $strFilename
$DelDir = @ERROR
EndIf
EndIf
; Get the next file name.
$strFilename = Dir()
Loop
; At this point, the directory should be empty. We just need to delete it now.
; Make sure the directory has normal file attributes.
SetFileAttr($strPath + "\" + $strFilename, 128)
If @ERROR <> 0
? "Could not set the file attributes of, " + $strFilename
? @SERROR
EndIf
RD $strPath
$intRetCode = @ERROR
$strFileName = @SERROR
If $intRetCode <> 0
? "There was an error removing the directory, " + $strPath + "."
? "The error number is, " + $intRetCode + ", and the error messae is: " + $strFileName + "."
EndIf
$DelDir = @ERROR
EndFunction