JCIT2009
asked on
VBScript to Kill print jobs
Hi,
I am trying to get a vbscript to run in the background and delete any print jobs spooled that are over 1hr old (on XP SP3 Machines)
I have this script that will successfully delete files older than 1hr
*******************
sFolder = "c:\windows\system32\spool
iMaxAge = 1
Set oFSO = CreateObject("Scripting.Fi
If oFSO.FolderExists(sFolder)
for each oFile in oFSO.GetFolder(sFolder).Fi
If DateDiff("h", oFile.DateLastModified, Now) > iMaxAge Then
oFile.Delete
End If
next
End If
**************************
and I have scripts that "should" stop and start the "print spooler" service
**************************
'stop spooler
strServiceName = "print spooler"
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery("S
For Each objService in colListOfServices
objService.StopService()
**************************
'start spooler
For Each objService in colListOfServices
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
objService.StartService()
**************************
However I seem unable to stitch this togther so that the print spooler is only stopped if there are files over 1hour old, then the delete kicks in, then restart the service.
I do not want to stop the service unless there are files over 1hr old to delete.
Can anyone point me in the right direction why I cant seem to get this to work?
Thanks
better to move "strServiceName = ..." to the start of the script I see now.
with that last change at least the syntax seems ok but on my system it doesn't find the service so can't stop/start it...
ASKER
hi.... thanks for this.
I will try the script tomorrow and let you know how I get on. I dont have any XP machines at home to try this on. In hindsight, I think the service should just be "spooler" - sorry I dont normally have to do things like this.
I will try the script tomorrow and let you know how I get on. I dont have any XP machines at home to try this on. In hindsight, I think the service should just be "spooler" - sorry I dont normally have to do things like this.
ASKER
Hi - managed to remote on to an XP box to try this and although the file delete was working on txt files it for some reason doesn't seem to work on the spooled print files. *scratches head*
However - I have taken your script and bodged it with some other script that does seem to delete the right files and have come up with this....
********************
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\ spool\prin ters"
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin g.filesyst emobject")
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo dified,dt) >2) then
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
End If
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery("S elect * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StopService()
Next
f.delete true 'forced
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
************************
On first attempt, remotely, it seemed to work, but alas I have now been cut off and cant seem to get back on so will not be able to find out until tomorrow PM when I am back in the office (boring site meeting in the morning)
However - I have taken your script and bodged it with some other script that does seem to delete the right files and have come up with this....
********************
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
End If
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery("S
For Each objService in colListOfServices
objService.StopService()
Next
f.delete true 'forced
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
************************
On first attempt, remotely, it seemed to work, but alas I have now been cut off and cant seem to get back on so will not be able to find out until tomorrow PM when I am back in the office (boring site meeting in the morning)
ASKER
*note
I have set it to 2mins in the above script for speed during testing
I have set it to 2mins in the above script for speed during testing
In the above script only the first file will be deleted, the command "f.delete true" should be in the main loop, after the "if not found ... end if" block.
ASKER
With moving the f.delete as you suggest - it now seems to do whats needed.
I would never have got there without your help - Thank you
I would never have got there without your help - Thank you
ASKER
hmm.... ok. now with further testing. If there are multiple files, but no files that meet the delete criteria I get permission denied error. If there are file(s) to delete, it works fine.
I knew there was a reason I am not a programmer.
I knew there was a reason I am not a programmer.
can you post the current code please, just to check there's nothing out of place?
ASKER
Thanks again for looking at this for me...
The most successful code so far is below...but it only seems to work if there are files to delete, if not or if there are a mix of files to leave and files to delete, it fails with permission error?
************************** ********
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\ spool\prin ters"
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin g.filesyst emobject")
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo dified,dt) >2) then
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
End If
f.delete true 'forced
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery("S elect * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StopService()
Next
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
************************** ********** ******
I have also tried the following, but this does not work at all.
************************** ********** ****
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\ spool\prin ters"
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin g.filesyst emobject")
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo dified,dt) >2) then
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
f.delete true 'forced
End If
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery("S elect * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StopService()
Next
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
The most successful code so far is below...but it only seems to work if there are files to delete, if not or if there are a mix of files to leave and files to delete, it fails with permission error?
**************************
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
End If
f.delete true 'forced
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery("S
For Each objService in colListOfServices
objService.StopService()
Next
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
**************************
I have also tried the following, but this does not work at all.
**************************
blnFound = False
strServiceName = "spooler"
sdir="c:\windows\system32\
dim dt, fso, odir, f
dt=now
set fso=createobject("scriptin
if fso.folderexists(sdir) then
set odir=fso.getfolder(sdir)
for each f in odir.files
if (datediff("n",f.datelastmo
If not blnFound then ' first
blnFound = True
Call stopSrv
End If
f.delete true 'forced
End If
next
End If
If blnFound Then Call startSrv
Sub stopSrv 'stop spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery("S
For Each objService in colListOfServices
objService.StopService()
Next
End Sub
Sub startSrv 'start spooler
Set objWMIService = GetObject("winmgmts:{imper
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
objService.StartService()
Next
End Sub
set odir=nothing
set fso=nothing
Well, the first piece of code would try to delete all files, as the 'delete' is outside of the time checking "if - end if" block. The second piece of code should work, if it finds any files older than the specified time period and the user that's running the script has permission to delete files in the specified folder.
I'm wondering by the way if there wouldn't be a nicer way to do this, maybe a PowerShell script can do it similar to a cancel or delete in the printer queue?
I'm wondering by the way if there wouldn't be a nicer way to do this, maybe a PowerShell script can do it similar to a cancel or delete in the printer queue?
@JCIT2009
Are you still on this? I may have an idea, using a batch file.
Are you still on this? I may have an idea, using a batch file.
I must admit I haven't explored it further, partly because I can't test in the same situation as yours. I don't see the value of a batch file here. Would you like help finding out if there's a better way to do this, like using an API, either from PowerShell or maybe even something like a VB.NET application?
@robert_schutt:
"I don't see the value of a batch file here"
I don't see why not! What if it works?
Anyway, let's first see if JCIT2009 is still on this, and I'll see if I can help.
Cheers
"I don't see the value of a batch file here"
I don't see why not! What if it works?
Anyway, let's first see if JCIT2009 is still on this, and I'll see if I can help.
Cheers
ASKER
Hi,
Sorry been away. I now have a different, but similar, working VBScript. I will post it tomorrow in case anyone finds it useful.
Thanks for all the help.
JCIT2009
Sorry been away. I now have a different, but similar, working VBScript. I will post it tomorrow in case anyone finds it useful.
Thanks for all the help.
JCIT2009
@ReneGe: sorry, I read your post wrong; thought it was directed at me, from the asker. I read it as: "would a batch file be able to do something different than vbs" and I couldn't see what that would be. Like @JCIT2009, maybe you should just post your idea, it might help somebody who stumbles across this while searching for a solution later.
@Robert:Don't worry :)
My idea was to scan the time of the printer spool files and delete from there.
Inspired by BillPrew's scripts found in:
https://www.experts-exchange.com/questions/27459125/DOS-Command-script-to-delete-files-in-dir-subs-by-date-and-exact-time.html?cid=748&anchorAnswerId=37174758#a37174758
And gerwinjansen:
https://www.experts-exchange.com/questions/27458652/Simple-batch-file-to-move-a-file-from-a-static-location-to-a-directory-named-by-the-system-date.html?cid=748&anchorAnswerId=37173619#a37173619
I have not tested it but here is my idea.
My idea was to scan the time of the printer spool files and delete from there.
Inspired by BillPrew's scripts found in:
https://www.experts-exchange.com/questions/27459125/DOS-Command-script-to-delete-files-in-dir-subs-by-date-and-exact-time.html?cid=748&anchorAnswerId=37174758#a37174758
And gerwinjansen:
https://www.experts-exchange.com/questions/27458652/Simple-batch-file-to-move-a-file-from-a-static-location-to-a-directory-named-by-the-system-date.html?cid=748&anchorAnswerId=37173619#a37173619
I have not tested it but here is my idea.
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET SpoolerFolder=C:\Windows\System32\spool\PRINTERS
FOR /F "tokens=1-4 delims= " %%A IN ('WMIC Path Win32_LocalTime Get Day^,Month^,Year^,Hour ^| findstr /r [0123456789]') DO (
IF %%B LEQ 9 (SET hh=09) ELSE (SET hh=9)
SET Now=%%D%%C%%A!hh!
)
NET STOP SPOOLER
FOR /R "%SpoolerFolder%" %%F in ("*.*") do (
REM Adjust file name for WMIC call (replace \ with \\)
SET WmicFile=%%~F
SET WmicFile=!WmicFile:\=\\!
REM Do WMIC call to get last modified date/time stamp for this file
WMIC datafile where "name='!WmicFile!'" get lastmodified | FINDSTR %Now% >NUL || ECHO DEL /f /q %%~F
)
NET START SPOOLER
PAUSE
EXIT
The flaw in my script will be that if a print job is sent at let's say 10:59 and the script runs at 11:00, that print job will also be deleted. I will gladly resolve this issue if it has a value, onless you (robert_schutt) feel like giving it a shot.
Cheers
Cheers
Great. No, go ahead. I didn't know what was preventing the vb script we got so far to do its job.
@robert_schutt:
I don't know VBScript, so I can't help with this. Let's see what JCIT2009 found in [37184894].
I don't know VBScript, so I can't help with this. Let's see what JCIT2009 found in [37184894].
ASKER
Hi Guys,
OK this is the end result - it works!!
Hope someone else finds this useful at some point as well.
:-)
-------------------------- ---------- ---------- ----
Option Explicit
Dim blnFound, strServiceName, sdir, CurrentDateTime, fso, odir, f, GracePeriodMinuteCount
'///////////////////////// ////////// ////////// ////////// ///
'/ Variables
'///////////////////////// ////////// ////////// ////////// ///
strServiceName = "spooler"
sdir="c:\windows\system32\ spool\prin ters"
CurrentDateTime = Now
GracePeriodMinuteCount = 30
blnFound = False
'///////////////////////// ////////// ////////// ////////// ///
'/ Main Code
'///////////////////////// ////////// ////////// ////////// ///
set fso=createobject("scriptin g.filesyst emobject")
If fso.folderexists(sdir) then
Set odir=fso.getfolder(sdir)
On Error Resume Next
Err.Clear
If (odir.Files.Count > 0) Then
For each f in odir.Files
If Err <> 0 Then
MsgBox "Error Fetching Files in: " & sdir & " - " & Err.Description
Err.Clear
End If
On Error Resume Next
If (datediff("n",f.datelastmo dified, CurrentDateTime) > GracePeriodMinuteCount) then
If Err <> 0 Then
MsgBox "Error Fetching File Date: " & f.Name & " - " & Err.Description
Err.Clear
End If
If not blnFound then ' first
blnFound = True
SetServiceState strServiceName, False
Err.Clear
f.Delete(True)
If Err <> 0 Then
MsgBox "Error: Deleting File: " & f.Name & " - " & Err.Description
Err.Clear
End If
If blnFound Then
SetServiceState strServiceName, True
End If
End If
End If 'datediff
Next 'f in odir.files
End If 'odir files count
Else
MsgBox "Error: Directory; " & sdir & " Does Not Exist"
WScript.Quit
End If
'///////////////////////// ////////// ////////// ////////// ///
'/ Functions
'///////////////////////// ////////// ////////// ////////// ///
'------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
Function SetServiceState( strServiceName, bState ) ' true = Start ; false = Stop
Dim objWMIService, colListOfServices, objService, strServiceState
On Error Resume Next
Err.Clear
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
If Err <> 0 Then
MsgBox "Error Getting Wmi Service - " & Err.Description
Err.Clear
Else
Set colListOfServices = objWMIService.ExecQuery("S elect * from Win32_Service Where Name ='" & strServiceName & "'")
If Err <> 0 Then
MsgBox "Error Getting Service Collection - " & Err.Description
Err.Clear
Else
For Each objService in colListOfServices
If bState = False Then
objService.StopService()
Do Until strServiceState = "Stopped"
strServiceState = GetServiceState(strService Name)
''' You may want to put a timeout here in case the service fails to stop to avoid an endless loop.
WScript.Sleep 200
Loop
Else
objService.StartService()
Do Until strServiceState = "Running"
strServiceState = GetServiceState(strService Name)
''' You may want to put a timeout here in case the service fails to start to avoid an endless loop.
WScript.Sleep 200
blnFound = False
Loop
End If
Next
End If
End If
Set colListOfServices = Nothing
Set objWMIService = Nothing
End Function
'------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
Function GetServiceState( strServiceName )
Dim objWMIService, colListOfServices, objService
GetServiceState = ""
On Error Resume Next
Err.Clear
Set objWMIService = GetObject("winmgmts:{imper sonationLe vel=impers onate}!\\. \root\cimv 2")
If Err <> 0 Then
MsgBox "Error Getting Wmi Service - " & Err.Description
Err.Clear
Else
Set colListOfServices = objWMIService.ExecQuery("S elect * from Win32_Service Where Name ='" & strServiceName & "'")
If Err <> 0 Then
MsgBox "Error Getting Service Collection - " & Err.Description
Err.Clear
Else
For Each objService in colListOfServices
GetServiceState = objService.State
Next
End If
End If
If GetServiceState = "" Then
GetServiceState = "Unknown"
End If
Set colListOfServices = Nothing
Set objWMIService = Nothing
End Function
OK this is the end result - it works!!
Hope someone else finds this useful at some point as well.
:-)
--------------------------
Option Explicit
Dim blnFound, strServiceName, sdir, CurrentDateTime, fso, odir, f, GracePeriodMinuteCount
'/////////////////////////
'/ Variables
'/////////////////////////
strServiceName = "spooler"
sdir="c:\windows\system32\
CurrentDateTime = Now
GracePeriodMinuteCount = 30
blnFound = False
'/////////////////////////
'/ Main Code
'/////////////////////////
set fso=createobject("scriptin
If fso.folderexists(sdir) then
Set odir=fso.getfolder(sdir)
On Error Resume Next
Err.Clear
If (odir.Files.Count > 0) Then
For each f in odir.Files
If Err <> 0 Then
MsgBox "Error Fetching Files in: " & sdir & " - " & Err.Description
Err.Clear
End If
On Error Resume Next
If (datediff("n",f.datelastmo
If Err <> 0 Then
MsgBox "Error Fetching File Date: " & f.Name & " - " & Err.Description
Err.Clear
End If
If not blnFound then ' first
blnFound = True
SetServiceState strServiceName, False
Err.Clear
f.Delete(True)
If Err <> 0 Then
MsgBox "Error: Deleting File: " & f.Name & " - " & Err.Description
Err.Clear
End If
If blnFound Then
SetServiceState strServiceName, True
End If
End If
End If 'datediff
Next 'f in odir.files
End If 'odir files count
Else
MsgBox "Error: Directory; " & sdir & " Does Not Exist"
WScript.Quit
End If
'/////////////////////////
'/ Functions
'/////////////////////////
'-------------------------
Function SetServiceState( strServiceName, bState ) ' true = Start ; false = Stop
Dim objWMIService, colListOfServices, objService, strServiceState
On Error Resume Next
Err.Clear
Set objWMIService = GetObject("winmgmts:{imper
If Err <> 0 Then
MsgBox "Error Getting Wmi Service - " & Err.Description
Err.Clear
Else
Set colListOfServices = objWMIService.ExecQuery("S
If Err <> 0 Then
MsgBox "Error Getting Service Collection - " & Err.Description
Err.Clear
Else
For Each objService in colListOfServices
If bState = False Then
objService.StopService()
Do Until strServiceState = "Stopped"
strServiceState = GetServiceState(strService
''' You may want to put a timeout here in case the service fails to stop to avoid an endless loop.
WScript.Sleep 200
Loop
Else
objService.StartService()
Do Until strServiceState = "Running"
strServiceState = GetServiceState(strService
''' You may want to put a timeout here in case the service fails to start to avoid an endless loop.
WScript.Sleep 200
blnFound = False
Loop
End If
Next
End If
End If
Set colListOfServices = Nothing
Set objWMIService = Nothing
End Function
'-------------------------
Function GetServiceState( strServiceName )
Dim objWMIService, colListOfServices, objService
GetServiceState = ""
On Error Resume Next
Err.Clear
Set objWMIService = GetObject("winmgmts:{imper
If Err <> 0 Then
MsgBox "Error Getting Wmi Service - " & Err.Description
Err.Clear
Else
Set colListOfServices = objWMIService.ExecQuery("S
If Err <> 0 Then
MsgBox "Error Getting Service Collection - " & Err.Description
Err.Clear
Else
For Each objService in colListOfServices
GetServiceState = objService.State
Next
End If
End If
If GetServiceState = "" Then
GetServiceState = "Unknown"
End If
Set colListOfServices = Nothing
Set objWMIService = Nothing
End Function
Great job, thanks for sharing.
Little issue: you've voided the usefulness of the variable "blnFirst", so now the service is stopped and started for each file found. Shouldn't be a real problem though.
But using the Functions and adding error checking is a really good job which will help others looking for a similar solution here.
Little issue: you've voided the usefulness of the variable "blnFirst", so now the service is stopped and started for each file found. Shouldn't be a real problem though.
But using the Functions and adding error checking is a really good job which will help others looking for a similar solution here.
ASKER
Hi - no probs for sharing - I wouldnt have got this far without your help. I'll hand out some points soon. ;)
Can you see how I could better this to only stop the service once then? Please feel free to advise.. :)
Can you see how I could better this to only stop the service once then? Please feel free to advise.. :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
cool - thanks - will try that today.
ASKER
all seems to work now. Thanks for everyones help! x
I have a question regarding this topic
I have a lot of print server and spool folder is not always at the same place
is there a way through vbs to find spool folder
I have a lot of print server and spool folder is not always at the same place
is there a way through vbs to find spool folder
You should not post comments like this on old questions since the experts will only be alerted about new questions and also they should be able to earn points. That being said, it might be a valuable addition to this particular code, Unfortunately, I'm not able to spend much time on this now so will just give some general info:
1) the spool folder can be found in the registry under: HKEY_LOCAL_MACHINE\SYSTEM\ CurrentCon trolSet\Co ntrol\Prin t\Printers
2) code to read the registry in vbscript can be found here for example: http://blogs.msdn.com/b/alejacma/archive/2008/04/11/how-to-read-a-registry-key-and-its-values.aspx
1) the spool folder can be found in the registry under: HKEY_LOCAL_MACHINE\SYSTEM\
2) code to read the registry in vbscript can be found here for example: http://blogs.msdn.com/b/alejacma/archive/2008/04/11/how-to-read-a-registry-key-and-its-values.aspx
Open in new window