ambers
 New Member Posts:16

 |
| 26 Oct 2007 07:02 AM |
|
# Ambers # 08/01/07 # R1 # Identify hung print jobs across server list
$computers = get-content c:\scripts\computers.txt $now = (get-date) Foreach ($computer in $computers) { $PrintJobs = get-wmiobject Win32_PrintJob -computername $computer If ($PrintJobs -ne $NULL){ Foreach ($PrintJob in $PrintJobs) { $then = ($printjob.ConvertToDateTime($printjob.timesubmitted)) $age = $now - $then If ($age.days -gt 0 -OR $age.hours -gt 0 -OR $age.minutes -gt 20) { "Print Server: " + $computer "Printer: " + $printjob.name "Print Job: " + $printjob.document "Time Submitted: " + $then "Job Status: " + $printjob.JobStatus "Time in Queue: " + "{0:N0}" -f $age.days + " days " + "{0:N0}" -f $age.hours + " hours " + "{0:N0}" -f $age.minutes + " minutes " "Size of File: " + $printjob.Size "Pages Printed: " + $printjob.pagesprinted "Total Pages: " + $printjob.totalpages write-host "" } } } } |
|
|
|
|
SAPIENScripter
 New Member Posts:45
 |
| 26 Oct 2007 02:11 PM |
|
Looks good. One minor suggestion. I'm assuming write-host "" is to put a blank line between entries. The better Powershell way would be: write-host `n I'd also like to know how you use this script. Do you manually run it from time to time? if you see hung print jobs do you manually kill them? There's nothing wrong with what you have, especially if it works, But, you might consider taking this a step further and turning the section of the code that returns print job information into a function that outputs an object. You could use Add-Member to create custom properties. Since the function would output an object, you or someone else could then turn it into a csv, xml, or html file. It could even be mailed. |
|
Jeffery Hicks Microsoft PowerShell MVP http://blog.sapien.com http://www.scriptinganswers.com
"Those who forget to script are doomed to repeat their work."
|
|
|
bsonposh
 Basic Member Posts:392

 |
| 26 Oct 2007 02:52 PM |
|
write-host `n will do two lines not one. write-host by default adds a nlcr at the end. |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|
DonJ PowerShell MVP
 Basic Member Posts:134

 |
| 26 Oct 2007 03:12 PM |
|
I love to see stuff like this written as a function that outputs objects - so that those objects can be piped to other cmdlets for sorting and so forth.
For example:
function Get-PrintJobStatus { # do the checking of status here $stat = new-object psobject # assuming variables like $jobstatus and $timewritten have the status # info you're looking for $stat | add-member JobStatus NoteProperty $jobstatus $stat | add-member TimeWritten NoteProperty $timewritten # continue piping the variable to add-member to add more properties
# output the object write $stat
}
That way the output can be formatted using the Format-* cmdlets, can be exported to XML, CSV, etc, converted to HTML, and so forth - allowing your function to really be a first-class PowerShell citizen. We've got a chapter in the 2nd edition of our book (Windows PowerShell: TFM, www.sapienpress.com/powershell2.asp) on this exact topic, in fact - it really helps make functions more flexible over the long term.
Remember - PowerShell is about objects, not text; outputting objects is the best way to go, when it's possible.
|
|
- Don Jones www.ConcentratedTech.com Subscribe (RSS) or visit for weekly PowerShell tips and lessons |
|
|
ambers
 New Member Posts:16

 |
| 26 Oct 2007 03:59 PM |
|
Thanks for the feedback.
Jeffery, I actually have this as a function (get-printjobs) in my profile which i run occassionally to check the status. I have also added a similar script to each of our print servers which creates a running text log. I couldn't find an easy way to append to the log file using export-csv so the code is functional, but pretty ugly and I knew it wasn't quite ready to post here. We actually have a series of scripts which I hope to combine into one. These look at other WMI information for the printers and combine it with relevant information from the event logs. My original intent was to get at the same information that is in the Print Management tool that was released with R2. I was probably about 70% successful in that regard.
I look forward to reading the 2nd Edition, Don. I grabbed the sample chapters last night. I'm watching Powershell 101 right now so I'll have a good background by the time it gets released. Any plans for Powershell 201 soon?
I'll work with the advice you both gave to get a more functional tool out for futher review. |
|
|
|
|
bsonposh
 Basic Member Posts:392

 |
| 26 Oct 2007 04:45 PM |
|
ambers, You may find these blog post useful for your project. http://bsonposh.com/modules/wordpress/?cat=12 They discuss creating custom objects and how to use them effectively. |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|
ambers
 New Member Posts:16

 |
| 26 Oct 2007 05:10 PM |
|
Thanks Brandon, this opens up a whole new set of toys for me. |
|
|
|
|
bsonposh
 Basic Member Posts:392

 |
| 26 Oct 2007 05:14 PM |
|
I hope it helps... as always feel free to post any questions you have. |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|
ambers
 New Member Posts:16

 |
| 27 Oct 2007 08:38 AM |
|
Thanks Guys for all of your help. I see where you are all coming from now and I have a ton of work to clean up some other scripts before I post them. I'm sure I'll have more questions as I learn more.
Any ideas if I wanted to export this as a csv and make it a rolling log file how I could go about it. I think I have an idea to grab the existing data as an object then add the output from the function and tehn export the new object to csv as a new object. It would be nice if I had an -append paramter for export-csv. Here the script with the my interpretation of your recommendations:
# Ambers # 08/01/07 # R2 # Identify hung print jobs across server list
function get-printjobs { $computers = get-content c:\scripts\computers.txt $now = (get-date) foreach ($computer in $computers) { $PrintJobs = Get-WmiObject Win32_PrintJob -computername $computer If ($PrintJobs -ne $NULL){ Foreach ($PrintJob in $PrintJobs) { $then = ($printjob.ConvertToDateTime($printjob.timesubmitted)) $age = $now - $then If ($age.days -gt 0 -OR $age.hours -gt 0 -OR $age.minutes -gt 20) { $hungjob = "" | select Server, Printer, PrintJob, TimeSubmitted, Status, QueueAge, Size, PagesPrinted, PagesTotal $hungjob.server = $computer $hungjob.printer = $printjob.name $hungjob.printjob = $printjob.document $hungjob.timesubmitted = $then $hungjob.status = $printjob.JobStatus $hungjob.QueueAge = "{0:N0}" -f $age.days + " days " + "{0:N0}" -f $age.hours + " hours " + "{0:N0}" -f $age.minutes + " minutes " $hungjob.size = $printjob.Size $hungjob.PagesPrinted = $printjob.pagesprinted $hungjob.PagesTotal = $printjob.totalpages write $hungjob } } } } }
##Thanks again, # Ambers. |
|
|
|
|
bsonposh
 Basic Member Posts:392

 |
| 28 Oct 2007 04:39 AM |
|
Try this [code]function get-printjobs { Param($List = "c:\scripts\computers.txt",$Export} $computers = get-content $list $now = (get-date) $objCol = @() ### I Add this for collecting the objects foreach ($computer in $computers) { $PrintJobs = Get-WmiObject Win32_PrintJob -computername $computer If ($PrintJobs -ne $NULL){ Foreach ($PrintJob in $PrintJobs) { $then = ($printjob.ConvertToDateTime($printjob.timesubmitted)) $age = $now - $then If ($age.days -gt 0 -OR $age.hours -gt 0 -OR $age.minutes -gt 20) { $hungjob = "" | select Server, Printer, PrintJob, TimeSubmitted, Status, QueueAge, Size, PagesPrinted, PagesTotal $hungjob.server = $computer $hungjob.printer = $printjob.name $hungjob.printjob = $printjob.document $hungjob.timesubmitted = $then $hungjob.status = $printjob.JobStatus $hungjob.QueueAge = "{0:N0}" -f $age.days + " days " + "{0:N0}" -f $age.hours + " hours " + "{0:N0}" -f $age.minutes + " minutes " $hungjob.size = $printjob.Size $hungjob.PagesPrinted = $printjob.pagesprinted $hungjob.PagesTotal = $printjob.totalpages # if $Export write object to array else write to output if($export){$objCol += $hungjob}else{write-Output $hungjob} } } } } if($export){$objCol | export-Csv $Export -noType} ## Exports to CSV file in $export }[/code] |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|
bsonposh
 Basic Member Posts:392

 |
| 28 Oct 2007 04:40 AM |
|
whoops.. used the wrong code tags Maybe this is better
function get-printjobs {
Param($List = "c:\scripts\computers.txt",$Export}
$computers = get-content $list
$now = (get-date)
$objCol = @() ### I Add this for collecting the objects
foreach ($computer in $computers) {
$PrintJobs = Get-WmiObject Win32_PrintJob -computername $computer
If ($PrintJobs -ne $NULL){
Foreach ($PrintJob in $PrintJobs) {
$then = ($printjob.ConvertToDateTime($printjob.timesubmitted))
$age = $now - $then
If ($age.days -gt 0 -OR $age.hours -gt 0 -OR $age.minutes -gt 20) {
$hungjob = "" | select Server, Printer, PrintJob, TimeSubmitted, Status, QueueAge, Size, PagesPrinted, PagesTotal
$hungjob.server = $computer
$hungjob.printer = $printjob.name
$hungjob.printjob = $printjob.document
$hungjob.timesubmitted = $then
$hungjob.status = $printjob.JobStatus
$hungjob.QueueAge = "{0:N0}" -f $age.days + " days " + "{0:N0}" -f $age.hours + " hours " + "{0:N0}" -f $age.minutes + " minutes "
$hungjob.size = $printjob.Size
$hungjob.PagesPrinted = $printjob.pagesprinted
$hungjob.PagesTotal = $printjob.totalpages
# if $Export write object to array else write to output
if($export){$objCol += $hungjob}else{write-Output $hungjob}
}
}
}
}
if($export){$objCol | export-Csv $Export -noType} ## Exports to CSV file in $export
} |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|
DonJ PowerShell MVP
 Basic Member Posts:134

 |
| 28 Oct 2007 07:16 PM |
|
Hey, Brandon, don't forget to drop that in the ScriptVault for long-term availability!
|
|
- Don Jones www.ConcentratedTech.com Subscribe (RSS) or visit for weekly PowerShell tips and lessons |
|
|
ambers
 New Member Posts:16

 |
| 29 Oct 2007 05:13 AM |
|
Thanks again Brandon for all of your help. I added a line to check if $export existed and if so appends instead of overwrites. The other was just a } to ) in the param line. function get-printjobs { Param($List = "c:\scripts\computers.txt",$Export) $computers = get-content $list $now = (get-date) $objCol = @() ### I Add this for collecting the objects foreach ($computer in $computers) { $PrintJobs = Get-WmiObject Win32_PrintJob -computername $computer If ($PrintJobs -ne $NULL){ Foreach ($PrintJob in $PrintJobs) { $then = ($printjob.ConvertToDateTime($printjob.timesubmitted)) $age = $now - $then If ($age.days -gt 0 -OR $age.hours -gt 0 -OR $age.minutes -gt 20) { $hungjob = "" | select Server, Printer, PrintJob, TimeSubmitted, Status, QueueAge, Size, PagesPrinted, PagesTotal $hungjob.server = $computer $hungjob.printer = $printjob.name $hungjob.printjob = $printjob.document $hungjob.timesubmitted = $then $hungjob.status = $printjob.JobStatus $hungjob.QueueAge = "{0:N0}" -f $age.days + " days " + "{0:N0}" -f $age.hours + " hours " + "{0:N0}" -f $age.minutes + " minutes " $hungjob.size = $printjob.Size $hungjob.PagesPrinted = $printjob.pagesprinted $hungjob.PagesTotal = $printjob.totalpages # if $Export write object to array else write to output if($export){$objCol += $hungjob}else{write-Output $hungjob} } } } } if (test-path $export) {(import-csv $Export) + $objCol | export-csv $Export -notype} elseif($export){$objCol | export-Csv $Export -noType} ## Exports to CSV file in $export } |
|
|
|
|
bsonposh
 Basic Member Posts:392

 |
| 29 Oct 2007 03:17 PM |
|
Ambers, As per Don suggestion. Why dont you drop that in the Script Repo... it is your script I just add a little flavor  |
|
Brandon Shell ---------------- Microsoft Powershell MVP https://mvp.support.microsoft.com/profile/Brandon Blog: http://www.bsonposh.com |
|
|