Offline Printer Install - Install TCP/IP printers from batch file

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Offline Printer Install - Install TCP/IP printers from batch file

Post by MigrationUser »

16 Aug 2011 10:00
NDog

This is one of the most advanced batch scripts I have come up with to date, and utilises a lot of stuff I have learnt from ss64 website and forum. I think some of the older members here will be able to see some of their code being used. Also this really highlights the limits of batch scripting such as ! and & characters which should be avoided at all cost. I am sharing this script as it is extremely useful to install IP printers from a batch file without need of a windows print server and also as a thank you to simon and some of the hard working folks around here. Hope you get some use out of it.

Some of the functions involve
-passing strings with spaces into subrountines
-creating virtual arrays
-utilising vbscript
-advanced for /f loop techniques
-mounting user registry hives and changing data
and more crazy stupid things

README.TXT

Code: Select all

===================================
OPI was developed by ndog
Designed to install IP printers easily and reduce the dependancy on having a network print server


FEATURES
===================================
+Printer settings saved in .printer files
+Installs printers by simply selecting desired printer from menu
+Tested working in Windows XP, 2003, 7 32 bit and 64 bit platforms
+Installs printer drivers using printui, most compatible method for unsigned printer drivers
+Can import printer preferences such as greyscale and apply to all user accounts, including uncreated accounts
+Includes option to backup printer settings
+Fully portable and self contained scripts

-Relies on WMI service to be running


TECHNICAL
===================================
*Works on Windows XP and higher
*Config files must be stored in the ~config folder
*Printer drivers must be stored in the same folder as opi.cmd
 can be nested as long as referenced in config file

*Do not use ! or & characters anywhere in the configuration files, either in the settings or config names.
 Doing so will render the script useless due to batch file limitations
 The reason is because batch files can not export single values from the registry
 and involves a complex cleaning process
 Until the code gets ported to autoit please refrain from these characters

e.g. instead of 'B&W', use 'BW'
Example Folder structure

printers\
- ~config\
- Sharp\
- opi.cmd
- saveprinterconfig.cmd

Firstly save your printer drivers in a sub folder

Sharp\
- AR-Mx\PCL6\
- 2kxpVista
- XPVistax64
- MX-x\PCL6\
- 2kXPVista
- XPVistax64

Secondly create your .printer files in the ~config folder

Admin Photocopier (BW) - Sharp MX-3501N.printer

Code: Select all

PrnNm=Admin Photocopier (BW) - Sharp MX-3501N
PrnLn=Admin Block
PrnCt=Random Primary School
PrtIP=192.168.10.36
PrnPl=RAW

PrnDrvr=SHARP MX-3501N PCL6

DrvPath_winxp_x86=Sharp\MX-x\PCL6\2kXPVista
InfFile_winxp_x86=sn0ejenu.inf
PrnDrvr_winxp_x86=

DrvPath_win2003_x86=Sharp\MX-x\PCL6\2kXPVista
InfFile_win2003_x86=sn0ejenu.inf
PrnDrvr_win2003_x86=

DrvPath_win7_x86=Sharp\MX-x\PCL6\2kXPVista
InfFile_win7_x86=sn0ejenu.inf
PrnDrvr_win7_x86=

DrvPath_win7_x64=Sharp\MX-x\PCL6\XPVistax64
InfFile_win7_x64=sn0emenu.inf
PrnDrvr_win7_x64=

Work Room Photocopier (BW) - Sharp AR-M550U.printer

PrnNm=Work Room Photocopier (BW) - Sharp AR-M550U
PrnLn=Work Room
PrnCt=Random Primary School
PrtIP=192.168.10.3
PrnPl=RAW

PrnDrvr=SHARP AR-M550U PCL6_T1

DrvPath_winxp_x86=Sharp\AR-Mx\PCL6\2kXPVista
InfFile_winxp_x86=sf0ewenu.inf
PrnDrvr_winxp_x86=

DrvPath_win2003_x86=Sharp\AR-Mx\PCL6\2kXPVista
InfFile_win2003_x86=sf0ewenu.inf
PrnDrvr_win2003_x86=

DrvPath_win7_x86=Sharp\AR-Mx\PCL6\2kXPVista
InfFile_win7_x86=sf0ewenu.inf
PrnDrvr_win7_x86=

DrvPath_win7_x64=Sharp\AR-Mx\PCL6\XPVistax64
InfFile_win7_x64=sf0emenu.inf
PrnDrvr_win7_x64=
opi.cmd

Code: Select all

@echo off&cls
setlocal

title Offline Printer Installer
rem last updated @ 10:51 p.m. 11/08/2011

:: RUN AS ADMINISTRATOR!!!

:: opi is designed to install IP printers offline
:: It reads information from config files stored in ~config folder
:: Depending on the OS and architecture it will install the appropriate driver
:: It will install RAW or LPR printers and setup the defined IP addresses
:: It can also restore printer preferences if they have been backed up prior

set _vbs=%temp%\opi.vbs

rem Scan ~config folder for .printer files. Strip .printer file extension and pass string to sub routine
for /f "tokens=*" %%g in ('dir /b/on "%~dp0~config\*.printer" 2^>nul') do (call :sub_printermenu "%%~ng")
goto :mainprintermenu

rem Sub routine needed to act as counter (otherwise delayed expansion required). Saves array to memory
:sub_printermenu
rem strip "" characters from the %1 string, needed to pass strings with spaces
set called=%1
set called=%called:~1%
set called=%called:~0,-1%
set /a _count+=1
set _menu_%_count%=%called%
goto :eof


:mainprintermenu
cls
set _profile=
set _choice=
echo      ---=== CHOSE A PRINTER TO INSTALL ===---
echo.
for /f "usebackq tokens=2-3* delims=_=" %%g in (`set _menu 2^>nul`) do (echo   %%g - %%h)
echo.
set /p _choice=Choose a printer (q to quit): 

if "%_choice%" equ "" goto :mainprintermenu
if "%_choice%" equ "q" goto :end
if "%_choice%" gtr "0" if "%choice%" lss "%_count%" for /f "usebackq tokens=2-3* delims=_=" %%g in (`set _menu 2^>nul`) do (if %%g equ %_choice% set _profile=%%h)
if not defined _profile goto :mainprintermenu
for /f "usebackq tokens=1* delims==" %%g in ("%~dp0~config\%_profile%.printer") do (set _%%g=%%h)


rem Detect operating system
for /f "tokens=*" %%a in ('ver') do set _ver=%%a

if "%_ver%" == "Microsoft Windows XP [Version 5.1.2600]" set _os=winxp
if "%_ver%" == "Microsoft Windows [Version 5.2.3790]" set _os=win2003
if "%_ver%" == "Microsoft Windows [Version 6.1.7600]" set _os=win7
if "%_ver%" == "Microsoft Windows [Version 6.1.7601]" set _os=win7

if not defined _os (echo Operating system not supported -- %_ver%&pause&exit)


rem Detect OS Architecture
rem reg query "HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0" | find /i "x86" >nul
rem if %errorlevel% == 1 (set _osarch=x64) else (set _osarch=x86)

if "%PROCESSOR_ARCHITECTURE%" equ "x86" set _osarch=x86
if "%PROCESSOR_ARCHITECTURE%" equ "AMD64" set _osarch=x64
if "%PROCESSOR_ARCHITECTURE%" equ "IA64" set _osarch=x64

rem Assign settings depending on system
for /f "usebackq tokens=1-3* delims=_=" %%g in (`set _DrvPath 2^>nul`) do (if "%%h" == "%_os%" if "%%i" == "%_osarch%" set _DrvPath=%%j)
for /f "usebackq tokens=1-3* delims=_=" %%g in (`set _InfFile 2^>nul`) do (if "%%h" == "%_os%" if "%%i" == "%_osarch%" set _InfFile=%%j)
for /f "usebackq tokens=1-3* delims=_=" %%g in (`set _PrnDrvr 2^>nul`) do (if "%%h" == "%_os%" if "%%i" == "%_osarch%" set _PrnDrvr=%%j)
for /f "usebackq tokens=1-3* delims=_=" %%g in (`set _RegPref 2^>nul`) do (if "%%h" == "%_os%" if "%%i" == "%_osarch%" set _RegPref=%%j)

rem Set supported platform
if "%_osarch%" == "x86" set _SupportedPlatform=Windows NT x86
if "%_osarch%" == "x64" set _SupportedPlatform=Windows x64

if exist "%~dp0~config\%_profile%_%_os%_%_osarch%.reg" set _importconfig=%~dp0~config\%_profile%_%_os%_%_osarch%.reg

cls
echo.
echo Selected profile = %_profile%
echo Printer name = %_PrnNm%
echo.
echo Detected OS = %_os% %_osarch%
echo Platform = %_SupportedPlatform%
echo.
echo Driver path = %_DrvPath%
echo Setup file = %_InfFile%
echo Printer driver = %_PrnDrvr%
echo.
echo Printer IP = %_PrtIP%
echo Printer protocol = %_PrnPl%
if defined _PrnLQ echo LPR Queue Name = %_PrnLQ%
echo.
if exist "%_importconfig%" echo Printer config = %_profile%_%_os%_%_osarch%.reg
echo.
echo.

echo Restarting 'Print Spooler' service...
net stop spooler /y 2>nul >nul
net start spooler /y 2>nul >nul

rem install printer driver with prndrvr.vbs (Win32 error code -2146500025)
rem cscript "C:\Windows\System32\Printing_Admin_Scripts\en-US\prndrvr.vbs" -a -m "%_PrnDrvr%" -h "%~dp0%_DrvPath%" -i "%~dp0%_DrvPath%\%_InfFile%"

rem install printer driver with printui.dll (will prompt if unsigned driver, but works!)
echo Installing printer driver...
rundll32 printui.dll,PrintUIEntry /ia /m "%_PrnDrvr%" /f "%~dp0%_DrvPath%\%_InfFile%"

echo Set objFso = CreateObject("Scripting.FileSystemObject") >"%_vbs%"
echo PrnName = "%_PrnNm%" >>"%_vbs%"
echo PrnLocation = "%_PrnLn%" >>"%_vbs%"
echo PrnComment = "%_PrnCt%" >>"%_vbs%"
echo PrnDrv = "%_PrnDrvr%" >>"%_vbs%"
echo DrvPath = "%~dp0%_DrvPath%" >>"%_vbs%"
echo InfFile = DrvPath ^& "\%_InfFile%" >>"%_vbs%"
echo PortIP = "%_PrtIP%" >>"%_vbs%"
echo PortName = "IP_" ^& PortIP >>"%_vbs%"

echo strComputer = "." >>"%_vbs%"
echo Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate, (LoadDriver)}!\\" ^& strComputer ^& "\root\cimv2") >>"%_vbs%"

if "%_PrnPl%" equ "RAW" goto :RAWPRINTER
if "%_PrnPl%" equ "LPR" goto :LPRPRINTER
echo TCPIP Printer not defined... exiting... &pause&goto :END

:RAWPRINTER
echo Set objNewPort = objWMIService.Get _ >>"%_vbs%"
echo ("Win32_TCPIPPrinterPort").SpawnInstance_ >>"%_vbs%"
echo objNewPort.Name = PortName >>"%_vbs%"
echo objNewPort.Protocol = 1 >>"%_vbs%"
echo objNewPort.HostAddress = PortIP >>"%_vbs%"
echo objNewPort.PortNumber = "9100" >>"%_vbs%"
echo objNewPort.SNMPEnabled = False >>"%_vbs%"
echo objNewPort.Put_ >>"%_vbs%"
goto :TCPIPDONE

:LPRPRINTER
echo Set objNewPort = objWMIService.Get _ >>"%_vbs%"
echo ("Win32_TCPIPPrinterPort").SpawnInstance_ >>"%_vbs%"
echo objNewPort.Name = PortName >>"%_vbs%"
echo objNewPort.Protocol = 2 >>"%_vbs%"
echo objNewPort.HostAddress = PortIP >>"%_vbs%"
echo objNewPort.PortNumber = "515" >>"%_vbs%"
echo objNewPort.Queue = "%_PrnLQ%" >>"%_vbs%"
echo objNewPort.ByteCount = True >>"%_vbs%"
echo objNewPort.SNMPEnabled = False >>"%_vbs%"
echo objNewPort.Put_ >>"%_vbs%"
goto :TCPIPDONE

:TCPIPDONE

rem echo objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True >>"%_vbs%"
rem echo Set objDriver = objWMIService.Get("Win32_PrinterDriver") >>"%_vbs%"
rem echo objDriver.Name = PrnDrv >>"%_vbs%"
rem echo objDriver.SupportedPlatform = "%_SupportedPlatform%" >>"%_vbs%"
rem echo objDriver.Version = "3" >>"%_vbs%"
rem echo objDriver.DriverPath = DrvPath >>"%_vbs%"
rem echo objDriver.InfName = InfFile >>"%_vbs%"
rem echo intResult = objDriver.AddPrinterDriver(objDriver) >>"%_vbs%"

echo Set objPrinter = objWMIService.Get("Win32_Printer").SpawnInstance_ >>"%_vbs%"
echo objPrinter.DriverName = PrnDrv >>"%_vbs%"
echo objPrinter.PortName = PortName >>"%_vbs%"
echo objPrinter.DeviceID = PrnName >>"%_vbs%"
echo objPrinter.Location = PrnLocation >>"%_vbs%"
echo objPrinter.Comment = PrnComment >>"%_vbs%"
echo objPrinter.Network = False >>"%_vbs%"
echo objPrinter.Put_ >>"%_vbs%"


echo Adding printer...
start /wait "" "%_vbs%"

echo Printer added...
if exist "%_importconfig%" goto :applypreferences
ping localhost -n 6 >nul
goto :mainprintermenu

:applypreferences
echo Applying printer config from file...
rem start /wait "" rundll32 printui.dll,PrintUIEntry /Sr /n "%_PrnNm%" /a "%~dp0~config\%_profile%_%_os%_%_osarch%.dat"
reg import "%_importconfig%" 2>nul >nul

echo Preparing registry...
set _expreg=%temp%\hkcuprinters.reg
del /f "%_expreg%" 2>nul >nul
reg export "HKEY_CURRENT_USER\Printers\DevModePerUser" "%_expreg%" 2>nul >nul

set _impreg=%temp%\hkzimport.reg

set _cleanregcmd=%temp%\crc.cmd
echo @echo off>"%_cleanregcmd%"
echo setlocal enableextensions enabledelayedexpansion>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo :: This is a cleanup script, it cleans up the .reg file generated by opi.cmd for importing into user registry profiles>>"%_cleanregcmd%"
echo :: This script is neccessary due to theses limitations>>"%_cleanregcmd%"
echo :: a) reg export command - Cannot export single values.. duh>>"%_cleanregcmd%"
echo :: b) batch file string limitations - string cannot exceed 8191, therefore long values *must* be imported via .reg file>>"%_cleanregcmd%"
echo :: c) REG_BINARY stores data in weird hex values>>"%_cleanregcmd%"
echo :: not to mention .reg files are unicode>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo set _inreg=%_expreg%>>"%_cleanregcmd%"
echo set _outreg=%_impreg%>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo set _PrnNm="%_PrnNm%">>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo echo Windows Registry Editor Version 5.00 ^>"%%_outreg%%">>"%_cleanregcmd%"
echo echo.^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo echo [HKEY_USERS\ZZZ\Printers\DevModePerUser]^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo :: The for loop will start reading the exported .reg file from top to bottom>>"%_cleanregcmd%"
echo :: It will search for matching value names, when found it will activate a counter>>"%_cleanregcmd%"
echo :: When counter activated it will 'echo out' the strings>>"%_cleanregcmd%"
echo :: When next value name is found it will deactivate the counter and let the script finish the loop>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo    for /f "skip=3 tokens=*" %%%%g in ('type "%%_inreg%%"') do (>>"%_cleanregcmd%"
echo        set line=%%%%g>>"%_cleanregcmd%"
echo        rem LAME ALERT>>"%_cleanregcmd%"
echo        rem 1 - If first parameter is ^" then assume start of value>>"%_cleanregcmd%"
echo        rem 2 - Use the = character to split the value name and value data>>"%_cleanregcmd%"
echo        rem 3 - %%h already has "" quotes around it so do not need to use "" to compare spaced strings>>"%_cleanregcmd%"
echo        set called=!line:~0,1!>>"%_cleanregcmd%"
echo        if [!called!] equ [^^^"] for /f "tokens=1-2* delims==" %%%%h in ("!line!") do (>>"%_cleanregcmd%"
echo            rem echo %%%%h=%%%%i>>"%_cleanregcmd%"
echo            if %%%%h equ %%_PrnNm%% set _active=yes>>"%_cleanregcmd%"
echo            if %%%%h neq %%_PrnNm%% set _active=>>"%_cleanregcmd%"
echo            )>>"%_cleanregcmd%"
echo        if "!_active!" equ "yes" echo !line! ^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo        )>>"%_cleanregcmd%"
echo    echo.^>^>"%%_outreg%%">>"%_cleanregcmd%"

echo Cleaning registry...
start /wait /min "" cmd /c "%_cleanregcmd%"

echo.
echo Applying printer settings to all users...
rem Scans through all 'valid' user profiles and sets to each registry
rem OS specific profile paths
set XP=Documents and Settings
set Vista=Users
for /f "tokens=*" %%g in ('dir /b %HOMEDRIVE%\ 2^>nul') do (
    if "%%g" == "%XP%" (set _profpath=%HOMEDRIVE%\%XP%)
    if "%%g" == "%Vista%" (set _profpath=%HOMEDRIVE%\%Vista%)
    )
for /f "tokens=*" %%g in ('dir /b/ad "%_profpath%" 2^>nul') do (
    if "%%g" neq "All Users" if "%%g" neq "LocalService" if "%%g" neq "NetworkService" (
    if "%%g" neq "Public" (
        echo - Updating %%g
        if "%%g" neq "%USERNAME%" if exist "%_profpath%\%%g\NTUSER.DAT" (
            reg load HKU\ZZZ "%_profpath%\%%g\NTUSER.DAT" 2>nul >nul
            reg import "%_impreg%" 2>nul >nul
            reg unload HKU\ZZZ 2>nul >nul
            )
        )
        )
    )

ping localhost -n 6 >nul
goto :mainprintermenu

:end
del "%temp%\crc.cmd" 2>nul >nul
del "%temp%\hkcuprinters.reg" 2>nul >nul
del "%temp%\hkzimport.reg" 2>nul >nul
del "%temp%\opi.vbs" 2>nul >nul
endlocal
saveprinterconfig.cmd

Code: Select all

@echo off&cls
setlocal

title Save Printer Config
rem last updated @ 10:23 p.m. 11/08/2011

:: RUN AS ADMINISTRATOR!!!

:: Use this script in conjuction with opi.cmd
:: It can backup printer defaults and apply them to all users
:: eg if a printer defaults to colour, you can change it to default to black and white
:: Backups the printer settings from registry
:: - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers
:: - HKEY_CURRENT_USER\Printers\DevModePerUser
:: Creates backup for the OS and architecture. You will need to backup each OS seperately

rem Scan ~config folder for .printer files
set _count=
for /f "tokens=*" %%g in ('dir /b/on "%~dp0~config\*.printer" 2^>nul') do (call :sub_printermenu "%%~ng")
goto :mainprintermenu


:sub_printermenu
set called=%1
set called=%called:~1%
set called=%called:~0,-1%
set /a _count+=1
set _menu_%_count%=%called%
goto :eof

:sub_enumnameprinter
set called=%1
set called=%called:~1%
set called=%called:~0,-1%
set /a _count+=1
set _regprinter_%_count%=%called%

if "%_PrnNm%" equ "%called%" set _selected=%called%

goto :eof


:mainprintermenu
cls
set _profile=
set _choice=
echo      ---=== CHOSE A PRINTER TO BACKUP SETTINGS ===---
echo.
for /f "usebackq tokens=2-3* delims=_=" %%g in (`set _menu 2^>nul`) do (echo   %%g - %%h)
echo.
set /p _choice=Choose a printer (q to quit): 

if "%_choice%" equ "" goto :mainprintermenu
if "%_choice%" equ "q" goto :end
if "%_choice%" gtr "0" if "%choice%" lss "%_count%" for /f "usebackq tokens=2-3* delims=_=" %%g in (`set _menu 2^>nul`) do (if %%g equ %_choice% set _profile=%%h)
if not defined _profile goto :mainprintermenu

rem Scan Registry for Installed Printer Names
for /f "usebackq tokens=1* delims==" %%h in ("%~dp0~config\%_profile%.printer") do (if "%%h" equ "PrnNm" set _%%h=%%i)

set _count=
set _selected=
for /f "tokens=8 delims=\" %%g in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers"') do (call :sub_enumnameprinter "%%g")
if defined _selected goto :printerconfigure

cls
echo.
echo Selected Profile = %_profile%
echo Printer Name = %_PrnNm%
echo.
echo You have not installed "%_PrnNm%" printer yet!
echo Please close this script and run "opi.cmd" to install printer first!
echo.
echo Otherwise printer name may mismatch to what is in your .printer file!
echo If this is the case please rename printer name!
echo.
echo.
echo   --== Installed Printers ==--
echo.
for /f "usebackq tokens=3* delims=_=" %%g in (`set _regprinter 2^>nul`) do (echo    - %%g)
echo.
pause
goto :mainprintermenu


:printerconfigure
rem Detect operating system
for /f "tokens=*" %%a in ('ver') do set _ver=%%a

if "%_ver%" == "Microsoft Windows XP [Version 5.1.2600]" set _os=winxp
if "%_ver%" == "Microsoft Windows [Version 5.2.3790]" set _os=win2003
if "%_ver%" == "Microsoft Windows [Version 6.1.7600]" set _os=win7
if "%_ver%" == "Microsoft Windows [Version 6.1.7601]" set _os=win7

if not defined _os (echo Operating system not supported -- %_ver%&pause&exit)


rem Detect OS Architecture
if "%PROCESSOR_ARCHITECTURE%" equ "x86" set _osarch=x86
if "%PROCESSOR_ARCHITECTURE%" equ "AMD64" set _osarch=x64
if "%PROCESSOR_ARCHITECTURE%" equ "IA64" set _osarch=x64


cls
echo.
echo Selected profile = %_profile%
echo Printer name = %_PrnNm%
echo.
echo Detected OS = %_os% %_osarch%
echo.
echo Configure printer settings to how you want to apply as default to all computers
echo eg if 'black and white' desired ensure 'black and white' / 'greyscale' selected
echo.
echo Press 'OK' to close printer windows after you have entered settings

rem Bring up the printer preferences e.g. [HKCU] B&W, Hold, embeded key
start /wait "" rundll32 printui.dll,PrintUIEntry /e /n "%_selected%"

rem Bring up the printer properties e.g. [HKLM] Popup verify box
start /wait "" rundll32 printui.dll,PrintUIEntry /p /n "%_selected%"

echo.
echo Have you selected with correct defaults?
set /p _choice=Backup settings now? [y]: 
if "%_choice%" neq "y" goto :mainprintermenu

rem printui.dll export method. Only applicable to current machine.
rem start /wait "" rundll32 printui.dll,PrintUIEntry /Ss /n "%_selected%" /a "%~dp0~config\%_profile%_%_os%_%_osarch%.dat"
rem echo.
rem echo Configuration saved as %_profile%_%_os%_%_osarch%.dat

set _regbackup=%~dp0~config\%_profile%_%_os%_%_osarch%.reg

echo.
echo Preparing registry...
set _mchreg=%temp%\hklmprinters.reg
del /f "%_mchreg%" 2>nul >nul
reg export "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\%_selected%\PrinterDriverData" "%_mchreg%" 2>nul >nul

set _expreg=%temp%\hkcuprinters.reg
del /f "%_expreg%" 2>nul >nul
reg export "HKEY_CURRENT_USER\Printers\DevModePerUser" "%_expreg%" 2>nul >nul

set _impreg=%temp%\hkzimport.reg

set _cleanregcmd=%temp%\crc.cmd
echo @echo off>"%_cleanregcmd%"
echo setlocal enableextensions enabledelayedexpansion>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo :: This is a cleanup script, it cleans up the .reg file generated by opi.cmd for importing into user registry profiles>>"%_cleanregcmd%"
echo :: This script is neccessary due to theses limitations>>"%_cleanregcmd%"
echo :: a) reg export command - Cannot export single values.. duh>>"%_cleanregcmd%"
echo :: b) batch file string limitations - string cannot exceed 8191, therefore long values *must* be imported via .reg file>>"%_cleanregcmd%"
echo :: c) REG_BINARY stores data in weird hex values>>"%_cleanregcmd%"
echo :: not to mention .reg files are unicode>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo set _inreg=%_expreg%>>"%_cleanregcmd%"
echo set _outreg=%_impreg%>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo set _PrnNm="%_selected%">>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo echo Windows Registry Editor Version 5.00 ^>"%%_outreg%%">>"%_cleanregcmd%"
echo echo.^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo echo [HKEY_USERS\ZZZ\Printers\DevModePerUser]^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo :: The for loop will start reading the exported .reg file from top to bottom>>"%_cleanregcmd%"
echo :: It will search for matching value names, when found it will activate a counter>>"%_cleanregcmd%"
echo :: When counter activated it will 'echo out' the strings>>"%_cleanregcmd%"
echo :: When next value name is found it will deactivate the counter and let the script finish the loop>>"%_cleanregcmd%"
echo.>>"%_cleanregcmd%"
echo    for /f "skip=3 tokens=*" %%%%g in ('type "%%_inreg%%"') do (>>"%_cleanregcmd%"
echo        set line=%%%%g>>"%_cleanregcmd%"
echo        rem LAME ALERT>>"%_cleanregcmd%"
echo        rem 1 - If first parameter is ^" then assume start of value>>"%_cleanregcmd%"
echo        rem 2 - Use the = character to split the value name and value data>>"%_cleanregcmd%"
echo        rem 3 - %%h already has "" quotes around it so do not need to use "" to compare spaced strings>>"%_cleanregcmd%"
echo        set called=!line:~0,1!>>"%_cleanregcmd%"
echo        if [!called!] equ [^^^"] for /f "tokens=1-2* delims==" %%%%h in ("!line!") do (>>"%_cleanregcmd%"
echo            rem echo %%%%h=%%%%i>>"%_cleanregcmd%"
echo            if %%%%h equ %%_PrnNm%% set _active=yes>>"%_cleanregcmd%"
echo            if %%%%h neq %%_PrnNm%% set _active=>>"%_cleanregcmd%"
echo            )>>"%_cleanregcmd%"
echo        if "!_active!" equ "yes" echo !line! ^>^>"%%_outreg%%">>"%_cleanregcmd%"
echo        )>>"%_cleanregcmd%"
echo    echo.^>^>"%%_outreg%%">>"%_cleanregcmd%"

echo Cleaning registry...
start /wait /min "" cmd /c "%_cleanregcmd%"

set _mergeregcmd=%temp%\mrc.cmd
echo @echo off>"%_mergeregcmd%"
echo setlocal enableextensions enabledelayedexpansion>>"%_mergeregcmd%"
echo.>>"%_mergeregcmd%"
echo :: This script merges hklmprinters.reg and import.reg into one ANSI reg file>>"%_mergeregcmd%"
echo :: This is to reduce the number of reg files needed overall>>"%_mergeregcmd%"
echo :: This method is stupid and may not work on non english OS'es>>"%_mergeregcmd%"
echo.>>"%_mergeregcmd%"
echo set _inreg1=%_mchreg%>>"%_mergeregcmd%"
echo set _inreg2=%_impreg%>>"%_mergeregcmd%"
echo set _outreg=%%temp%%\regout.reg>>"%_mergeregcmd%"
echo.>>"%_mergeregcmd%"
echo set _PrnNm="%_selected%">>"%_mergeregcmd%"
echo.>>"%_mergeregcmd%"
echo set _PrnNm=%%_PrnNm:~1%%>>"%_mergeregcmd%"
echo set _PrnNm=%%_PrnNm:~0,-1%%>>"%_mergeregcmd%"
echo.>>"%_mergeregcmd%"
echo del /f "%%_outreg%%" 2^>nul ^>nul>>"%_mergeregcmd%"
echo echo Windows Registry Editor Version 5.00 ^>^>"%%_outreg%%">>"%_mergeregcmd%"
echo echo.^>^>"%%_outreg%%">>"%_mergeregcmd%"
echo echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\%%_PrnNm%%\PrinterDriverData]^>^>"%%_outreg%%">>"%_mergeregcmd%"
echo for /f "skip=3 tokens=*" %%%%g in ('type "%%_inreg1%%"') do (if "%%%%g" neq "" echo %%%%g ^>^>"%%_outreg%%")>>"%_mergeregcmd%"
echo echo.^>^>"%%_outreg%%">>"%_mergeregcmd%"
echo echo [HKEY_CURRENT_USER\Printers\DevModePerUser]^>^>"%%_outreg%%">>"%_mergeregcmd%"
echo for /f "skip=3 usebackq tokens=*" %%%%g in ("%%_inreg2%%") do (if "%%%%g" neq "" echo %%%%g ^>^>"%%_outreg%%")>>"%_mergeregcmd%"
echo echo.^>^>"%%_outreg%%">>"%_mergeregcmd%"

echo Saving file...
start /wait /min "" cmd /c "%_mergeregcmd%"

del /f "%_regbackup%" 2>nul>nul
copy "%temp%\regout.reg" "%_regbackup%" >nul

echo.
echo Configuration saved as %_profile%_%_os%_%_osarch%.reg

echo.
set /p _choice=Apply this configuration to all user profiles now? [y]: 
if "%_choice%" neq "y" goto :mainprintermenu

echo.
echo Applying printer settings to all users...
rem Scans through all 'valid' user profiles and sets to each registry
rem OS specific profile paths
set XP=Documents and Settings
set Vista=Users
for /f "tokens=*" %%g in ('dir /b %HOMEDRIVE%\ 2^>nul') do (
    if "%%g" == "%XP%" (set _profpath=%HOMEDRIVE%\%XP%)
    if "%%g" == "%Vista%" (set _profpath=%HOMEDRIVE%\%Vista%)
    )
for /f "tokens=*" %%g in ('dir /b/ad "%_profpath%" 2^>nul') do (
    if "%%g" neq "All Users" if "%%g" neq "LocalService" if "%%g" neq "NetworkService" (
    if "%%g" neq "Public" (
        echo - Updating %%g
        if "%%g" neq "%USERNAME%" if exist "%_profpath%\%%g\NTUSER.DAT" (
            reg load HKU\ZZZ "%_profpath%\%%g\NTUSER.DAT" 2>nul >nul
            reg import "%_impreg%" 2>nul >nul
            reg unload HKU\ZZZ 2>nul >nul
            )
        )
        )
    )

ping localhost -n 6 >nul
goto :mainprintermenu

:end
del "%temp%\crc.cmd" 2>nul >nul
del "%temp%\mrc.cmd" 2>nul >nul
del "%temp%\hklmprinters.reg" 2>nul >nul
del "%temp%\hkcuprinters.reg" 2>nul >nul
del "%temp%\hkzimport.reg" 2>nul >nul
del "%temp%\regout.reg" 2>nul >nul
endlocal

More examples....

For an LPR printer

Code: Select all

PrnNm=Upstairs LaserJet Printer (BW) - HP 2500
PrnLn=Upstairs
PrnCt=Office HQ
PrtIP=192.168.1.78
PrnPl=LPR
PrnLQ=HP2500

PrnDrvr=HP Color LaserJet 2500 PCL 6

DrvPath_winxp_x86=HP\HP Color Laserjet 2500\winALL_x86
InfFile_winxp_x86=hpc2500c.inf
PrnDrvr_winxp_x86=

DrvPath_win2003_x86=HP\HP Color Laserjet 2500\winALL_x86
InfFile_win2003_x86=hpc2500c.inf
PrnDrvr_win2003_x86=

DrvPath_win7_x86=HP\HP Color Laserjet 2500\winALL_x86
InfFile_win7_x86=hpc2500c.inf
PrnDrvr_win7_x86=

DrvPath_win7_x64=HP\HP Color Laserjet 2500\winALL_x64
InfFile_win7_x64=hpc2500u.inf
PrnDrvr_win7_x64=
Example Printer that has diffferent drivers

Code: Select all

PrnNm=Office Photocopier (BW)
PrnLn=Resource Room
PrnCt=Awesome School
PrtIP=192.168.1.220
PrnPl=RAW

PrnDrvr=

DrvPath_winxp_x86=KM\bizhub C252\PCL6\NT5_x86
InfFile_winxp_x86=KRH326O2.inf
PrnDrvr_winxp_x86=KONICA MINOLTA C252/C252P PCL

DrvPath_win2003_x86=KM\bizhub C252\PCL6\NT5_x86
InfFile_win2003_x86=KRH326O2.inf
PrnDrvr_win2003_x86=KONICA MINOLTA C252/C252P PCL

DrvPath_win7_x86=KM\bizhub C252\PCL6\NT6_x86
InfFile_win7_x86=KOBZVKB_.inf
PrnDrvr_win7_x86=KONICA MINOLTA C252/C252P VXL

DrvPath_win7_x64=KM\bizhub C252\PCL6\NT6_x64
InfFile_win7_x64=KOBZVLB_.inf
PrnDrvr_win7_x64=KONICA MINOLTA C252/C252P VXL
cmd, vbs, ps, bash
autoit, python, swift

----------------------------

#2 16 Nov 2011 22:01
haberova


I cannot manage to get this to work, but I am not sure if I'm even understanding how the program operates. Does it prompt you for what printer needs to be installed or does it install all of the printers that have ".printer" files setup for them?

I'm running on Windows 7 and get "The arguments are invalid." after line "B:\printers>rundll32 printui.dll,PrintUIEntry /ia /m "" /f "B:\Printers\\"

Then at the end it says TCPIP Printer not defined... exiting...

This batch file seems like exactly what I need if I can get it to work. Any help would be appreciated greatly.

----------------------------

#3 29 Mar 2013 18:37
BadMachine


I registered just to say thank you for this! I was able to get the script configured with the 8 printers we use in the office and backup all of the settings in under 2 hours. After testing on 4 of the new computers we just built everything appears to be working flawlessly. It took less than 4 minutes to install all 8 printers and apply their settings, a task which normally took around 20.

Thanks Again!
Post Reply