Last active
December 24, 2015 16:39
-
-
Save Iristyle/6829813 to your computer and use it in GitHub Desktop.
Ripper - Konica Minolta Driver Scrubbing Utility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Konica Driver Uninstallation Utility | |
=============================================================================== | |
README | |
Purpose | |
================== | |
The purpose of the Konica uninstallation utility is to completely uninstall all | |
exclusive and proprietary traces of the 7030 and IP-421 Visual and Adobe printer | |
drivers from Windows NT 4.0, Windows 2000 and Windows XP operating systems. The | |
utility can be used on a local machine, a remote machine or a series of remote | |
machines to remove files, registry entries, shares, printer defaults, individual | |
user settings, and any other traces of the installed drivers. The utility will | |
work properly against either network installed drivers, or those that have been | |
installed via the driver installation utility. All committed changes to a | |
system are logged to a text file. | |
Disclaimer | |
================== | |
All system changes are permanent. It is highly recommended that all machines | |
be backed up prior to running the driver uninstallation utility. | |
Pre-Requisites | |
================== | |
- The driver uninstallation utility requires JScript version 5.5 because of | |
several language features present only in that version and higher. | |
Version 5.5 of JScript ships with: | |
Microsoft Internet Explorer 5.5 | |
Microsoft Windows Millennium Edition | |
Microsoft Internet Explorer 6.0 | |
Microsoft Windows XP | |
The latest version of JScript, included in the Microsoft Windows Script | |
distribution, can be found here : | |
http://msdn.microsoft.com/library/default.asp?url=/downloads/list/webdev.asp | |
NOTE : It is only necessary for the machine executing the script to have | |
this version, NOT remote clients of the script. | |
- The driver uninstallation utility relies extensively on WMI Core 1.5 - the | |
Windows Management Instrumentation. WMI allows for remote management of | |
machines on a network. | |
WMI ships with: | |
Microsoft Windows 2000 | |
Microsoft Windows Millenium Edition | |
Microsoft Windows XP | |
The latest version of WMI can be found here: | |
http://www.microsoft.com/downloads/details.aspx?FamilyID=afe41f46-e213-4cbf-9c5b-fbf236e0e875&DisplayLang=en | |
NOTE : It is necessary for all client machines to have WMI installed. | |
Machines that do not have WMI installed cannot be manipulated by the | |
Konica driver uninstallation utility. These machines include Windows 95, | |
Windows 98, and Windows NT 4.0 machines. | |
- The drive uninstallation utility relies on psexec from System Internals. | |
Psexec allows running a remote process on a machine, via a supplied executable, | |
or a known executable on a remote machine. It is only necessary for the server | |
executing the script to have this file in it's path. psexec.exe has been | |
included with the script distribution. | |
The latest version of psexec can be found here: | |
http://www.sysinternals.com/ntw2k/freeware/psexec.shtml | |
- The drive uninstallation utility relies on reg.exe (shipped with Windows XP, | |
the Windows 2000 and NT 4.0 Resource Kits). Reg.exe allows loading a registry | |
file into a specific HKLM or HKU registry hive. Reg.exe has been included with | |
the script distribution, and must be in the same directory as the script. | |
IMPORTANT NOTES | |
================== | |
Because of the nature of the drivers being removed, the files can potentially | |
be locked/in-use by the print spooler service, or other interactive applications. | |
The driver uninstallation utility will remotely stop and restart the spooler | |
service, and will automatically log off any interactive users on the machine | |
that it's currently targeting. | |
However, because of a known bug in the WMI implementation on Windows XP, an | |
interactive logon cannot be remotely logged off. Therefore, it is highly | |
recommended that when run against Windows XP machines, all users are logged out | |
of those machines first! A /reboot switch has been added to allow remotely | |
rebooting a Windows XP machine, but it is highly recommended that this switch | |
never be used. | |
Furthermore, even though the script detects being run on the local machine to | |
prevent a logoff, it is not recommended that the utility be run against the | |
current machine, because of that very reason. Files may be locked during the | |
current user's logon session that cannot be removed. | |
Also note that any unsaved work will be lost on those machines that are logged | |
off automatically. | |
Features / Usage | |
================== | |
- The driver uninstallation utility has been designed to be used in 4 different manners: | |
- From a server machine against all computers within an Active Directory | |
- From a server machine against a specific set of computers | |
- From a server machine against a single client machine (which can be itself) | |
- To generate a list of computers within an Active Directory | |
To support these features, a variety of command line switches are available: | |
/computer:NAME | |
- This will scan and clean a single computer named 'NAME' for instances of driver | |
files and settings. If a local computer is specified by name, and the script is | |
running on that computer, a logoff will not be initiated. This name can also be | |
a DNS name or IP address. | |
/scan:PDC | |
- This will generate a list of computers from the Active Directory located on | |
computer 'PDC', scan and clean each computer in the list for instances of driver | |
files and settings. | |
/computerlist:FILENAME.EXT | |
- This will load the file specified by 'FILENAME.EXT', and treat each line as a | |
computer name. Each of the computers specified will be scanned and cleaned of | |
all instances of driver files and settings. The file must be formatted with one | |
computer name per line, including an optional username and password separated by | |
tabs. Lines that start with a ';' will be ignored. For instance, the following | |
lines are all legal: | |
COMPUTER USER | |
COMPUTER USER1 PASSWORD | |
;Comment | |
COMPUTER2 | |
/buildcomputerlist:FILENAME.EXT | |
- This MUST be used in conjunction with the /scan:PDC switch. This will generate | |
a new text file named 'FILENAME.EXT' that contains a list of all computers in the | |
Active Directory located on computer 'PDC'. If a /user:USER and /password:PASSWORD | |
switch are supplied, these will be written to the text file. If a 'FILENAME.EXT' | |
is not specified, the generated file will be named 'inclusion.txt'. This file | |
can be supplied to the /computerlist:FILENAME.EXT switch. | |
/exclude:FILENAME.EXT | |
- Like the /computerlist switch, the 'FILENAME.EXT' specified is parsed for | |
computer names. The format of the file is exactly the same, but if user names | |
and passwords are specified within the file, they are ignored. The computers | |
specified in the file will NOT be scanned during the execution of the | |
uninstallation utility. These computer names will be placed in the ignored.txt | |
log. This switch can only be specified in conjunction with the /scan:PDC switch | |
and the /computerlist:FILENAME.EXT switch. | |
The only valid combinations of the above switches are the following: | |
/computer:COMPUTER | |
/scan:PDC | |
/scan:PDC /exclude:EXCLUDE.TXT | |
/computerlist:INCLUDE.TXT | |
/computerlist:INCLUDE.TXT /exclude:EXCLUDE.TXT | |
/buildcomputerlist:INCLUDE.TXT /scan:PDC | |
/scan:PDC /buildcomputerlist | |
/installregfrompath:PATH | |
- This will install reg.exe to the system directory of all machines scanned. | |
Although this is not necessary, it could prove useful to deploy this file. | |
The path must be a UNC path accessible from each of the computers being scanned. | |
i.e. \\Server\Share\reg.exe | |
/user:USERNAME | |
- Will use the 'USERNAME' specified to connect to the machines included in the | |
scan. This includes querying the Active Directory on the machine specified | |
by /scan:PDC if applicable. If /computerlist:FILENAME.EXT is specified, | |
'USERNAME' will be used when a user name has not been specified in 'FILENAME.EXT'. | |
The 'USERNAME' specified can be in the format 'DOMAIN\User' | |
/password:PASSWORD | |
- Like the /user:USERNAME switch, will be used when connecting to machines | |
included in the scan and clean operation. a /user:USERNAME must be specified | |
for this switch to be valid. | |
/noprompt | |
- Sets the uninstallation utility into expert mode. Ordinarily, there would be | |
a confirmation dialog for each computer included in the scan. When scanning, | |
for instance, an Active Directory, this can be inconvenient. When this switch | |
is specified, no prompts will be shown. | |
/reboot | |
- Will force a remote reboot on Windows XP machines only. As discussed in the | |
'Important Notes' sections above, because of a known bug in the Windows XP | |
implementation of WMI, a remote logoff cannot be forced on Windows XP. Using | |
this switch will reboot the Windows XP machine. Because the machine won't be | |
available in time for a scan, it will be added to the unavailable.txt file | |
generated by the script. | |
/? | |
- Displays the list of command line parameters | |
Output / Log Files | |
================== | |
ripperlog.txt | |
--------------- | |
- A complete log of the scripts operations, including basic environment | |
information, command line switches, time/date, a list of machines to include | |
and exclude from the scan, detailed information about deletions on remote | |
machines, and summary statistics. This log also contains warnings and errors, | |
which appear in the log respectively as follows: | |
* WARNING : | |
** ERROR : | |
errors.txt | |
--------------- | |
- Contains a list of computer names that caused errors during the last scan. | |
This list can be supplied to the /computerlist:FILENAME.EXT switch. | |
unavailable.txt | |
--------------- | |
- Contains a list of computer names that were unavailable at the time of the last | |
scan. Because an Active Directory may contain a list of computers, some of | |
which may be offline at the time, this file provides an easy to get to list of | |
those machines. This list can be supplied to the /computerlist:FILENAME.EXT | |
switch. | |
ignored.txt | |
--------------- | |
- Contains a list of computer names that were specified by the | |
/exclude:FILENAME.EXT, and computer names that were scanned if 'No' or 'Cancel' | |
was selected in the prompt dialog. If the /noprompt switch is present, only | |
computer names specified in the exclusion list will be included in this file. | |
Backup Files | |
--------------- | |
- A backup copy of each of the following files is kept at ripperlog.bak, errors.bak, | |
unavailable.bak and ignored.bak. Each time the driver uninstallation utility is | |
run, the contents of the current log files are prepended to any existing backups. | |
This creates a backup file in which the newest items appear at the top of the file. | |
Examples | |
================== | |
ripper.js /scan:mynet-dc1 /exclude:exclusion.txt /user:MYNET\Administrator /password:Adminpassword | |
- Searches 'mynet-dc1' for a list of computers in the Active Directory. Those | |
specified in 'exclusion.txt' will not be included in the scan. All machines will | |
accessed by the 'MYNET\Administrator' account. | |
ripper.js /scan:mynet-dc1 /buildcomputerlist:computers.txt | |
- Searches 'mynet-dc1' for a lits of computers in the Active Directory. All | |
computer names are written to the file 'computers.txt' | |
ripper.js /computer:localhost | |
- Searches and cleans the local machine. (NOT RECOMMENDED) | |
ripper.js /scan:mynet-dc1 /noprompt | |
- Searches 'mynet-dc1' for a list of computers in the Active Directory. Will | |
not prompt for confirmation for each machine that will be scanned and cleaned. | |
ripper.js /computerlist:unavailable.txt /noprompt | |
- Searches all computers specified by the uninstallation utility output file | |
'unavailable.txt' - In other words, searches computers that were previously | |
unavailable. Will not prompt for confirmation for each machine that will be | |
scanned and cleaned. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Looks like I originally wrote this hunk of junk 10+ years ago. Brings back some, ahem, fond .. memories. | |
Expects psexec.exe and reg.exe in the local directory |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Windows script download | |
//http://msdn.microsoft.com/library/default.asp?url=/downloads/list/webdev.asp | |
//wmi for Windows 95/98/NT 4 - download | |
//http://www.microsoft.com/downloads/details.aspx?FamilyID=afe41f46-e213-4cbf-9c5b-fbf236e0e875&DisplayLang=en | |
//windows script debugger for Windows nt 4.0, 2000 and xp | |
//http://microsoft.com/downloads/details.aspx?FamilyId=2F465BE0-94FD-4569-B3C4-DFFDF19CCD99&displaylang=en | |
//windows script debugger for Windows 98 and ME | |
//http://www.microsoft.com/downloads/details.aspx?FamilyId=E606E71F-BA7F-471E-A57D-F2216D81EC3D&displaylang=en | |
//win32 error code list | |
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp | |
//wmi error constants | |
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_error_constants.asp | |
registryTypes = new Array( | |
" ", // 0 | |
"REG_SZ ", // 1 | |
"REG_EXPAND_SZ ", // 2 | |
"REG_BINARY ", // 3 | |
"REG_DWORD ", // 4 | |
"REG_DWORD_BIG_ENDIAN ", // 5 | |
"REG_LINK ", // 6 | |
"REG_MULTI_SZ ", // 7 | |
"REG_RESOURCE_LIST ", // 8 | |
"REG_FULL_RESOURCE_DESCRIPTOR ", // 9 | |
"REG_RESOURCE_REQUIREMENTS_LIST", // 10 | |
"REG_QWORD "); // 11 | |
var driversToFind = new Array( | |
"K421PSS.DLL"); | |
var system32Directories = new Array( | |
"\\spool\\drivers\\w32x86\\3\\", | |
"\\spool\\drivers\\w32x86\\2\\"); | |
var system32FilesToDelete = new Array( | |
"k421ps.hlp", | |
"k421psc.dll", | |
"K421PSI3.DLL", | |
"k421psj.dll", | |
"k421psk.dll", | |
"k421psl.dll", | |
"k421psp.dll", | |
"k421psq.exe", | |
"k421pss.dll", | |
"k421psu.dll", | |
"k421psw.hlp", | |
"k421pswk.dll", | |
"k421pswu.dll", | |
"k421psx.dll", | |
"K421PSZ.EXE", | |
"kc421pb0.dll", | |
"kc421pb0.hlp"); | |
var infFilesToDelete = new Array( | |
"K421PSK.INF", | |
"K421PSK1.INF", | |
"K421PSK2.INF", | |
"K421PSK3.INF", | |
"K421PSK4.INF", | |
"K421PSK5.INF", | |
"K421PSK6.INF", | |
"K421PSK7.INF", | |
"K421PSK8.INF", | |
"K421PSK9.INF"); | |
var WBEM_E_NOT_FOUND = 0x80041002; //object not found - i.e. file not found | |
var ERROR_FILE_NOT_FOUND = 2; | |
var ERROR_INVALID_COMMAND_LINE = 1639; | |
var REGDB_E_CLASSNOTREG = 0x80040154; | |
var HKCR = 0x80000000; //HKEY_CLASSES_ROOT | |
var HKCU = 0x80000001; //HKEY_CURRENT_USER | |
var HKLM = 0x80000002; //HKEY_LOCAL_MACHINE | |
var HKU = 0x80000003; //HKEY_USERS | |
var HKCC = 0x80000005; //HKEY_CURRENT_CONFIG | |
var HKDD = 0x80000006; //HKEY_DYNAMIC_DATA | |
var OpenAsDefault = -2; | |
var FailIfNotExist = 0; | |
var ForReading = 1; | |
var ForWriting = 2; | |
var ForAppending = 8; | |
var ImpersonationLevelAnonymous = 1; | |
var ImpersonationLevelIdentify = 2; | |
var ImpersonationLevelImpersonate = 3; | |
var ImpersonationLevelDelegate = 4; | |
var AuthenticationLevelDefault = 0; | |
var AuthenticationLevelNone = 1; | |
var AuthenticationLevelConnect = 2; | |
var AuthenticationLevelCall = 3; | |
var AuthenticationLevelPkt = 4; | |
var AuthenticationLevelPktIntegrity = 5; | |
var AuthenticationLevelPktPrivacy = 6; | |
var PriorityClassNormal = 32; //no special schedule needs | |
var PriorityClassIdle = 64; //threads run only when the system is idle and is preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes. | |
var PriorityClassHigh = 128; //a process that performs time critical tasks that must be executed immediately to run correctly. The threads of a high priority class process preempt the threads of normal priority or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high priority class, because a high priority class CPU-bound application can use nearly all available cycles. Only Realtime priority preempts threads set to this level. | |
var PriorityClassRealtime = 256; // a process that has the highest possible priority. The threads of a real time priority class process preempt the threads of all other processes—including high priority threads and operating system processes performing important tasks. For example, a real time process that executes for more than a very brief interval can cause disk caches not to flush, or cause a mouse to be unresponsive. | |
var PriorityClassAbove_Normal = 16384; // Windows Server 2003, Windows XP, Windows 2000: Indicates a process that has priority higher than Normal but lower than High. | |
var PriorityClassBelow_Normal = 32768; //Windows Server 2003, Windows XP, and Windows 2000: Indicates a process that has priority higher than Idle but lower than Normal. | |
var SW_HIDE = 0; //Hides the window and activates another window. | |
var SW_NORMAL = 1; // Activates and displays a window. If the window is minimized or maximized, the system restores it to the original size and position. An application specifies this flag when displaying the window for the first time. | |
var SW_SHOWMINIMIZED = 2; // Activates the window, and displays it as a minimized window. | |
var SW_SHOWMAXIMIZED = 3; // Activates the window, and displays it as a maximized window. | |
var SW_SHOWNOACTIVATE = 4; // Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the window is not activated. | |
var SW_SHOW = 5; // Activates the window, and displays it at the current size and position. | |
var SW_MINIMIZE = 6; // Minimizes the specified window, and activates the next top level window in the Z order. | |
var SW_SHOWMINNOACTIVE = 7; // Displays the window as a minimized window. This value is similar to SW_SHOWMINIMZED, except that the window is not activated. | |
var SW_SHOWNA = 8; // Displays the window at the current size and position. This value is similar to SW_SHOW, except that the window is not activated. | |
var SW_RESTORE = 9; // Activates and displays the window. If the window is minimized or maximized, the system restores it to the=original size and position. An application specifies this flag when restoring a minimized window. | |
var SW_SHOWDEFAULT = 10; // Sets the show state based on the SW_ value that is specified in the STARTUPINFO structure passed to the CreateProcess function by the program that starts the application. | |
var SW_FORCEMINIMIZE = 11; // Windows Server 2003, Windows XP, and Windows 2000: Minimizes a window, even when the thread that owns the window is hung. Only use this flag when minimizing windows from a different thread. | |
var localPrinterKeyName = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"; | |
var networkPrinterKeyName = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Providers\\LanMan Print Services\\Servers"; | |
var driverSubKeyName = "\\PrinterDriverData"; | |
var driverFileKeyName = "SPLUserModePrinterDriver"; | |
//var spoolerSubKeyName = "\\DsSpooler"; | |
//var driverValueName = "driverName"; | |
var driverValueName = "Printer Driver"; | |
//var printerValueName = "printerName"; | |
var printerValueName = "Name"; | |
//var shareValueName = "printShareName"; | |
var shareValueName = "Share Name"; | |
var controlSetKeyNames = new Array( | |
"SYSTEM\\CurrentControlSet", | |
"SYSTEM\\ControlSet001", | |
"SYSTEM\\ControlSet002", | |
"SYSTEM\\ControlSet003", | |
"SYSTEM\\ControlSet004", | |
"SYSTEM\\ControlSet005", | |
"SYSTEM\\ControlSet006", | |
"SYSTEM\\ControlSet007", | |
"SYSTEM\\ControlSet008", | |
"SYSTEM\\ControlSet009"); | |
var spoolerServiceName = "Spooler"; | |
var uninstallKeyName = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; | |
var arpCacheKeyName = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Management\\ARPCache"; | |
var profileListKeyName = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"; | |
var separator = "==============================================================================\r\n"; | |
var commandLineMessage = ""; | |
var keysDeleted, valuesDeleted, filesDeleted; | |
var keysDeletedFailed, valuesDeletedFailed, filesDeletedFailed; | |
var totalKeysDeleted = 0, totalValuesDeleted = 0, totalFilesDeleted = 0; | |
var totalKeysDeletedFailed = 0, totalValuesDeletedFailed = 0, totalFilesDeletedFailed = 0; | |
var totalComputersToScan = 0, totalComputersScannedSuccesfully = 0, totalComputersScannedWithErrors = 0, totalComputersUnavailable = 0, totalComputersIgnored = 0; | |
//TODO: add stats for number of printers removed - network vs. local... success/ fail | |
//TODO: make use of these statistics about OS | |
var win98, winME, win2000, winXP, winOther; | |
var scanError = false; | |
var localComputerName = ""; | |
var commandLineDescription = "Konica Printer Driver Uninstallation Utility -- Command Line Options:\r\n\r\n/computer:NAME - Searches computer specified by 'NAME' for installed printers and removes them\r\n"; | |
commandLineDescription += "/scan:PDC - Builds a list of computers in the Active Directory of computer 'PDC', and searches them\r\n/computerlist:FILENAME.EXT - Searches computer specified in file 'FILENAME.EXT'\r\n"; | |
commandLineDescription += "\tFile must be formatted with one computer name, and an optional username and password, separated by tabs, per line like:\r\n\tCOMPUTER\tUSER\tPASSWORD\r\n"; | |
commandLineDescription += "/buildcomputerlist:FILENAME.EXT - Builds a list of computers in the Active Directory specified by the /scan switch and writes them to 'FILENAME.EXT'\r\n\tPerforms No Scanning\r\n\tIf no filename is specified, the file is named 'inclusion.txt'\r\n"; | |
commandLineDescription += "/installregfrompath:PATH - This will install reg.exe to the system directory of all machines scanned. Although this is not necessary, it could prove useful to deploy this file.\r\n\tThe path must be a UNC path accessible from each of the computers being scanned\r\n"; | |
commandLineDescription += "/exclude:FILENAME.EXT - Excludes all computers listed in 'FILENAME.EXT' from being searched (only valid in conjunction with /scan or /computerlist)\r\n\tFile must be formatted with one computer name per line\r\n"; | |
commandLineDescription += "/user:USERNAME - The username to connect to computers with when searching\r\n/password:PASSWORD - The password to connect to computers with when searching\r\n"; | |
commandLineDescription += "\tIf the /computerlist switch is used, /user and /password are used only when NOT specified in the 'FILENAME.EXT'\r\n\tA username may be in the form Domain\\Username - if no Domain is specified, a local account is used\r\n"; | |
commandLineDescription += "\tIf the /buildcomputerlist switch is used, /user and /password are written to 'FILENAME.EXT' in a format usable by the the /computerlist switch\r\n"; | |
commandLineDescription += "/noprompt - Will override the default setting, so that no confirmation prompts will occur when each computer is searched\r\n/reboot - Will force a remote reboot on a Windows XP machine, because a WMI logoff won't work properly on Windows XP (NOT RECOMMENDED)\r\n"; | |
commandLineDescription += "/? - Will Display this list of options"; | |
var fso, shell; | |
if (WScript.Arguments.Named.Exists("?") || (0 == WScript.Arguments.length)) | |
WScript.Echo(commandLineDescription); | |
else | |
Run(); | |
function Run() | |
{ | |
var i, j, args = "", today = new Date(); | |
var logFile, errorLogFile, ignoredLogFile, unavailableLogFile; | |
var excludeList, scanList; | |
try | |
{ | |
//The script that drives the script | |
fso = new ActiveXObject("Scripting.FileSystemObject"); | |
shell = new ActiveXObject("WScript.Shell"); | |
var user, password; | |
logFile = InitializeLog("ripperlog.txt"); | |
WriteToLog(logFile, separator + separator + "\r\nKonica Driver Uninstallation Utility"); | |
WriteToLog(logFile, "Run Date : " + today.toString()); | |
WriteToLog(logFile, "Host Executable : " + WScript.FullName + " - Version " + WScript.Version + "." + WScript.BuildVersion); | |
WriteToLog(logFile, "Script Path : " + WScript.ScriptFullName); | |
for (i = 0; i < WScript.Arguments.length; ++i) | |
{ | |
args += WScript.Arguments(i) + " "; | |
} | |
WriteToLog(logFile, "Command Line Arguments : " + args); | |
var locator = new ActiveXObject("WbemScripting.SWbemLocator"); | |
localComputerName = GetLocalComputerName(locator, logFile); | |
WriteToLog(logFile, "Run From Computer : " + localComputerName + "\r\n"); | |
ValidateEnvironment(logFile); | |
ValidateCommandLine(logFile); | |
//read these files first - b/c they might be blown away when we initalize our logs | |
if (WScript.Arguments.Named.Exists("exclude")) | |
{ | |
excludeList = ReadComputerList(WScript.Arguments.Named("exclude"), user, password, false, logFile); | |
} | |
if (WScript.Arguments.Named.Exists("computerlist")) | |
{ | |
var fileName = WScript.Arguments.Named("computerlist"); | |
scanList = ReadComputerList(fileName, user, password, true, logFile); | |
} | |
//don't open these files up until after the command line has been validated | |
errorLogFile = InitializeLog("errors.txt"); | |
WriteToLog(errorLogFile, "; Generated : " + today.toString()); | |
ignoredLogFile = InitializeLog("ignored.txt"); | |
WriteToLog(ignoredLogFile, "; Generated : " + today.toString()); | |
unavailableLogFile = InitializeLog("unavailable.txt"); | |
WriteToLog(unavailableLogFile, "; Generated : " + today.toString()); | |
//user name and password processing - if applicable | |
if (WScript.Arguments.Named.Exists("user")) | |
{ | |
user = WScript.Arguments.Named("user"); | |
if (WScript.Arguments.Named.Exists("password")) | |
{ | |
password = WScript.Arguments.Named("password"); | |
} | |
else | |
{ | |
password = null; | |
} | |
} | |
else | |
{ | |
user = null; | |
password = null; | |
} | |
//a one computer only scan | |
if (WScript.Arguments.Named.Exists("computer")) | |
{ | |
computerNames = new Array(new Array(1), new Array(1), new Array(1)); | |
computerNames[0][0] = WScript.Arguments.Named("computer"); | |
computerNames[1][0] = user; | |
computerNames[2][0] = password; | |
WriteToLog(logFile, "Computers To Scan :\r\n" + computerNames[0][0] + "\r\n"); | |
CleanComputers(locator, computerNames, logFile, ignoredLogFile, unavailableLogFile, errorLogFile); | |
} | |
//scan the active directory for computer names | |
else if (WScript.Arguments.Named.Exists("scan")) | |
{ | |
var domainController = WScript.Arguments.Named("scan"); | |
var scanList = BuildComputerList(locator, domainController, user, password, logFile); | |
//build and save a list of computers - don't scan | |
if (WScript.Arguments.Named.Exists("buildcomputerlist")) | |
{ | |
var fileName = WScript.Arguments.Named("buildcomputerlist"); | |
if ((null == fileName) || ("" == fileName)) | |
fileName = "inclusion.txt"; | |
WriteComputerList(scanList, fileName, logFile); | |
WriteToLog(logFile, "Computers Written To [" + fileName + "] :\r\n"); | |
WriteComputerListToLog(scanList[0], logFile); | |
} | |
//scan | |
else | |
{ | |
if (WScript.Arguments.Named.Exists("exclude")) | |
{ | |
scanList = RemoveExclusions(excludeList, scanList); | |
WriteToLog(logFile, "Computers To Exclude From Scan :\r\n"); | |
WriteComputerListToLog(excludeList[0], logFile); | |
} | |
WriteToLog(logFile, "Computers To Scan :\r\n"); | |
WriteComputerListToLog(scanList[0], logFile); | |
CleanComputers(locator, scanList, logFile, ignoredLogFile, unavailableLogFile, errorLogFile); | |
} | |
WriteScriptSummary(logFile); | |
} | |
//use a list of computers | |
else if (WScript.Arguments.Named.Exists("computerlist")) | |
{ | |
if (WScript.Arguments.Named.Exists("exclude")) | |
{ | |
scanList = RemoveExclusions(excludeList, scanList); | |
WriteToLog(logFile, "Computers To Exclude From Scan :\r\n"); | |
WriteComputerListToLog(excludeList[0], logFile); | |
} | |
WriteToLog(logFile, "Computers To Scan :\r\n"); | |
WriteComputerListToLog(scanList[0], logFile); | |
CleanComputers(locator, scanList, logFile, ignoredLogFile, unavailableLogFile, errorLogFile); | |
WriteScriptSummary(logFile); | |
} | |
else | |
{ | |
WScript.Echo("A computer name must be specified with the /computer:COMPUTER switch or a domain controller with the /scan:DC switch"); | |
WScript.Quit(); | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : While Initializing Script [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
finally | |
{ | |
CloseLog(logFile); | |
WriteToLog(errorLogFile, ""); | |
CloseLog(errorLogFile); | |
WriteToLog(ignoredLogFile, ""); | |
CloseLog(ignoredLogFile); | |
WriteToLog(unavailableLogFile, ""); | |
CloseLog(unavailableLogFile); | |
} | |
} | |
function RemoveExclusions(exclusionList, inclusionList) | |
{ | |
var i, j; | |
for (i = 0; i < exclusionList[0].length; ++i) | |
{ | |
for (j = 0; j < inclusionList[0].length; ++j) | |
{ | |
//compare computer names | |
if (exclusionList[0][i].toUpperCase() == inclusionList[0][j].toUpperCase()) | |
{ | |
inclusionList[0].splice(j, 1); | |
inclusionList[1].splice(j, 1); | |
inclusionList[2].splice(j, 1); | |
break; | |
} | |
} | |
} | |
return inclusionList; | |
} | |
function ValidateEnvironment(logFile) | |
{ | |
if (!IsFileInPath("psexec.exe", logFile)) | |
{ | |
WScript.Echo("FATAL ERROR : Could Not Find PSExec.Exe In Path..."); | |
throw new Error(ERROR_FILE_NOT_FOUND, "FATAL ERROR : Could Not Find PSExec.Exe In Path..."); | |
} | |
if (!fso.FileExists("reg.exe")) | |
{ | |
WScript.Echo("FATAL ERROR : Could Not Find Reg.exe In Current Path..."); | |
throw new Error(ERROR_FILE_NOT_FOUND, "FATAL ERROR : Could Not Find Reg.Exe In Current Path..."); | |
} | |
} | |
function IsFileInPath(fileName, logFile) | |
{ | |
var found = false; | |
try | |
{ | |
//current directory | |
if (fso.FileExists(fileName)) | |
return true; | |
var directories = shell.ExpandEnvironmentStrings("%path%").split(";"); | |
var currentPath; | |
var i = 0; | |
for (i = 0; i < directories.length; ++i) | |
{ | |
currentPath = fso.BuildPath(directories[i], fileName); | |
if (fso.FileExists(currentPath)) | |
{ | |
found = true; | |
break; | |
} | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : While Searching Path For File [" + fileName + "] - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return found; | |
} | |
//this method will throw - so that execution will totally fail | |
function ValidateCommandLine(logFile) | |
{ | |
var i, arg; | |
var errorMessage = ""; | |
var validArguments = 0; | |
var computerExists = WScript.Arguments.Named.Exists("computer"); | |
if (computerExists) | |
++validArguments; | |
var buildcomputerlistExists = WScript.Arguments.Named.Exists("buildcomputerlist"); | |
if (buildcomputerlistExists) | |
++validArguments; | |
var scanExists = WScript.Arguments.Named.Exists("scan") | |
if (scanExists) | |
++validArguments; | |
var computerlistExists = WScript.Arguments.Named.Exists("computerlist"); | |
if (computerlistExists) | |
++validArguments; | |
var installregfrompathExists = WScript.Arguments.Named.Exists("installregfrompath"); | |
if (installregfrompathExists) | |
++validArguments; | |
var excludeExists = WScript.Arguments.Named.Exists("exclude"); | |
if (excludeExists) | |
++validArguments; | |
var nopromptExists = WScript.Arguments.Named.Exists("noprompt"); | |
if (nopromptExists) | |
++validArguments; | |
var rebootExists = WScript.Arguments.Named.Exists("reboot"); | |
if (rebootExists) | |
++validArguments; | |
var userExists = WScript.Arguments.Named.Exists("user"); | |
if (userExists) | |
++validArguments; | |
var passwordExists = WScript.Arguments.Named.Exists("password"); | |
if (passwordExists) | |
++validArguments; | |
if ((computerExists && (scanExists || computerlistExists || buildcomputerlistExists)) || (scanExists && computerlistExists) || (computerlistExists && buildcomputerlistExists)) | |
errorMessage += "** ERROR : There can only be one instance of a /scan, /computer, /computerlist switch - they cannot be specified together\r\n"; | |
if (buildcomputerlistExists && !scanExists) | |
errorMessage += "** ERROR : The /scan switch must be specified when using the /buildcomputerlist switch\r\n"; | |
if (installregfrompathExists) | |
{ | |
var installregfrompath = WScript.Arguments.Named("installregfrompath"); | |
var fileName = "REG.EXE"; | |
var foundIndex = installregfrompath.toUpperCase().indexOf(fileName); | |
var matches = installregfrompath.match(/\\\\.+?\\/i); | |
//match the path, so that reg.exe is at the end | |
if (("" == installregfrompath) || (-1 == foundIndex) || (installregfrompath.length != (foundIndex + fileName.length)) || (!fso.FileExists(installregfrompath))) | |
errorMessage += "** ERROR : The /installregfrompath supplied is not valid\r\n"; | |
//invalid server-style share name | |
else if ((null == matches) || (matches.length == 0)) | |
errorMessage += "** ERROR : The /installregfrompath supplied must be a UNC style path\r\n"; | |
} | |
if (excludeExists && (computerExists || buildcomputerlistExists)) | |
errorMessage += "** ERROR : The /exclude switch cannot be used with the /computer or /buildcomputerlist switch - it can only be used with the /computer or /computerlist switch\r\n"; | |
if (!userExists && passwordExists) | |
errorMessage += "** ERROR : The /password switch must be used with the /user switch\r\n"; | |
if (buildcomputerlistExists && nopromptExists) | |
errorMessage += "* WARNING: The /noprompt switch has no effect when used with the /buildcomputerlist switch\r\n"; | |
if (buildcomputerlistExists && rebootExists) | |
errorMessage += "* WARNING: The /reboot switch has no effect when used with the /buildcomputerlist switch\r\n"; | |
if (WScript.Arguments.Unnamed.length > 0) | |
{ | |
errorMessage += "** ERROR : Unnamed arguments "; | |
for (i = 0; i < WScript.Arguments.Unnamed.length; ++i) | |
{ | |
errorMessage += WScript.Arguments.Unnamed(i); | |
if (i != (WScript.Arguments.Unnamed.length - 1)) | |
errorMessage += ", "; | |
} | |
errorMessage += " are not valid\r\n"; | |
} | |
//user passed some invalid named arguments | |
if (WScript.Arguments.Named.length > validArguments) | |
{ | |
for (i = 0; i < WScript.Arguments.Named.length; ++i) | |
{ | |
arg = WScript.Arguments.Named(i); | |
if ((arg != "computer") && (arg != "scan") && (arg != "computerlist") && (arg != "exclude") && (arg != "noprompt") && (arg != "reboot") && (arg != "user") && (arg != "password")) | |
{ | |
errorMessage += "** ERROR : Switch " + arg + " is not valid\r\n"; | |
} | |
} | |
} | |
if (errorMessage != "") | |
{ | |
WriteToLog(logFile, errorMessage); | |
throw new Error(ERROR_INVALID_COMMAND_LINE, "Invalid Command Line"); | |
} | |
} | |
function BuildComputerList(locator, domainController, user, password, logFile) | |
{ | |
var computerNames = new Array(new Array(), new Array(), new Array()), computerName; | |
try | |
{ | |
//TODO: what to do when there's no active directory on the network? | |
//issue net view /domain:domainname ... and capture the output? | |
if (IsAvailable(domainController, 2, null, logFile)) | |
{ | |
var service; | |
//TODO: check to see if this IS in fact a domain controller - to prevent locking the query ?? | |
if (("" == user) || (null == user)) | |
service = locator.ConnectServer(computerName, "root\\directory\\ldap"); | |
else if (null == password) | |
service = locator.ConnectServer(computerName, "root\\directory\\ldap", user); | |
else | |
service = locator.ConnectServer(computerName, "root\\directory\\ldap", user, password); | |
var queryResult = service.ExecQuery("SELECT * FROM DS_Computer"); | |
//this will loop as many times as there are computers in the domain | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
computerNames[0].push(e.item().ds_cn); | |
computerNames[1].push(user); | |
computerNames[2].push(password); | |
} | |
WriteToLog(logFile, "[" + computerNames[0].length + "] computer accounts identified in domain controller [" + domainController + "]"); | |
} | |
else | |
{ | |
throw new Error("Domain Controller [" + domainController + "] invalid or unavailable"); | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : While Building Computer List [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return computerNames; | |
} | |
function ReadComputerList(fileName, defaultUser, defaultPassword, throwError, logFile) | |
{ | |
var i = 0; | |
var computerNames = new Array(new Array(), new Array(), new Array()); | |
try | |
{ | |
if (fso.FileExists(fileName)) | |
{ | |
var listFile = fso.OpenTextFile(fileName, ForReading); | |
var readLine, splitArray; | |
var lines = listFile.ReadAll().split("\r\n"); | |
for (i = 0; i < lines.length; ++i) | |
{ | |
readLine = lines[i]; | |
//ignore lines starting with semi-colon, blank lines and null lines | |
if ((';' != readLine.charAt(0)) && ("" != readLine) && (null != readLine)) | |
{ | |
//split the line up with tabs | |
splitArray = readLine.split("\t"); | |
//computer name | |
if (splitArray.length >= 1) | |
{ | |
computerNames[0].push(splitArray[0]); | |
//a user name has been supplied | |
if (splitArray.length >= 2) | |
{ | |
//store it | |
computerNames[1].push(splitArray[1]); | |
//password supplied | |
if (splitArray.length >= 3) | |
computerNames[2].push(splitArray[2]); | |
//no password | |
else | |
computerNames[2].push(null); | |
} | |
//no user name, so no password | |
else | |
{ | |
computerNames[1].push(defaultUser); | |
computerNames[2].push(defaultPassword); | |
} | |
} | |
} | |
} | |
listFile.Close(); | |
WriteToLog(logFile, "[" + computerNames[0].length + "] computers listed in file [" + fileName + "]"); | |
} | |
else | |
{ | |
throw new Error(ERROR_FILE_NOT_FOUND, "Computer list file [" + fileName + "] not found."); | |
} | |
} | |
catch (ex) | |
{ | |
if (throwError) | |
WriteToLog(logFile, "** ERROR : While Reading Computer List [" + hexString(ex.number) + " / " + ex.message + "]"); | |
else | |
WriteToLog(logFile, "* WARNING : While Reading Computer List [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return computerNames; | |
} | |
function WriteComputerList(computerNames, fileName, logFile) | |
{ | |
var i, listFile, currentLine = ""; | |
try | |
{ | |
if (fso.FileExists(fileName)) | |
{ | |
var backupFileName = fileName.substr(0, fileName.lastIndexOf(".")) + ".bak"; | |
var oldFileName = fileName.substr(0, fileName.lastIndexOf(".")) + ".old"; | |
if (fso.FileExists(backupFileName)) | |
{ | |
if (fso.FileExists(oldFileName)) | |
fso.DeleteFile(oldFileName); | |
//rename the .bak to .old | |
fso.MoveFile(backupFileName, oldFileName); | |
//append the .bak.old to .txt and call it .bak (newest stuff at top of file) | |
shell.Run("%comspec% /c copy /y " + fileName + " + " + oldFileName + " " + backupFileName, 0, true); | |
//delete our temp stuff, and our original log | |
fso.DeleteFile(oldFileName); | |
fso.DeleteFile(fileName); | |
} | |
else | |
{ | |
//this is the first backup | |
fso.MoveFile(fileName, backupFileName); | |
} | |
} | |
listFile = fso.OpenTextFile(fileName, ForAppending, true); | |
listFile.WriteLine("; Generated : " + (new Date()).toString()); | |
for (i = 0; i < computerNames[0].length; ++i) | |
{ | |
if ((null == computerNames[1][i]) || ("" == computerNames[1][i])) | |
currentLine = computerNames[0][i]; | |
else | |
{ | |
if ((null == computerNames[2][i]) || ("" == computerNames[2][i])) | |
currentLine = computerNames[0][i] + "\t" + computerNames[1][i]; | |
else | |
currentLine = computerNames[0][i] + "\t" + computerNames[1][i] + "\t" + computerNames[2][i]; | |
} | |
listFile.WriteLine(currentLine); | |
} | |
listFile.WriteLine(); | |
} | |
catch(ex) | |
{ | |
WriteToLog(logFile, "Could Not Open File [" + fileName + "] For Writing..."); | |
WScript.Echo("Could Not Open File [" + fileName + "] For Writing..."); | |
} | |
finally | |
{ | |
if (null != listFile) | |
{ | |
listFile.Close(); | |
} | |
} | |
} | |
function WriteComputerListToLog(computerList, logFile) | |
{ | |
var currentLine = ""; | |
var i = 0; | |
if (0 == computerList.length) | |
{ | |
WriteToLog(logFile, "None\r\n"); | |
return; | |
} | |
for (i = 0; i < computerList.length; ++i) | |
{ | |
if ((i % 4) > 0) | |
currentLine += "\t"; | |
currentLine += computerList[i]; | |
if ((i != 0) && (0 == (i % 4))) | |
{ | |
WriteToLog(logFile, currentLine); | |
currentLine = ""; | |
} | |
} | |
//flush the left-overs | |
if ("" != currentLine) | |
WriteToLog(logFile, currentLine); | |
WriteToLog(logFile, ""); | |
} | |
function GetLocalComputerName(locator, logFile) | |
{ | |
try | |
{ | |
var service = locator.ConnectServer(".", "root\\cimv2"); | |
var computerQuery = service.ExecQuery("Select * from Win32_ComputerSystem"); | |
var e = new Enumerator(computerQuery); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
//domain is e.item().Domain | |
return e.item().Name; | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "* WARNING : Could Not Retrieve Local Computer Name - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return ""; | |
} | |
function CleanComputers(locator, computerNames, logFile, ignoredLogFile, unavailableLogFile, errorLogFile) | |
{ | |
var i, computerName, user, password, caption, success; | |
var code, scanCurrentComputer; | |
var cancelScan = false; | |
var cimv2service = null; | |
var serviceStopped = false; | |
totalComputersToScan = computerNames[0].length; | |
for (i = 0; i < computerNames[0].length; ++i) | |
{ | |
try | |
{ | |
cimv2service = null; | |
//initalize our global variables for this run | |
scanError = false; | |
serviceStopped = false; | |
keysDeleted = valuesDeleted = filesDeleted = 0; | |
keysDeletedFailed = valuesDeletedFailed = filesDeletedFailed = 0; | |
scanCurrentComputer = false; | |
computerName = computerNames[0][i]; | |
user = computerNames[1][i]; | |
password = computerNames[2][i]; | |
//ping the machine to make sure we can connect - do this before asking a user if it should be scanned | |
if (IsAvailable(computerName, 2, null, logFile)) | |
{ | |
//did the user override prompts? | |
if (WScript.Arguments.Named.Exists("noprompt")) | |
{ | |
scanCurrentComputer = true; | |
} | |
else | |
{ | |
//10 second wait... show Yes + No + Cancel ... with a Question Mark icon | |
code = shell.Popup("Process Computer " + computerName + "?", 8, "Cleaning Computer", 3 + 32); | |
//user clicked yes | |
if (6 == code) | |
{ | |
scanCurrentComputer = true; | |
} | |
//cancel - stop everything | |
else | |
{ | |
scanCurrentComputer = false; | |
//cancel - stop everything - totally exit the CleanComputers function - we're done here | |
if (2 == code) | |
cancelScan = true; | |
} | |
} | |
//user said yes at the prompt, or didn't ask to be prompted | |
if (scanCurrentComputer) | |
{ | |
WriteToLog(logFile, separator + "Cleaning Computer [" + computerName + "]"); | |
try | |
{ | |
if (("" == user) || (null == user)) | |
cimv2service = locator.ConnectServer(computerName, "root\\cimv2"); | |
else if (null == password) | |
cimv2service = locator.ConnectServer(computerName, "root\\cimv2", user); | |
else | |
cimv2service = locator.ConnectServer(computerName, "root\\cimv2", user, password); | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : Could not establish WMI connection... "); | |
if (REGDB_E_CLASSNOTREG == hex(ex.number)) | |
{ | |
WriteToLog(logFile, "** ERROR : This is likely caused by WMI not being installed on the client computer..."); | |
WriteToLog(logFile, "** ERROR : Download the latest version at :"); | |
WriteToLog(logFile, "** ERROR : http://www.microsoft.com/downloads/details.aspx?FamilyID=afe41f46-e213-4cbf-9c5b-fbf236e0e875&DisplayLang=en"); | |
} | |
throw ex; | |
} | |
caption = GetComputerCaption(cimv2service); | |
WriteToLog(logFile, "Operating System : " + caption); | |
//make sure not to log off on the current local machine | |
if (("LOCALHOST" != computerName.toUpperCase()) && ("." != computerName) && (localComputerName.toUpperCase() != computerName.toUpperCase())) | |
ForceLogoff(cimv2service, logFile); | |
StopService(cimv2service, spoolerServiceName, 4, logFile); | |
serviceStopped = true; | |
CleanRegistry(locator, computerName, user, password, logFile); | |
CleanDisk(cimv2service, logFile); | |
} | |
//this computer is not being scanned | |
else | |
{ | |
if (("" == user) || (null == user)) | |
WriteToLog(ignoredLogFile, computerName); | |
else if (null == password) | |
WriteToLog(ignoredLogFile, computerName + "\t" + user); | |
else | |
WriteToLog(ignoredLogFile, computerName + "\t" + user + "\t" + password); | |
++totalComputersIgnored; | |
WriteToLog(logFile, separator + "* WARNING : Computer [" + computerName + "] NOT scanned - aborted by user..."); | |
} | |
} | |
//computer is not avaiable on the network at all | |
else | |
{ | |
++totalComputersUnavailable; | |
if (("" == user) || (null == user)) | |
WriteToLog(unavailableLogFile, computerName); | |
else if (null == password) | |
WriteToLog(unavailableLogFile, computerName + "\t" + user); | |
else | |
WriteToLog(unavailableLogFile, computerName + "\t" + user + "\t" + password); | |
//prevent trying to start a service on a non-existant machine | |
scanCurrentComputer = false; | |
WriteToLog(logFile, separator + "** ERROR : Computer [" + computerName + "] not found or unavailable"); | |
WriteComputerSummary(logFile); | |
} | |
} | |
catch (ex) | |
{ | |
scanError = true; | |
WriteToLog(logFile, "** ERROR : Problem Cleaning [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
finally | |
{ | |
if (scanCurrentComputer) | |
{ | |
if (!scanError) | |
++totalComputersScannedSuccesfully; | |
else | |
{ | |
if (("" == user) || (null == user)) | |
WriteToLog(errorLogFile, computerName); | |
else if (null == password) | |
WriteToLog(errorLogFile, computerName + "\t" + user); | |
else | |
WriteToLog(errorLogFile, computerName + "\t" + user + "\t" + password); | |
++totalComputersScannedWithErrors; | |
} | |
if (serviceStopped) | |
StartService(cimv2service, spoolerServiceName, logFile); | |
WriteComputerSummary(logFile); | |
} | |
WriteToLog(logFile, "\r\n" + separator + "\r\n\r\n"); | |
if (cancelScan) | |
{ | |
totalComputersIgnored += computerNames[0].length - i; | |
//adjust our statistics appropriately - based on where we are in the loop | |
return; | |
} | |
} | |
} | |
} | |
function WriteComputerSummary(logFile) | |
{ | |
WriteToLog(logFile, "\r\n" + "Registry Keys Deleted :\t\t\t\t" + keysDeleted); | |
WriteToLog(logFile, "Registry Values Deleted :\t\t\t" + valuesDeleted); | |
WriteToLog(logFile, "Files Deleted :\t\t\t\t\t\t" + filesDeleted); | |
WriteToLog(logFile, "Registry Key Deletion Failures :\t" + keysDeletedFailed); | |
WriteToLog(logFile, "Registry Value Deletion Failures :\t" + valuesDeletedFailed); | |
WriteToLog(logFile, "File Deletion Failures :\t\t\t" + filesDeletedFailed); | |
} | |
function WriteScriptSummary(logFile) | |
{ | |
WriteToLog(logFile, separator + "Script Action Summary "); | |
WriteToLog(logFile, "\r\nTotal Computers Set To Scan :\t\t\t\t\t\t\t" + totalComputersToScan); | |
var totalScanned = totalComputersScannedSuccesfully + totalComputersScannedWithErrors; | |
WriteToLog(logFile, "\t\tTotal Computers Scanned :\t\t\t\t\t\t" + totalScanned); | |
WriteToLog(logFile, "\t\t\t\tSuccessfully :\t\t\t\t\t\t\t" + totalComputersScannedSuccesfully); | |
WriteToLog(logFile, "\t\t\t\tWith Errors :\t\t\t\t\t\t\t" + totalComputersScannedWithErrors); | |
WriteToLog(logFile, "\t\tTotal Computers Unavailable :\t\t\t\t\t" + totalComputersUnavailable); | |
WriteToLog(logFile, "\t\tTotal Computers Ignored / Aborted By User :\t\t" + totalComputersIgnored); | |
WriteToLog(logFile, "\r\nTotal Registry Keys Deleted :\t\t\t\t" + totalKeysDeleted); | |
WriteToLog(logFile, "Total Registry Values Deleted :\t\t\t\t" + totalValuesDeleted); | |
WriteToLog(logFile, "Total Files Deleted :\t\t\t\t\t\t" + totalFilesDeleted); | |
WriteToLog(logFile, "Total Registry Key Deletion Failures :\t\t" + totalKeysDeletedFailed); | |
WriteToLog(logFile, "Total Registry Value Deletion Failures :\t" + totalValuesDeletedFailed); | |
WriteToLog(logFile, "Total File Deletion Failures :\t\t\t\t" + totalFilesDeletedFailed); | |
WriteToLog(logFile, "\r\n" + separator); | |
} | |
function InitializeLog(fileName) | |
{ | |
var logFile = null; | |
try | |
{ | |
if (fso.FileExists(fileName)) | |
{ | |
var backupFileName = fileName.substr(0, fileName.lastIndexOf(".")) + ".bak"; | |
var oldFileName = fileName.substr(0, fileName.lastIndexOf(".")) + ".old"; | |
if (fso.FileExists(backupFileName)) | |
{ | |
if (fso.FileExists(oldFileName)) | |
fso.DeleteFile(oldFileName); | |
//rename the .bak to .old | |
fso.MoveFile(backupFileName, oldFileName); | |
//append the .old to .txt and call it .bak (newest stuff at top of file) | |
shell.Run("%comspec% /c copy /y " + fileName + " + " + oldFileName + " " + backupFileName, 0, true); | |
//delete our temp stuff, and our original log | |
fso.DeleteFile(oldFileName); | |
fso.DeleteFile(fileName); | |
} | |
else | |
{ | |
//this is the first backup | |
fso.MoveFile(fileName, backupFileName); | |
} | |
} | |
logFile = fso.OpenTextFile(fileName, ForAppending, true); | |
} | |
catch(ex) | |
{ | |
WScript.Echo("FATAL ERROR : Could Not Open Log File [" + fileName + "]"); | |
throw ex; | |
} | |
return logFile; | |
} | |
function WriteToLog(logFile, text) | |
{ | |
if (null != logFile) | |
logFile.WriteLine(text); | |
} | |
function CloseLog(logFile) | |
{ | |
if (null != logFile) | |
logFile.Close(); | |
} | |
function ForceLogoff(service, logFile) | |
{ | |
var version; | |
try | |
{ | |
var queryResult = service.ExecQuery("SELECT * FROM Win32_OperatingSystem where Primary=true"); | |
//this will loop as many times as there are OS named like the one we got | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
version = e.item().Version; | |
//Windows XP version = 5.1.XXXX | |
if (-1 != version.indexOf("5.1.")) | |
{ | |
if (WScript.Arguments.Named.Exists("reboot")) | |
{ | |
//0 = reboot / 4 = force | |
e.item().Win32Shutdown(2 + 4); | |
} | |
else | |
{ | |
//TODO: command line switch /reboot - force reboot on XP based machine IFF there are logged on interactive users ? | |
WriteToLog(logFile, "* WARNING : Cannot force logoff on Windows XP b/c of a known Microsoft WMI bug..."); | |
WriteToLog(logFile, "* WARNING : The following sessions could potentially lock files - check log for file deletion errors:"); | |
var logonQueryResult = service.ExecQuery("SELECT * FROM Win32_LoggedOnUser"); | |
var logons = new Enumerator(logonQueryResult); | |
var session, account, accountName; | |
//enumerate the logons | |
for (; !logons.atEnd(); logons.moveNext()) | |
{ | |
//pull session and account information for each logon | |
session = GetSessionFromLoggedOnUser(service, logons.item()); | |
account = GetAccountFromLoggedOnUser(service, logons.item()); | |
if (null == account) | |
accountName = "Unknown"; | |
else | |
accountName = (account.LocalAccount ? account.Name : "\\\\" + account.Domain + "\\" + account.Name); | |
WriteToLog(logFile, "* WARNING : User [" + accountName + "] logged in under Session ID [" + (null != session ? session.LogonId : "Unknown") + "] as [" + (null != session ? GetLogonTypeName(session.LogonType) : "Unknown") + "] - Status [" + (null != account ? account.Status : "Unknown") + "]"); | |
} | |
} | |
} | |
else | |
{ | |
WriteToLog(logFile, "Forcing Logoff..."); | |
//0 = logoff / 4 = force | |
e.item().Win32Shutdown(0 + 4); | |
} | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : Could Not Force Logoff - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
} | |
function GetSessionFromLoggedOnUser(service, loggedOnUser) | |
{ | |
if ((null == loggedOnUser) || (null == service)) | |
return null; | |
try | |
{ | |
return service.Get(loggedOnUser.Dependent); | |
} | |
catch (ex) | |
{} | |
return null; | |
} | |
function GetAccountFromLoggedOnUser(service, loggedOnUser) | |
{ | |
if ((null == loggedOnUser) || (null == service)) | |
return null; | |
try | |
{ | |
return service.Get(loggedOnUser.Antecedent); | |
} | |
catch (ex) | |
{} | |
return null; | |
} | |
function GetLogonTypeName(logonType) | |
{ | |
var logonTypeName; | |
switch (logonType) | |
{ | |
case 2: | |
logonTypeName = "Interactive"; | |
break; | |
case 3: | |
logonTypeName = "Network"; | |
break; | |
case 4: | |
logonTypeName = "Batch"; | |
break; | |
case 5: | |
logonTypeName = "Service"; | |
break; | |
case 6: | |
logonTypeName = "Proxy"; | |
break; | |
case 7: | |
logonTypeName = "Unlock"; | |
break; | |
case 8: | |
logonTypeName = "NetworkCleartext"; | |
break; | |
case 9: | |
logonTypeName = "NewCredentials"; | |
break; | |
case 10: | |
logonTypeName = "RemoteInteractive"; | |
break; | |
case 11: | |
logonTypeName = "CachedInteractive"; | |
break; | |
case 12: | |
logonTypeName = "CachedRemoteInteractive"; | |
break; | |
case 13: | |
logonTypeName = "CachedUnlock"; | |
break; | |
default: | |
logonTypeName = "Unknown"; | |
} | |
return logonTypeName + " (" + logonType + ")"; | |
} | |
function GetComputerCaption(service) | |
{ | |
var caption = ""; | |
try | |
{ | |
var queryResult = service.ExecQuery("SELECT * FROM Win32_OperatingSystem where Primary=true"); | |
//this will loop as many times as there are OS named like the one we got | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
caption += e.item().Caption; | |
} | |
} | |
catch (ex) | |
{ | |
caption += "Error Retrieving Win32_OperatingSystem.Caption"; | |
} | |
return caption; | |
} | |
function GetSystemDirectory(service) | |
{ | |
var systemDirectory = ""; | |
var queryResult = service.ExecQuery("SELECT * FROM Win32_OperatingSystem where Primary=true"); | |
//this will loop as many times as there are OS named like the one we got | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
systemDirectory = e.item().SystemDirectory; | |
break; | |
} | |
return systemDirectory; | |
} | |
function StartService(service, serviceName, logFile) | |
{ | |
WriteToLog(logFile, "Starting Service [" + serviceName + "]..."); | |
try | |
{ | |
var queryResult = service.ExecQuery("SELECT * FROM Win32_Service WHERE name='" + serviceName + "'"); | |
//this will loop as many times as there are services named like the one we got | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
e.item().StartService(); | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "* WARNING : Could Not Start Service - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
} | |
function StopService(service, serviceName, timeOut, logFile) | |
{ | |
var counted, stopped; | |
WriteToLog(logFile, "Stopping Service [" + serviceName + "]..."); | |
try | |
{ | |
var queryResult = service.ExecQuery("SELECT * FROM Win32_Service WHERE name='" + serviceName + "'"); | |
//this will loop as many times as there are services named like the one we got | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
e.item().StopService(); | |
} | |
//interrogate the services to make sure they've stopped - we wait on them essentially | |
stopped = true; | |
do | |
{ | |
queryResult = service.ExecQuery("SELECT * FROM Win32_Service WHERE name='" + serviceName + "'"); | |
e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
e.item().InterrogateService(); | |
stopped = stopped && (e.item().State == "Stopped"); | |
} | |
//sleep in 1000 millisecond intervals | |
if (!stopped) | |
{ | |
WScript.Sleep(500); | |
counted += 500; | |
//if we've slept over our timeout, then break out | |
if (counted >= (timeOut * 1000)) | |
break; | |
} | |
} while (!stopped); | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "* WARNING : Could Not Stop Service - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
finally | |
{ | |
if (!stopped) | |
WriteToLog(logFile, "** ERROR : Could Not Stop Service [" + serviceName + "]"); | |
} | |
} | |
function CleanRegistry(locator, computerName, user, password, logFile) | |
{ | |
WriteToLog(logFile, "Examining Registry..."); | |
var service, i = 0; | |
if (("" == user) || (null == user)) | |
service = locator.ConnectServer(computerName, "root\\default"); | |
else if (null == password) | |
service = locator.ConnectServer(computerName, "root\\default", user); | |
else | |
service = locator.ConnectServer(computerName, "root\\default", user, password); | |
//var remoteRegistry = WScript.GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\" + computerName + "\\root\\default:StdRegProv"); | |
var remoteRegistry = service.Get("StdRegProv"); | |
LoadAllUserHives(locator, remoteRegistry, computerName, user, password, logFile); | |
//for windows 2000 and above style | |
CleanNetworkPrinters(remoteRegistry, networkPrinterKeyName, logFile); | |
//for NT style printers where the lanman stuff is stored in a different location | |
for (i = 0; i < controlSetKeyNames.length; ++i) | |
{ | |
CleanNetworkPrinters(remoteRegistry, controlSetKeyNames[i] + "\\Control\\Print\\Providers\\LanMan Print Services\\Servers", logFile); | |
} | |
//for windows 2000 and above style | |
CleanLocalPrinters(remoteRegistry, localPrinterKeyName, logFile); | |
//for NT style printers where the lanman stuff is stored in a different location | |
for (i = 0; i < controlSetKeyNames.length; ++i) | |
{ | |
CleanLocalPrinters(remoteRegistry, controlSetKeyNames[i] + "\\Control\\Print\\Printers", logFile); | |
} | |
} | |
function CleanNetworkPrinters(remoteRegistry, networkKey, logFile) | |
{ | |
var i, j, k; | |
var serverNames = GetSubKeyNames(remoteRegistry, HKLM, networkKey), serverName; | |
var printerKey, printerNames, printerNameKey, driverFileName, driverName, printerName, shareName; | |
for (i = 0; i < serverNames.length; ++i) | |
{ | |
printerKey = networkKey + "\\" + serverNames[i] + "\\Printers"; | |
printerNames = GetSubKeyNames(remoteRegistry, HKLM, printerKey); | |
for (j = 0; j < printerNames.length; ++j) | |
{ | |
printerNameKey = printerKey + "\\" + printerNames[j]; | |
//pull the value of | |
driverFileName = GetStringValue(remoteRegistry, HKLM, printerNameKey + driverSubKeyName, driverFileKeyName); | |
for (k = 0; k < driversToFind.length; ++k) | |
{ | |
if (driverFileName.toUpperCase() == driversToFind[k].toUpperCase()) | |
{ | |
//we have a match - store the name of the driver - to be used later when we delete, etc | |
//driverName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, driverValueName); | |
driverName = GetStringValue(remoteRegistry, HKLM, printerNameKey, driverValueName); | |
//printerName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, printerValueName); | |
printerName = GetStringValue(remoteRegistry, HKLM, printerNameKey, printerValueName); | |
WriteToLog(logFile, "\r\nFound NETWORK-installed printer [" + printerName + "] using driver [" + driversToFind[k] + "]"); | |
//shareName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, shareValueName); | |
shareName = GetStringValue(remoteRegistry, HKLM, printerNameKey, shareValueName); | |
RemoveShare(remoteRegistry, shareName, logFile); | |
DeleteRegistryKey(remoteRegistry, HKLM, printerNameKey, logFile); | |
DeleteRegistryKey(remoteRegistry, HKLM, arpCacheKeyName + "\\" + printerName, logFile); | |
DeleteUserSettings(remoteRegistry, serverNames[i], printerName, logFile); | |
//there might also be some funky local installed printer looking registry entries - kill those also | |
DeleteNetworkPrinterLocalSettings(remoteRegistry, serverNames[i], printerName, logFile); | |
DeleteControlSetSettings(remoteRegistry, driverName, logFile); | |
} | |
} | |
} | |
} | |
} | |
function CleanLocalPrinters(remoteRegistry, localKey, logFile) | |
{ | |
var i, j; | |
var printerNameKey; | |
var driverFileName, driverName, printerName, shareName; | |
var printerNames = GetSubKeyNames(remoteRegistry, HKLM, localKey); | |
for (i = 0; i < printerNames.length; ++i) | |
{ | |
printerNameKey = localKey + "\\" + printerNames[i]; | |
//pull the value of the driver | |
driverFileName = GetStringValue(remoteRegistry, HKLM, printerNameKey + driverSubKeyName, driverFileKeyName); | |
for (j = 0; j < driversToFind.length; ++j) | |
{ | |
if (driverFileName.toUpperCase() == driversToFind[j].toUpperCase()) | |
{ | |
//we have a match - store the name of the driver - to be used later when we delete, etc | |
//driverName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, driverValueName); | |
driverName = GetStringValue(remoteRegistry, HKLM, printerNameKey, driverValueName); | |
//printerName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, printerValueName); | |
printerName = GetStringValue(remoteRegistry, HKLM, printerNameKey, printerValueName); | |
WriteToLog(logFile, "\r\nFound LOCAL-installed printer [" + printerName + "] using driver [" + driversToFind[j] + "]"); | |
//shareName = GetStringValue(remoteRegistry, HKLM, printerNameKey + spoolerSubKeyName, shareValueName); | |
shareName = GetStringValue(remoteRegistry, HKLM, printerNameKey, shareValueName); | |
RemoveShare(remoteRegistry, shareName, logFile); | |
DeleteRegistryKey(remoteRegistry, HKLM, printerNameKey, logFile); | |
//this is local only - remove this so it doesn't show up in add/remove programs | |
DeleteRegistryKey(remoteRegistry, HKLM, uninstallKeyName + "\\" + driverName, logFile); | |
DeleteRegistryKey(remoteRegistry, HKLM, arpCacheKeyName + "\\" + printerName, logFile); | |
DeleteUserSettings(remoteRegistry, null, printerName, logFile); | |
DeleteControlSetSettings(remoteRegistry, driverName, logFile); | |
} | |
} | |
} | |
} | |
function RemoveShare(remoteRegistry, shareName, logFile) | |
{ | |
var i; | |
var sharesKeyName; | |
if ((null != shareName) && ("" != shareName)) | |
{ | |
for (i = 0; i < controlSetKeyNames.length; ++i) | |
{ | |
sharesKeyName = controlSetKeyNames[i] + "\\Services\\lanmanserver\\Shares"; | |
DeleteRegistryValue(remoteRegistry, HKLM, sharesKeyName, shareName, logFile); | |
DeleteRegistryValue(remoteRegistry, HKLM, sharesKeyName + "\\Security", shareName, logFile); | |
} | |
} | |
} | |
function CleanDisk(service, logFile) | |
{ | |
var i, j; | |
WriteToLog(logFile, "\r\nExamining File System..."); | |
var systemDirectory, windowsDirectory, currentPath; | |
var queryResult = service.ExecQuery("SELECT WindowsDirectory, SystemDirectory FROM Win32_OperatingSystem"); | |
//this should only loop once - there should only be one OS with a SystemDirectory | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
systemDirectory = e.item().SystemDirectory; | |
for (i = 0; i < system32FilesToDelete.length; ++i) | |
{ | |
for (j = 0; j < system32Directories.length; ++j) | |
{ | |
currentPath = systemDirectory + system32Directories[j] + system32FilesToDelete[i]; | |
DeleteFile(service, currentPath, logFile); | |
} | |
} | |
windowsDirectory = e.item().WindowsDirectory; | |
for (i = 0; i < infFilesToDelete.length; ++i) | |
{ | |
DeleteFile(service, windowsDirectory + "\\inf\\" + infFilesToDelete[i], logFile); | |
} | |
} | |
} | |
function DeleteFile(service, fileName, logFile) | |
{ | |
try | |
{ | |
service.Delete("Cim_Datafile='" + fileName + "'"); | |
WriteToLog(logFile, "Deleted File [" + fileName + "]"); | |
++filesDeleted; | |
++totalFilesDeleted; | |
} | |
catch (ex) | |
{ | |
//ignore 'file not found' error | |
if (hex(ex.number) != WBEM_E_NOT_FOUND) | |
{ | |
scanError = true; | |
WriteToLog(logFile, "** ERROR : Could Not Delete - Error [" + hexString(ex.number) + " / " + ex.message + "] - File [ " + fileName + "]"); | |
++filesDeletedFailed; | |
++totalFilesDeletedFailed; | |
} | |
} | |
} | |
function DeleteControlSetSettings(remoteRegistry, driverName, logFile) | |
{ | |
var c, i, j, k, l; | |
var controlSetKeyName; | |
var printEnvironmentKeys, printEnvironmentKey; | |
var driverKeys, driverKey, driverTypes, driverType, drivers; | |
for (c = 0; c < controlSetKeyNames.length; ++c) | |
{ | |
controlSetKeyName = controlSetKeyNames[c] + "\\Control\\Print\\Environments"; | |
printEnvironmentKeys = GetSubKeyNames(remoteRegistry, HKLM, controlSetKeyName); | |
for (i = 0; i < printEnvironmentKeys.length; ++i) | |
{ | |
printEnvironmentKey = controlSetKeyName + "\\" + printEnvironmentKeys[i]; | |
driverKeys = GetSubKeyNames(remoteRegistry, HKLM, printEnvironmentKey); | |
for (j = 0; j < driverKeys.length; ++j) | |
{ | |
driverKey = printEnvironmentKey + "\\" + driverKeys[j]; | |
driverTypes = GetSubKeyNames(remoteRegistry, HKLM, driverKey); | |
for (k = 0; k < driverTypes.length; ++k) | |
{ | |
driverType = driverKey + "\\" + driverTypes[k]; | |
drivers = GetSubKeyNames(remoteRegistry, HKLM, driverType); | |
for (l = 0; l < drivers.length; ++l) | |
{ | |
if (driverName.toUpperCase() == drivers[l].toUpperCase()) | |
{ | |
//we've found a matching driver by name - delete related CurrentControlSet registry settings | |
DeleteRegistryKey(remoteRegistry, HKLM, driverType + "\\" + drivers[l], logFile); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
function DeleteUserSettings(remoteRegistry, serverName, printerName, logFile) | |
{ | |
var i, j, foundIndex; | |
var printerPath; | |
//set up the 'path' so that it will work with local or networked printers | |
if ((null != serverName) && ("" != serverName)) | |
printerPath = "\\\\" + serverName + "\\" + printerName; | |
else | |
printerPath = printerName; | |
var userKeyNames = GetSubKeyNames(remoteRegistry, HKU, ""); | |
var userKeyName, connectionKeyNames, searchString; | |
var defaultPrinter, deviceOld; | |
for (i = 0; i < userKeyNames.length; ++i) | |
{ | |
userKeyName = userKeyNames[i]; | |
//strictly for networked printers - connections - this determines what shows in the printers folder, for one | |
if ((null != serverName) && ("" != serverName)) | |
{ | |
connectionKeyNames = GetSubKeyNames(remoteRegistry, HKU, userKeyName + "\\Printers\\Connections"); | |
for (j = 0; j < connectionKeyNames.length; ++j) | |
{ | |
searchString = (serverName + "," + printerName).toUpperCase(); | |
foundIndex = connectionKeyNames[j].toUpperCase().indexOf(searchString); | |
//make sure we match the entire string - otherwise we could match a partial, and accidentally delete that connection | |
if ((-1 != foundIndex) && (connectionKeyNames[j].length == (foundIndex + searchString.length))) | |
{ | |
DeleteRegistryKey(remoteRegistry, HKU, userKeyName + "\\Printers\\Connections\\" + connectionKeyNames[j], logFile); | |
} | |
} | |
} | |
deviceOld = GetStringValue(remoteRegistry, HKU, userKeyName + "\\Printers", "DeviceOld"); | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Printers\\Settings", printerPath, logFile); | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices", printerPath, logFile); | |
//TODO: look at the port value, and use that to rip from HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports ?? | |
//probably not a good idea to do that - b/c there will be ports like LPT1, etc... | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts", printerPath, logFile); | |
if (0 == deviceOld.toUpperCase().indexOf((printerPath + ",").toUpperCase())) | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Printers", "DeviceOld", logFile); | |
//should be local stuff only | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Printers\\DevModePerUser", printerPath, logFile); | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Printers\\DevModes2", printerPath, logFile); | |
//pull the printer from being the default if it is | |
defaultPrinter = GetStringValue(remoteRegistry, HKU, userKeyName + "\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", "Device"); | |
if (0 == defaultPrinter.toUpperCase().indexOf((printerPath + ",").toUpperCase())) | |
{ | |
//windows will automatically pick a new default | |
DeleteRegistryValue(remoteRegistry, HKU, userKeyName + "\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", "Device", logFile); | |
} | |
} | |
} | |
function LoadAllUserHives(locator, remoteRegistry, computerName, user, password, logFile) | |
{ | |
var i = 0, j = 0; | |
var found = false; | |
var existingUserKeyNames, profileKeyNames, profileKeyName = ""; | |
var path, commandLine, returnValue, methodResult; | |
var loaded = new Array(); | |
var fileCopied = false, returnCode; | |
try | |
{ | |
existingUserKeyNames = GetSubKeyNames(remoteRegistry, HKU, ""); | |
//these are all the profiles | |
profileKeyNames = GetSubKeyNames(remoteRegistry, HKLM, profileListKeyName); | |
//see which are already loaded into HKU | |
for (i = 0; i < profileKeyNames.length; ++i) | |
{ | |
found = false; | |
profileKeyName = profileKeyNames[i]; | |
for (j = 0; j < existingUserKeyNames.length; ++j) | |
{ | |
if (profileKeyName == existingUserKeyNames[j]) | |
{ | |
found = true; | |
break; | |
} | |
} | |
if (!found) | |
loaded.push(profileKeyName); | |
} | |
fileCopied = false; | |
//user has requested that the file be deployed on the remote machine via the /installregfrompath switch | |
if (WScript.Arguments.Named.Exists("installregfrompath") && (0 != loaded.length)) | |
{ | |
fileCopied = CopySharedFileToSystemFolder(locator, computerName, user, password, WScript.Arguments.Named("installregfrompath"), logFile); | |
} | |
//load each of the profiles | |
for (i = 0; i < loaded.length; ++i) | |
{ | |
profileKeyName = loaded[i]; | |
//retrieve the path to ntuser.dat | |
path = GetStringValue(remoteRegistry, HKLM, profileListKeyName + "\\" + profileKeyName, "ProfileImagePath"); | |
//this will copy the file over to the destination machine and it will run it | |
//run under the user account specified | |
//commandLine = "psexec \\\\" + computerName + " -c -u " + user + " -p " + password + " reg.exe load HKU\\" + profileKeyName + " \"" + path + "\\ntuser.dat\""; | |
//run psexec under the system account | |
if (fileCopied) | |
//watch out! NT 4 reg.exe took path first, then key... the new version takes key first, then path - go figure | |
commandLine = "psexec \\\\" + computerName + " -s reg.exe load HKU\\" + profileKeyName + " \"" + path + "\\ntuser.dat\""; | |
else | |
commandLine = "psexec \\\\" + computerName + " -c -s reg.exe load HKU\\" + profileKeyName + " \"" + path + "\\ntuser.dat\""; | |
WriteToLog(logFile, "Loading User Registry Hive - Command Line [" + commandLine + "]"); | |
//wait for it to finish executing | |
returnCode = shell.Run(commandLine, SW_HIDE, true); | |
//generally bad news | |
if ((null == returnCode) || (0 != returnCode)) | |
{ | |
WriteToLog(logFile, "** ERROR : psexec could not be run succesfully - all user hives may not be loaded..."); | |
} | |
} | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : Could Not Load User Hives - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return loaded; | |
} | |
//the assumption is that the sharedPath is valid | |
function CopySharedFileToSystemFolder(locator, computerName, user, password, sharedPath, logFile) | |
{ | |
var service; | |
var localSystemDirectory, localCopiedPath; | |
var foundIndex, remotePath, driveLetter; | |
var success = true; | |
try | |
{ | |
if (("" == user) || (null == user)) | |
service = locator.ConnectServer(computerName, "root\\cimv2"); | |
else if (null == password) | |
service = locator.ConnectServer(computerName, "root\\cimv2", user); | |
else | |
service = locator.ConnectServer(computerName, "root\\cimv2", user, password); | |
//set the appropriate security | |
service.Security_.ImpersonationLevel = ImpersonationLevelImpersonate; | |
service.Security_.AuthenticationLevel = AuthenticationLevelConnect; | |
//we've already validated this as a server style path that exists | |
foundIndex = sharedPath.lastIndexOf("\\"); | |
remotePath = sharedPath.substr(0, foundIndex); | |
driveLetter = FindAvailableDriveLetter(service); | |
//this should never happen - there are 52 available slots to work with | |
if ("" != driveLetter) | |
{ | |
localSystemDirectory = GetSystemDirectory(service); | |
localCopiedPath = localSystemDirectory + "\\reg.exe"; | |
//if we don't have a local copy of reg.exe | |
if (!fso.FileExists(localCopiedPath)) | |
{ | |
var win32process = service.Get("Win32_Process"); | |
var createMethod = win32process.Methods_.Item("Create"); | |
var startupInfo = service.Get("Win32_ProcessStartup"); | |
inParameters = createMethod.InParameters.SpawnInstance_(); | |
//share the remote path as a local drive letter | |
inParameters.CommandLine = "net use " + driveLetter + ": " + remotePath; | |
inParameters.ProcessStartupInformation = startupInfo; | |
inParameters.ProcessStartupInformation.PriorityClass = PriorityClassHigh; | |
inParameters.ProcessStartupInformation.ShowWindow = SW_HIDE; | |
methodResult = win32process.ExecMethod_(createMethod.Name, inParameters); | |
//couldn't execute the net use | |
if ((null == methodResult) || (0 != methodResult.ReturnValue)) | |
{ | |
WriteToLog(logFile, "** ERROR : Could Not Share Path [" + remotePath + "] As [" + driveLetter + ":] - Error [" + (null == methodResult) ? "undefined" : methodResult.ReturnValue); | |
success = false; | |
} | |
//it worked, so keep try to copy the file now | |
else | |
{ | |
WriteToLog(logFile, "Path [" + remotePath + "] Sucesfully Shared As [" + driveLetter + ":]"); | |
//use WMI to select the remote file (referenced by local drive letter) | |
var queryResult = service.ExecQuery("Select * from CIM_DataFile Where Name = '" + driveLetter + ":\\\\reg.exe'"); | |
//copy the one matched file over to our system directory | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
returnValue = e.item().Copy(localCopiedPath); | |
break; | |
} | |
if (0 != returnValue) | |
{ | |
success = false; | |
WriteToLog(logFile, "** ERROR : Could Not Copy File [" + driveLetter + ":\\\\reg.exe] To [" + localCopiedPath + "] - Error [" + (null == methodResult) ? "undefined" : methodResult.ReturnValue + "]"); | |
} | |
else | |
{ | |
WriteToLog(logFile, "File [" + driveLetter + ":\\\\reg.exe] sucesfully copied to System Directory as [" + localCopiedPath + "]"); | |
} | |
//delete the share | |
inParameters.CommandLine = "net use " + driveLetter + ": /d"; | |
methodResult = win32process.ExecMethod_(createMethod.Name, inParameters); | |
//generally bad news | |
if ((null == methodResult) || (0 != methodResult.ReturnValue)) | |
{ | |
WriteToLog(logFile, "** ERROR : Could Not Delete Share Path [" + remotePath + "] As [" + driveLetter + ":] - Error [" + (null == methodResult) ? "undefined" : methodResult.ReturnValue + "]"); | |
} | |
else | |
{ | |
WriteToLog(logFile, "Shared Path [" + driveLetter + ":] succesfully deleted..."); | |
} | |
} | |
} | |
//file already exists at destination | |
else | |
{ | |
//not an error per se - still return success | |
WriteToLog(logFile, "Local File [" + localCopiedPath + "] already exists - NOT performing copy..."); | |
} | |
} | |
//Could not find an available drive letter | |
else | |
{ | |
success = false; | |
WriteToLog(logFile, "** ERROR : Could Not Find Available Drive Letter To Map Share..."); | |
} | |
} | |
//something bad happened | |
catch (ex) | |
{ | |
success = false; | |
WriteToLog(logFile, "** ERROR : Could Not Copy File [" + sharedPath + "] to Computer [" + computerName + "] - Error [" + hexString(ex.number) + " / " + ex.message + "]"); | |
} | |
return success; | |
} | |
function FindAvailableDriveLetter(service) | |
{ | |
var i = 0, found = false; | |
var startLetter = "Z"; | |
var usedLetters = new Array(); | |
var availableLetter = ""; | |
//use WMI to get logical disk info | |
var queryResult = service.ExecQuery("Select * from Win32_LogicalDisk"); | |
var e = new Enumerator(queryResult); | |
for(; ! e.atEnd(); e.moveNext()) | |
{ | |
//copy the file locally to the system directory | |
usedLetters.push(e.item().DeviceID); | |
} | |
while (startLetter >= "A") | |
{ | |
for (i = 0; i < usedLetters.length; ++i) | |
{ | |
if ((startLetter + ":") == usedLetters[i].toUpperCase()) | |
{ | |
//we've found a match - can't use this letter | |
break; | |
} | |
} | |
if (!found) | |
{ | |
availableLetter = startLetter; | |
break; | |
} | |
//decrement the starting letter | |
startLetter = String.fromCharCode(--startLetter.charCodeAt(0)); | |
} | |
return availableLetter; | |
} | |
function DeleteNetworkPrinterLocalSettings(remoteRegistry, serverName, printerName, logFile) | |
{ | |
var i, j, foundIndex; | |
var printerSearchString = "," + serverName.toUpperCase() + "," + printerName.toUpperCase(); | |
var printerKeyNames, currentControlSetName; | |
for (i = 0; i < controlSetKeyNames.length; ++i) | |
{ | |
currentControlSetName = controlSetKeyNames[i] + "\\Control\\Print\\Printers"; | |
printerKeyNames = GetSubKeyNames(remoteRegistry, HKLM, currentControlSetName); | |
for (j = 0; j < printerKeyNames.length; ++j) | |
{ | |
foundIndex = printerKeyNames[j].toUpperCase().indexOf(printerSearchString); | |
if ((-1 != foundIndex) && (printerKeyNames[j].length == (foundIndex + printerSearchString.length))) | |
{ | |
DeleteRegistryKey(remoteRegistry, HKLM, currentControlSetName + "\\" + printerKeyNames[j], logFile); | |
} | |
} | |
} | |
printerKeyNames = GetSubKeyNames(remoteRegistry, HKLM, localPrinterKeyName); | |
for (i = 0; i < printerKeyNames.length; ++i) | |
{ | |
foundIndex = printerKeyNames[j].toUpperCase().indexOf(printerSearchString); | |
if ((-1 != foundIndex) && (printerKeyNames[j].length == (foundIndex + printerSearchString.length))) | |
{ | |
DeleteRegistryKey(remoteRegistry, HKLM, localPrinterKeyName + "\\" + printerKeyNames[j], logFile); | |
} | |
} | |
//TODO: what's the deal here? | |
//HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control\Print\Environments\Windows NT x86\Drivers\Version-3\Konica 7030 PS | |
} | |
/* | |
Registry Helper Functions | |
*/ | |
function GetSubKeyNames(remoteRegistry, rootKey, keyName) | |
{ | |
var enumMethod = remoteRegistry.Methods_.Item("EnumKey"); | |
var inParameters = enumMethod.InParameters.SpawnInstance_(); | |
inParameters.hDefKey = rootKey; | |
inParameters.sSubKeyName = keyName; | |
var methodResult = remoteRegistry.ExecMethod_(enumMethod.Name, inParameters); | |
if ((null == methodResult) || (null == methodResult.sNames)) | |
return new Array(); | |
//return methodResult.Properties_.Item("sNames").toArray(); | |
return methodResult.sNames.toArray(); | |
} | |
function GetMultiStringValues(remoteRegistry, rootKey, keyName, valueName) | |
{ | |
var getMultiStringMethod = remoteRegistry.Methods_.Item("GetMultiStringValue"); | |
var inParameters = getMultiStringMethod.InParameters.SpawnInstance_(); | |
inParameters.hDefKey = rootKey; | |
inParameters.sSubKeyName = keyName; | |
inParameters.sValueName = valueName; | |
var methodResult = remoteRegistry.ExecMethod_(getMultiStringMethod.Name, inParameters); | |
if ((null == methodResult) || (null == methodResult.sValue)) | |
return new Array(); | |
return methodResult.sValue.toArray(); | |
} | |
function GetStringValue(remoteRegistry, rootKey, keyName, valueName) | |
{ | |
var getStringMethod = remoteRegistry.Methods_.Item("GetStringValue"); | |
var inParameters = getStringMethod.InParameters.SpawnInstance_(); | |
inParameters.hDefKey = rootKey; | |
inParameters.sSubKeyName = keyName; | |
inParameters.sValueName = valueName; | |
var methodResult = remoteRegistry.ExecMethod_(getStringMethod.Name, inParameters); | |
if ((null == methodResult) || (null == methodResult.sValue)) | |
return ""; | |
return methodResult.sValue; | |
} | |
function DeleteRegistryKey(remoteRegistry, rootKey, keyName, logFile) | |
{ | |
var deleteKeyMethod = remoteRegistry.Methods_.Item("DeleteKey"); | |
var subKeyNames = GetSubKeyNames(remoteRegistry, rootKey, keyName); | |
var index = 0; | |
for (; index < subKeyNames.length; ++index) | |
{ | |
DeleteRegistryKey(remoteRegistry, rootKey, keyName + "\\" + subKeyNames[index], logFile); | |
} | |
var inParameters = deleteKeyMethod.InParameters.SpawnInstance_(); | |
inParameters.hDefKey = rootKey; | |
inParameters.sSubKeyName = keyName; | |
var methodResult = remoteRegistry.ExecMethod_(deleteKeyMethod.Name, inParameters); | |
if (0 == methodResult.ReturnValue) | |
{ | |
WriteToLog(logFile, "Deleted Registry Key [" + keyName + "]"); | |
++keysDeleted; | |
++totalKeysDeleted; | |
} | |
//ignore this error | |
else if (ERROR_FILE_NOT_FOUND != methodResult.ReturnValue) | |
{ | |
scanError = true; | |
WriteToLog(logFile, "** ERROR : Could Not Delete Registry Key - Error [" + methodResult.ReturnValue + " - " + Error.message + "] - Key [" + keyName + "]"); | |
++keysDeletedFailed; | |
++totalKeysDeletedFailed; | |
} | |
return methodResult.ReturnValue; | |
} | |
function DeleteRegistryValue(remoteRegistry, rootKey, keyName, valueName, logFile) | |
{ | |
var deleteValueMethod = remoteRegistry.Methods_.Item("DeleteValue"); | |
var inParameters = deleteValueMethod.InParameters.SpawnInstance_(); | |
inParameters.hDefKey = rootKey; | |
inParameters.sSubKeyName = keyName; | |
inParameters.sValueName = valueName; | |
var methodResult = remoteRegistry.ExecMethod_(deleteValueMethod.Name, inParameters); | |
if (0 == methodResult.ReturnValue) | |
{ | |
WriteToLog(logFile, "Deleted Registry Value [" + keyName + "\\" + valueName + "]"); | |
++valuesDeleted; | |
++totalValuesDeleted; | |
} | |
//ignore this error | |
else if (ERROR_FILE_NOT_FOUND != methodResult.ReturnValue) | |
{ | |
scanError = true; | |
WriteToLog(logFile, "** ERROR : Could Not Delete Registry Value - Error [" + methodResult.ReturnValue + " - " + Error.message + "] - Value [" + keyName + "\\" + valueName + "]"); | |
++valuesDeletedFailed; | |
++totalValuesDeletedFailed; | |
} | |
return methodResult.ReturnValue; | |
} | |
function hexString(num) | |
{ | |
if (num > 0) | |
return "0x" + num.toString(16); | |
else | |
return "0x" + (num + 0x100000000).toString(16); | |
} | |
function hex(num) | |
{ | |
if (num > 0) | |
return num; | |
else | |
return (num + 0x100000000); | |
} | |
//this is a real hack - but we don't have a choice | |
function IsAvailable(hostName, pings, timeOut, logFile) | |
{ | |
var pingCount, milliseconds; | |
if ((null == hostName) || ("" == hostName)) | |
return false; | |
if ((null == pings) || ("" == pings)) | |
pingCount = 2; | |
else | |
pingCount = pings; | |
if ((null == timeOut) || ("" == timeOut)) | |
milliseconds = 750; | |
else | |
milliseconds = timeOut * 1000; | |
try | |
{ | |
var tempDirectory = shell.ExpandEnvironmentStrings("%TEMP%"); | |
var tempFileName = tempDirectory + "\\ping.test"; | |
if (fso.FileExists(tempFileName)) | |
fso.DeleteFile(tempFileName); | |
shell.Run("%comspec% /c ping.exe -n " + pingCount + " -w " + milliseconds + " " + hostName + " > " + tempFileName, 0, true); | |
var tempFile = fso.OpenTextFile(tempFileName, ForReading, FailIfNotExist, OpenAsDefault); | |
var fileContents = tempFile.ReadAll(); | |
tempFile.Close(); | |
fso.DeleteFile(tempFileName); | |
//we could ping it and get a TTL | |
if (-1 != fileContents.indexOf("TTL=")) | |
return true; | |
} | |
catch (ex) | |
{ | |
WriteToLog(logFile, "** ERROR : IsAvailable failed [" + hexString(ex.number) + " / " + ex.message + "] - Computer [ " + hostName + "]"); | |
} | |
return false; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
============================================================================== | |
============================================================================== | |
Konica Driver Uninstallation Utility | |
Run Date : Fri Jun 13 15:07:27 EDT 2003 | |
Host Executable : C:\WINNT\system32\wscript.exe - Version 5.6.6626 | |
Script Path : C:\Documents and Settings\Administrator.TESTDOMAIN\ripper.js | |
Command Line Arguments : /computerlist:include.txt | |
Run From Computer : TS-W2KDC2 | |
[4] computers listed in file [include.txt] | |
Computers To Scan : | |
TW-NT401 10.5.1.69 TW-W2K5-1 TW-XPRO2 | |
============================================================================== | |
Cleaning Computer [TW-NT401] | |
Operating System : Microsoft Windows NT Workstation | |
Forcing Logoff... | |
Stopping Service [Spooler]... | |
Examining Registry... | |
Loading User Registry Hive - Command Line [psexec \\TW-NT401 -c -s reg.exe load HKU\S-1-5-21-336750941-1657348416-1536833037-500 "C:\WINNT\Profiles\Administrator\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-NT401 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1119 "C:\WINNT\Profiles\apci_mixgroup\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-NT401 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1126 "C:\WINNT\Profiles\apci_1\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-NT401 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1127 "C:\WINNT\Profiles\apci_2\ntuser.dat"] | |
Found NETWORK-installed printer [Konica 7030 PS] using driver [K421PSS.DLL] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\Connections\,,Ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\Settings\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1128\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Printers\Settings\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-500\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-2\Konica 7030 PS] | |
Deleted Registry Key [SYSTEM\ControlSet002\Control\Print\Environments\Windows NT x86\Drivers\Version-2\Konica 7030 PS] | |
Found NETWORK-installed printer [Konica 7030 PS (Copy 2)] using driver [K421PSS.DLL] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1128\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Printers\Settings\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1128\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-500\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Found NETWORK-installed printer [Konica 7030 PS] using driver [K421PSS.DLL] | |
Deleted Registry Key [SYSTEM\ControlSet002\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\ControlSet002\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS] | |
Found NETWORK-installed printer [Konica 7030 PS (Copy 2)] using driver [K421PSS.DLL] | |
Deleted Registry Key [SYSTEM\ControlSet002\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\ControlSet002\Control\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)] | |
Examining File System... | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421ps.hlp] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psc.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\K421PSI3.DLL] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psj.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psk.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psl.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psp.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psq.exe] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421pss.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psu.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psw.hlp] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421pswk.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421pswu.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\k421psx.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\K421PSZ.EXE] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\kc421pb0.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\2\kc421pb0.hlp] | |
Starting Service [Spooler]... | |
Registry Keys Deleted : 15 | |
Registry Values Deleted : 13 | |
Files Deleted : 17 | |
Registry Key Deletion Failures : 0 | |
Registry Value Deletion Failures : 0 | |
File Deletion Failures : 0 | |
============================================================================== | |
============================================================================== | |
Cleaning Computer [10.5.1.69] | |
Operating System : Microsoft Windows 2000 Professional | |
Forcing Logoff... | |
Stopping Service [Spooler]... | |
Examining Registry... | |
Loading User Registry Hive - Command Line [psexec \\10.5.1.69 -c -s reg.exe load HKU\S-1-5-21-2052111302-1801674531-682003330-500 "C:\Documents and Settings\Administrator\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\10.5.1.69 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1126 "C:\Documents and Settings\apci_1\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\10.5.1.69 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1127 "C:\Documents and Settings\apci_2\ntuser.dat"] | |
Found NETWORK-installed printer [Konica 7030 PS] using driver [K421PSS.DLL] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\DsDriver] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\DsSpooler] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PnPData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PrinterDriverData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\DevModes2\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1127\Printers\Connections\,,Ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1127\Printers\Settings\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1127\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1127\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-500\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Printers\DevModes2\\\Ts-w2kdc2\Konica 7030 PS] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Printers\,,ts-w2kdc2,Konica 7030 PS\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Printers\,,ts-w2kdc2,Konica 7030 PS] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\Konica 7030 PS] | |
Found NETWORK-installed printer [Konica 7030 PS (Copy 2)] using driver [K421PSS.DLL] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\DsDriver] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\DsSpooler] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\PnPData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)\PrinterDriverData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS (Copy 2)] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-1126\Printers\DevModes2\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Key [S-1-5-21-343818398-1644491937-1177238915-500\Printers\Connections\,,ts-w2kdc2,Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\Devices\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Value [S-1-5-21-343818398-1644491937-1177238915-500\Printers\DevModes2\\\Ts-w2kdc2\Konica 7030 PS (Copy 2)] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Printers\,,ts-w2kdc2,Konica 7030 PS (Copy 2)\PrinterDriverData] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Printers\,,ts-w2kdc2,Konica 7030 PS (Copy 2)] | |
Examining File System... | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421ps.hlp] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psc.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\K421PSI3.DLL] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psj.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psk.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psl.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psp.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psq.exe] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421pss.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psu.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psw.hlp] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421pswk.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421pswu.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\k421psx.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\K421PSZ.EXE] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\kc421pb0.dll] | |
Deleted File [C:\WINNT\System32\spool\drivers\w32x86\3\kc421pb0.hlp] | |
Starting Service [Spooler]... | |
Registry Keys Deleted : 20 | |
Registry Values Deleted : 15 | |
Files Deleted : 17 | |
Registry Key Deletion Failures : 0 | |
Registry Value Deletion Failures : 0 | |
File Deletion Failures : 0 | |
============================================================================== | |
============================================================================== | |
Cleaning Computer [TW-W2K5-1] | |
Operating System : Microsoft Windows 2000 Professional | |
Forcing Logoff... | |
Stopping Service [Spooler]... | |
Examining Registry... | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1109 "C:\Documents and Settings\apci_user\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1113 "C:\Documents and Settings\test1\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1114 "C:\Documents and Settings\test2\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1127 "C:\Documents and Settings\apci_2\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1128 "C:\Documents and Settings\apci_3\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-790525478-152049171-1060284298-500 "C:\Documents and Settings\Administrator\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1107 "C:\Documents and Settings\d709arp\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1126 "C:\Documents and Settings\D709SAD\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1130 "C:\Documents and Settings\d709gjl\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1148 "C:\Documents and Settings\d711rpr\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1152 "C:\Documents and Settings\d711gas\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1157 "C:\Documents and Settings\D711rjv\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-W2K5-1 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1285 "C:\Documents and Settings\apci_user.NSSG\ntuser.dat"] | |
Examining File System... | |
Starting Service [Spooler]... | |
Registry Keys Deleted : 0 | |
Registry Values Deleted : 0 | |
Files Deleted : 0 | |
Registry Key Deletion Failures : 0 | |
Registry Value Deletion Failures : 0 | |
File Deletion Failures : 0 | |
============================================================================== | |
============================================================================== | |
Cleaning Computer [TW-XPRO2] | |
Operating System : Microsoft Windows XP Professional | |
* WARNING : Cannot force logoff on Windows XP b/c of a known Microsoft WMI bug... | |
* WARNING : The following sessions could potentially lock files - check log for file deletion errors: | |
* WARNING : User [SYSTEM] logged in under Session ID [999] as [Unknown (0)] - Status [OK] | |
* WARNING : User [LOCAL SERVICE] logged in under Session ID [997] as [Service (5)] - Status [OK] | |
* WARNING : User [NETWORK SERVICE] logged in under Session ID [996] as [Service (5)] - Status [OK] | |
* WARNING : User [\\TESTDOMAIN\Administrator] logged in under Session ID [57784] as [Interactive (2)] - Status [OK] | |
* WARNING : User [\\TESTDOMAIN\Administrator] logged in under Session ID [486277] as [Network (3)] - Status [OK] | |
* WARNING : User [\\TESTDOMAIN\Administrator] logged in under Session ID [486181] as [Network (3)] - Status [OK] | |
* WARNING : User [\\TESTDOMAIN\Administrator] logged in under Session ID [485881] as [Network (3)] - Status [OK] | |
* WARNING : User [ANONYMOUS LOGON] logged in under Session ID [46447] as [Network (3)] - Status [OK] | |
Stopping Service [Spooler]... | |
Examining Registry... | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-1822439336-1161744426-439199626-1005 "C:\Documents and Settings\test\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-1822439336-1161744426-439199626-500 "C:\Documents and Settings\Administrator\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1109 "C:\Documents and Settings\apci_user\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1130 "C:\Documents and Settings\apci_5\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-343818398-1644491937-1177238915-1132 "C:\Documents and Settings\apci_7\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1157 "C:\Documents and Settings\d711rjv\ntuser.dat"] | |
Loading User Registry Hive - Command Line [psexec \\TW-XPRO2 -c -s reg.exe load HKU\S-1-5-21-852520110-1269919429-925700815-1285 "C:\Documents and Settings\apci_user.NSSG\ntuser.dat"] | |
Found NETWORK-installed printer [Konica 7030 PS] using driver [K421PSS.DLL] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\DsDriver] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\DsSpooler] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PnPData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS\PrinterDriverData] | |
Deleted Registry Key [SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\LanMan Print Services\Servers\Ts-w2kdc2\Printers\Konica 7030 PS] | |
Deleted Registry Key [SYSTEM\CurrentControlSet\Control\Print\Environments\Windows NT x86\Drivers\Version-3\Konica 7030 PS] | |
Examining File System... | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421ps.hlp] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psc.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\K421PSI3.DLL] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psj.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psk.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psl.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psp.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psq.exe] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421pss.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psu.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psw.hlp] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421pswk.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421pswu.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\k421psx.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\K421PSZ.EXE] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\kc421pb0.dll] | |
Deleted File [C:\WINDOWS\System32\spool\drivers\w32x86\3\kc421pb0.hlp] | |
Starting Service [Spooler]... | |
Registry Keys Deleted : 6 | |
Registry Values Deleted : 0 | |
Files Deleted : 17 | |
Registry Key Deletion Failures : 0 | |
Registry Value Deletion Failures : 0 | |
File Deletion Failures : 0 | |
============================================================================== | |
============================================================================== | |
Script Action Summary | |
Total Computers Set To Scan : 4 | |
Total Computers Scanned : 4 | |
Successfully : 4 | |
With Errors : 0 | |
Total Computers Unavailable : 0 | |
Total Computers Ignored / Aborted By User : 0 | |
Total Registry Keys Deleted : 41 | |
Total Registry Values Deleted : 28 | |
Total Files Deleted : 51 | |
Total Registry Key Deletion Failures : 0 | |
Total Registry Value Deletion Failures : 0 | |
Total File Deletion Failures : 0 | |
============================================================================== | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment