Printer Spooler and Driver Cleanout Script

All the random crap I spend all day long figuring out.
Post Reply
User avatar
syntax
Site Admin
Posts: 54
Joined: Tue Jan 06, 2009 9:25 pm

Printer Spooler and Driver Cleanout Script

Post by syntax »

requires: psexec.exe for remote and printer vbs scripts under C:\Windows\System32\Printing_Admin_Scripts\en-US

Script can be ran via double-click or via command line, on a remote machine or local machine
Command line:
batchfilename.bat pcname [localtoo] [reboot]

localtoo = delete local printers and drivers
reboot = reboot when finished

Code: Select all

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set tst="%windir%\$del_me$"
(type nul>%tst%) 2>nul && (del %tst% & set elev=YES) || (set elev=NO)

SET "BATDIR=%~dp0"
SET "BATFILE=%~nx0"
SET "BATDRIVE=%BATDIR:~0,2%"
CALL SET BATDIR=%%BATDIR:~0,-1%%
SET "SOURCE=%BATDIR%\%BATFILE%"

IF EXIST "%BATDIR%\psexec.exe" (
	SET "PSEXEC=%BATDIR%\psexec.exe"
)
IF EXIST "%BATDIR%\PsTools\psexec.exe" (
	SET "PSEXEC=%BATDIR%\PsTools\psexec.exe"
)

SET "SCRIPTS_PATH=C:\Windows\System32\Printing_Admin_Scripts\en-US"
SET REMOTE=0
SET LOCALTOO=0
SET LOCAL_DRIVERS=
SET LOCAL_PRINTERS=
SET NUM_LOCAL_DRIVERS=0
SET NUM_LOCAL_PRINTERS=0

IF "%1*"=="localtoo*" (
	SET LOCALTOO=1
)
IF "%2*"=="localtoo*" (
	SET LOCALTOO=1
)

IF "%1*"=="remote*" (
	SET REMOTE=1
	GOTO LOCAL
)
IF "%2*"=="remote*" (
	SET REMOTE=1
	GOTO LOCAL
)
IF NOT "%1*"=="*" (
	SET "PCNAME=%1"
	GOTO REMOTE2
)

echo.
echo.
choice /c LRC /M "[L]ocal Computer or [R]remote?  Or [C]ancel: "
IF %ERRORLEVEL%==3 GOTO END
IF %ERRORLEVEL%==2 SET REMOTE=1

echo.
echo.
choice /c YNC /M "Remove Local Printers as well?: "
IF %ERRORLEVEL%==3 GOTO END
IF %ERRORLEVEL%==1 SET LOCALTOO=1
IF "%REMOTE%"=="0" GOTO LOCAL
GOTO REMOTE

:REMOTE
SET REMOTE=1
echo.
echo.
set /p "PCNAME=Enter PC Name: "
:REMOTE2
IF "%PCNAME%"=="" GOTO END

if not exist "%PSEXEC%" (
	echo.
	echo "%PSEXEC%" not found
	echo.
	IF "%1*"=="*" pause
	goto END
)

copy /y "%SOURCE%" "\\%PCNAME%\C$\Windows\temp"
IF NOT EXIST "\\%PCNAME%\C$\Windows\temp\%BATFILE%" (
	echo.
	echo Error copying batch to remote machine.
	echo.
	pause
	GOTO END
)

IF "%LOCALTOO%"=="1" (
	"%PSEXEC%" \\%PCNAME% -s -h -w c:\windows\system32 cmd /c "C:\Windows\temp\%BATFILE%" remote localtoo
) ELSE (
	"%PSEXEC%" \\%PCNAME% -s -h -w c:\windows\system32 cmd /c "C:\Windows\temp\%BATFILE%" remote
)
GOTO finish_remote

:LOCAL
IF %elev%==NO (
	echo.
	echo.
	echo NOT RUN AS ADMIN!  -- Right click and "Run as Administrator"
	echo.
	echo.
	pause
	GOTO END
)
cls
GOTO DOIT

:DOIT
SET DOITAGAIN=1
:DOITAGAIN
IF NOT EXIST "%SCRIPTS_PATH%\prnmngr.vbs" (
	echo.
	echo.
	echo "%SCRIPTS_PATH%\prnmngr.vbs" not found
	echo.
	pause
	GOTO END
)

IF "%LOCALTOO%"=="1" (
	CALL:RESTART_SPOOLER
	echo.
	echo Generating list of current local printers and purging queues...
	echo.
) ELSE (
	echo.
	echo Generating list of current local printers...
	echo.
)

SET PNAME=
SET PLOCAL=0
SET PDRIVER=
	
for /F "tokens=1-2*" %%A IN ('cscript.exe //nologo %SCRIPTS_PATH%\prnmngr.vbs -l') DO (
	IF %%A*==Printer* (
		IF %%B*==name* (
			SET "PNAME=%%C"
			SET PLOCAL=0
			SET PDRIVER=
		)
	)
	
	IF %%A*==Port* (
		IF %%B*==name* (
			echo "%%C"|findstr /r "^.*[0-9].*\.[0-9].*\.[0-9].*\.[0-9].*$" >nul
			IF ERRORLEVEL 1 (
				SET PLOCAL=1
			) ELSE (
				cscript.exe //nologo %SCRIPTS_PATH%\prnport.vbs -l|find /i "Port name %%C">nul
				IF NOT ERRORLEVEL 1 (
					SET PLOCAL=1
					IF "%LOCALTOO%"=="0" (
						echo.
						echo.
						echo **************************************************************
						echo *  Warning: Network printer added as local printer detected  *
						echo **************************************************************
						echo.
						ping localhost -n 5 >nul
					)
				)
			)
		)
	)
	
	IF %%A*==Driver* (
		IF %%B*==name* (
			IF NOT "%%C*"=="*" (
				SET "PDRIVER=%%C"
			)
		)
	)
	 
	IF %%A*==Printer* (
		IF %%B*==status* (
			IF NOT "!PNAME!*"=="*" (
				IF "!PLOCAL!"=="1" (
					IF NOT "!PDRIVER!*"=="*" (
						echo "!LOCAL_DRIVERS!*"|find /i "!PDRIVER!;">nul
						IF ERRORLEVEL 1 (
							SET /A "NUM_LOCAL_DRIVERS=NUM_LOCAL_DRIVERS+1"
							SET "LOCAL_DRIVERS=!PDRIVER!;!LOCAL_DRIVERS!"
						)
					)
					SET /A "NUM_LOCAL_PRINTERS=NUM_LOCAL_PRINTERS+1"
					SET "LOCAL_PRINTERS=!PNAME!;!LOCAL_PRINTERS!"
					IF "%LOCALTOO%"=="1" (
						echo.
						echo Cleaning print queue for "!PNAME!" ...
						cscript.exe //nologo %SCRIPTS_PATH%\prnqctl.vbs -x -p "!PNAME!"
						echo.
						echo.
					)
					IF "%LOCALTOO%"=="0" (
						echo.
						echo Local printer identified: "!PNAME!"
						echo.
					)
				)
			)
			SET PNAME=
			SET PLOCAL=0
			SET PDRIVER=
		)
	)
)

IF "%LOCALTOO%"=="1" (
	IF "%DOITAGAIN%*"=="1*" (
		SET DOITAGAIN=0
		GOTO DOITAGAIN
	)
	CALL:RESTART_SPOOLER
)

echo.
REM ECHO Num Local printers: %NUM_LOCAL_PRINTERS%
REM ECHO Num Local drivers: %NUM_LOCAL_DRIVERS%
REM echo Printers: %LOCAL_PRINTERS%
REM echo Drivers: %LOCAL_DRIVERS%
REM echo.

IF "%LOCALTOO%"=="1" (
	echo.
	echo Removing all printers...
	echo.
	SET SWITCH=x
) ELSE (
	echo.
	echo Removing only network printers...
	echo.
	SET SWITCH=xc
)

cscript.exe //nologo %SCRIPTS_PATH%\prnmngr.vbs -%SWITCH%

set /a "i = 0"
:again_printers
SET /a "i = i + 1"
IF %i% GEQ 11 (
	echo.
	echo Could not delete all printers.  Check queues.
	echo.
	pause
)

echo.

SET "TEXTTOFIND=printers and connections enumerated 0"
IF "%LOCALTOO%"=="0" SET "TEXTTOFIND=printer connections enumerated 0"

cscript.exe //nologo %SCRIPTS_PATH%\prnmngr.vbs -%SWITCH%|find /i "%TEXTTOFIND%">nul

echo.

if "%ERRORLEVEL%"=="1" (
	echo.
	echo Printers still remaining:
	echo.
	cscript.exe //nologo %SCRIPTS_PATH%\prnmngr.vbs -l
	echo.
	CALL:RESTART_SPOOLER
	GOTO again_printers
)

echo.
REG DELETE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider" /f >nul
echo.

CALL:RESTART_SPOOLER

IF "%LOCALTOO%"=="1" (
	echo.
	echo Removing all drivers...
	echo.
	goto remove_all
) ELSE (
	echo.
	echo Removing drivers not used by local printers...
	echo.
	GOTO remove_network
)

:remove_all
echo.
cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -x>nul
echo.

set /a "i = 0"
:again_driver
SET /a "i = i + 1"
IF %i% GEQ 50 (
	echo.
	echo Could not delete all printer drivers.  Try rebooting.
	echo.
	pause
)

cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -x|find /i "printer drivers enumerated 0" >nul

if "%ERRORLEVEL%"=="1" (
	echo.
	echo Printer drivers still remaining:
	echo.
	
	cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -l|find /i "driver name"
	
	echo.
	REG DELETE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider" /f >nul
	echo.
	
	CALL:RESTART_SPOOLER
	GOTO again_driver
)
echo.
CALL:RESTART_SPOOLER
GOTO finish

:decipher_model_name
SET DNAME=
SET DVER=
SET DENV=
for /F "tokens=1-5 delims=," %%H IN ("%~1") DO (
	IF NOT "%%L*"=="*" (
		SET DENV=%%L
		SET DVER=%%K
		SET "DNAME=%%H,%%I,%%J"
	)
	
	IF "!DNAME!*"=="*" IF NOT "%%K*"=="*" (
		SET DENV=%%K
		SET DVER=%%J
		SET "DNAME=%%H,%%I"
	)
	
	IF "!DNAME!*"=="*" IF NOT "%%J*"=="*" (
		SET DENV=%%J
		SET DVER=%%I
		SET DNAME=%%H
	)
)

exit /b 0

:remove_network
SET INSTALLED_DRIVER_NUM=0
	
for /F "tokens=1-2*" %%A IN ('c:\windows\system32\cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -l^|find /i "driver name"') DO (
	IF "%%A*"=="Driver*" (
		IF "%%B*"=="name*" (
			IF NOT "%%C*"=="*" (
				CALL:decipher_model_name "%%C"
				
				IF NOT "!DNAME!*"=="*" (
					echo "%LOCAL_DRIVERS%"|find /i "!DNAME!;">nul
					IF ERRORLEVEL 1 (
						SET /A "INSTALLED_DRIVER_NUM=INSTALLED_DRIVER_NUM+1"
						SET "INSTALLED_DENV!INSTALLED_DRIVER_NUM!=!DENV!"
						SET "INSTALLED_DVER!INSTALLED_DRIVER_NUM!=!DVER!"
						SET "INSTALLED_DNAME!INSTALLED_DRIVER_NUM!=!DNAME!"
						echo Driver "!DNAME!" will be deleted...
					) ELSE (
						echo Local Driver "!DNAME!" will be skipped...
					)
				)
			)
		)
	)
)

IF "%INSTALLED_DRIVER_NUM%"=="0" (
	echo.
	echo ** No non-local drivers found **
	echo.
	IF NOT "%1*"=="*" GOTO END
	GOTO finish
) ELSE (
	echo.
	echo Identified %INSTALLED_DRIVER_NUM% drivers to uninstall...
	echo.
)

set /a "i = 0"
:again_network_drivers
SET /a "i = i + 1"
IF %i% GEQ 50 (
	echo.
	echo Could not delete all printer drivers.  Try rebooting.
	echo.
	pause
)


for /L %%A IN (1,1,%INSTALLED_DRIVER_NUM%) DO (
	IF NOT "!INSTALLED_DNAME%%A!*"=="*" (
		echo Attempting removal of "!INSTALLED_DNAME%%A!,!INSTALLED_DVER%%A!,!INSTALLED_DENV%%A!" ...
		
		cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -d -m "!INSTALLED_DNAME%%A!" -e "!INSTALLED_DENV%%A!" -v !INSTALLED_DVER%%A!|find /i "Deleted printer driver">nul
		
		if !ERRORLEVEL!==0 (
			SET !INSTALLED_DNAME%%A!=
		)
	)
)

echo.
cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -l|find /i "printer drivers enumerated %NUM_LOCAL_DRIVERS%" >nul
echo.

if %ERRORLEVEL%==1 (
	echo.
	echo Printer drivers still remaining:
	echo.
	
	cscript.exe //nologo %SCRIPTS_PATH%\prndrvr.vbs -l|find /i "driver name"
	
	echo.
	REG DELETE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider" /f >nul
	
	echo.
	CALL:RESTART_SPOOLER
	GOTO again_network_drivers
)
echo.
CALL:RESTART_SPOOLER
GOTO finish

:finish
echo.
echo Drivers cleaned.
echo.
echo ****************************************
echo Reboot the computer to complete the fix.
echo ****************************************
IF NOT "%1*"=="*" GOTO END
:finish_remote
IF NOT "%1*"=="*" (
	IF "%2*"=="reboot*" shutdown /r /t 5 /m \\%1
	IF "%3*"=="reboot*" shutdown /r /t 5 /m \\%1
	GOTO END
)
echo.
echo.
choice /c YN /M "Reboot Computer? "
IF "%ERRORLEVEL%"=="1" (
	IF "%REMOTE%"=="0" (
		shutdown /r /t 5
	) ELSE (
		shutdown /r /t 5 /m \\%PCNAME%
	)
)
GOTO END

:RESTART_SPOOLER
net stop spooler
net start spooler
exit /b 0

:END
Post Reply