Skip navigation

JSI Tip 5825. How do I define a quota for a printer?


I know of no standard way of setting a quota on a printer, so I scripted PrintQuota.bat.

The syntax for using PrintQuota.bat is:

PrintQuota \\ServerName\RealPrinter \\ServerName\QuotaPrinter MaximumBytes \[P \[HH:MM-HH:MM\]\]

where:

Parameter Description
\\ServerName\RealPrinter is the printer that will print the job. I would NOT publish it in Active Directory.
\\ServerName\QuotaPrinter       This is the printer that the user submits their jobs to. It must have the same Print Processor and Default datatype as \\ServerName\RealPrinter. This printer must be paused. You must create a spool folder on your 'print server' for this printer, like <Drive:>\QuotaPrinter, and set the SpoolDirectory Value Name, a REG_SZ data type, at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\<QuotaPrinter> to the spool path (<Drive:>\QuotaPrinter). NOTE: You must restart your 'print server' for these settings to take effect.
MaximumBytes The quota, in bytes. This is the maximum size of the nnnnnn.SPL file (at <Drive:>\QuotaPrinter) that you will allow to be printed. It may take some trial and error to arrive at a suitable value.
P The optional Purge parameter. PrintQuota.bat will automatically clean up the files at SpoolDirectory, but the P parameter is required to purge the documents from the printer queue. Without the HH:MM-HH:MM parameter, the spool will be purged every time that there are no jobs left to be printed. It is possible, but unlikely, that at the same instance that PrintQuota.bat initiates a purge, a user's job arrives for printing. This job may be lost. The purge function is performed by the Resource Kit Prnadmin.dll and PRNCTRL.VBS tools. NOTE: If you don't use the P parameter, someone will have to periodically open the \\ServerName\QuotaPrinter printer and press Cancel All Documents on the Printer menu.
HH:MM-HH:MM Time range, in 24 hour time, to allow purging. Example: 01:00-04:59 or 22:00-23:59. The first HH:MM must be earlier than the second HH:MM.

For each \\ServerName\QuotaPrinter that I define, I created a QuotaPrinter.bat file that contains:

@echo off
:loop
@ping -n 61 127.0.0.1>nul
call printquota \\ServerName\RealPrinter \\ServerName\QuotaPrinter MaximumBytes \[P \[HH:MM-HH:MM\]\]
goto loop
NOTE: You can sleep for whatever number of seconds makes sense in your environment.

I schedule this job to start on the 'print server' at System startup. I uncheck all the boxes on the Settings tab. I use an account that I set up for running jobs in the background, so it won't interfere with anyone who logs onto the 'print server' locally. It should have administrative privileges.

PrintQuota.bat calls a VB Script, SHD.VBS, which must be in your path. SHD.VBS parses the nnnnn.SHD file in the spool (<Drive:>\QuotaPrinter) to send the following message to a user who's job exceeds the quota:

PRINT JOB EXCEEDED QUOTA - <size> - <UserName><UserName><PrintedOject><QuotaPrinter> <QuotaPrinterType><PrintProcessor><DefaultDatatype><\\UsersComputerName>

SHD.VBS contains:

dim fso, text, readfile, contents, x, writefile, SearchFor, ReplaceWith
dim FullFileName, ParentDirName, Filename, NewFilename
Dim objArguments
Set objArguments = Wscript.Arguments
Dim Newfldr
set fso = CreateObject("Scripting.FileSystemObject")
FullFileName=objArguments(0)
NewFilename=objArguments(1)
set readfile = fso.OpenTextFile(FullFileName, 1, false)
set writefile = fso.CreateTextFile(NewFileName, 2)
Do until readfile.AtEndOfStream = True
     contents = readfile.Read(1)
' Unwrap the case statement.
     select case contents
       case " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
              "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
              "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e",
              "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
               "t", "u", "v", "w", "x", "y", "z", "/", "\", ".", "-", "_", "$", ":"
         writefile.write contents
     end select
loop
readfile.close
writefile.close
PrintQuota.bat uses REG.EXE on Windows 2000, from the Windows 2000 Support Tools, or REG.EXE built into Windows XP and Windows .NET.

PrintQuota.batcontains:

@echo off
setlocal
if \{%3\}

\{\} goto Syntax set realprt=%1 set quotaprt=%2 set maximum=%3 set prg=N set /a sec1=0 set /a sec2=1440 if /i "%4"

"P" set prg=Y if not "%prg%" EQU "Y" goto pq1 if \{%5\}==\{\} goto pq1 set targ=%5 if not "%targ:~2,1%" EQU ":" goto syntax if not "%targ:~8,1%" EQU ":" goto syntax if not "%targ:~5,1%" EQU "-" goto syntax for /f "Tokens=1-4 Delims=:-" %%a in ('@echo %targ%') do set t1=1%%a&set t2=1%%b&set t3=1%%c&set t4=1%%d set /a t1=%t1% - 100 set /a t2=%t2% - 100 if %t2% GTR 59 goto syntax if %t1% GTR 23 goto syntax set /a sec1=%t1% * 60 set /a sec1=%t2% + %sec1% set /a t3=%t3% - 100 set /a t4=%t4% - 100 if %t4% GTR 59 goto syntax if %t3% GTR 23 goto syntax set /a sec2=%t3% * 60 set /a sec2=%t4% + %sec2% if %sec1% GTR %sec2% goto syntax :pq1 if exist "%temp%\SHD.tmp" del /q "%temp%\SHD.tmp" for /f "Tokens=1 Delims=\" %%a in ('@echo %quotaprt%') do set quotasvr=\\%%a set regpath="%quotasvr%\HKLM\System\CurrentControlSet\Control\Print\Printers\HPQuota" for /f "Tokens=*" %%a in ('reg QUERY %regpath% /v SpoolDirectory') do set line=%%a&call :spool set SpoolDirectory=%quotasvr%\%SpoolDirectory% set SpoolDirectory=%SpoolDirectory::=$% if exist "%SpoolDirectory%\*.spl" for /f "Tokens=*" %%a in ('dir /b "%SpoolDirectory%\*.spl"') do call :quota %%a if exist "%temp%\SHD.tmp" del /q "%temp%\SHD.tmp" if "%prg%" EQU "Y" call :purge >nul 2>&1 endlocal goto :EOF :quota set file=%~n1 set fnd=N for /f "Skip=4 Tokens=*" %%b in ('dir /-c "%SpoolDirectory%\%file%.spl"') do set line=%%b&call :size if %sz% GTR %maximum% goto msg print /D:%realprt% "%SpoolDirectory%\%file%.spl" @ping -n 2 127.0.0.1>nul del /q "%SpoolDirectory%\%file%.*" goto :EOF :purge set /a tm=0 set t4=A for /f "Tokens=*" %%a in ('time /t') do set t3="%%a" set t3=%t3: =% set t3=%t3:"=% if "%t3:~2,1%" EQU ":" set t1=1%t3:~0,2%&set t2=1%t3:~3,2%&set t4=%t3:~5,1% if "%t3:~1,1%" EQU ":" set t1=10%t3:~0,1%&set t2=1%t3:~2,2%&set t4=%t3:~4,1% set /a t1=%t1% - 100 set /a t1=%t1% * 60 set /a t2=%t2% - 100 if /i "%t4:~0,1%" EQU "P" set /a tm=720 set /a t1=%t1% + %t2% set /a tm=%t1% + %tm% if %tm% LSS %sec1% goto :EOF if %tm% GEQ %sec2% goto :EOF if not exist "%SpoolDirectory%\*.spl" cscript "%ProgramFiles%\Resource Kit\PRNCTRL.VBS" -x -b "%quotaprt%" goto :EOF :msg shd "%SpoolDirectory%\%file%.shd" "%temp%\SHD.tmp" for /f "tokens=*" %%g in ('type "%temp%\SHD.tmp"') do set strip=%%g&call :stripit goto :EOF :stripit set /a cnt=0 :stripit1 set /a cnt=%cnt% + 1 call set char=%%strip:~%cnt%,19%% if "%char%" EQU " 0 0 :$tYC2V:$tYC2" goto stripit2 goto stripit1 :stripit2 set /a cnt=%cnt% + 19 call set strip=%%strip:~%cnt%,999%% set /a cnt=50 :stripit3 set /a cnt=%cnt% + 1 call set char=%%strip:~%cnt%,2%% if "%char%" EQU "\\" goto stripit4 goto stripit3 :stripit4 set /a cnt=%cnt% + 2 call set computer=%%strip:~%cnt%,999%% call :stripit5 >nul 2>&1 del /q "%SpoolDirectory%\%file%.*" goto :EOF :stripit5 net send %computer% PRINT JOB EXCEEDED QUOTA - %sz% - %strip% goto :EOF :size If "%fnd%" EQU "Y" goto :EOF set fnd=Y for /f "Tokens=3" %%c in ('@echo %line%') do set /a sz=%%c goto :EOF :syntax @echo Syntax: PrintQuota \\ServerName\RealPrinter \\ServerName\QuotaPrinter MaximumBytes \[P \[HH:MM-HH:MM\]\] endlocal goto :EOF :spool if /i "%line:~0,14%" EQU "SpoolDirectory" for /f "Tokens=2*" %%b in ('@echo %line%') do set SpoolDirectory=%%c



Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish