Учет заданий печати в офисе
Перед каждым сотрудником организации, который, по мнению офисных клерков и руководства, отвечает за всё, что подключается к электричеству, рано или поздно встаёт вопрос учёта заданий печати в офисе. Часто эта потребность возникает, когда руководство вдруг озаботится сокращением расходов. Ясно-понятно, что при словосочетании «сокращение расходов» руководство меньше всего думает о своей зарплате, а всё больше об интернете, количестве бумаги и других «особо затратных» статьях расхода. Так или иначе, мы получили задание учесть количество бумажек, извергающимися нашими печатными устройствами. При запросе выделенного бюджета смотрите на честные и удивленные глаза босса и понимаете — бюджет стабильный.
Дабы не пополнить ряды тех, кто безуспешно болтается по службам занятости, приступаем к выполнению поставленной задачи. Первым делом — гугль. Довольно быстро выясняем, что бесплатных вариантов в мире где всё продаётся и покупается — нет. Они конечно есть, но там установлено ограничение либо на количество принтеров, либо на количество заданий печати, либо ещё на что-нибудь полезное, в общем shareware.
Тогда наступает очередь различных «варезников». Но и там нас поджидает неудача — то плохо «ломано», то ключ не подходит, то ещё какая-нибудь напасть. А время идёт… Прошло уже минут 40-60, и босс уже смотрит так, словно вы должны были сделать этот отчет ещё вчера и при этом за весь прошлый год.
В общем деваться некуда — придётся таки работать. И что самое интересное, для получения данных «кто с какого компьютера на какой принтер сколько листов напечатал» потребуется не так много времени. Особенно если я вам сейчас расскажу как это сделать средствами уже имеющимися у вас в наличии.
Итак, в моём случае, мне понадобилось:
windows домен с настроенным DNS, powershell, планировщик заданий.
Приступаем...
Итак, первым делом нам нужно включить нужный нам журнал. Я не стал заморачиваться и сделал всё вручную, благо у меня не так много устройств — один принт сервер и не более десятка личных принтеров у сотрудников.
1. Запускаем консоль.
2. Далее заходим в меню «Файл -> Добавить или удалить оснастку» или просто нажимаем CTRL+M.
3. Добавляем «Просмотр событий». Указываем компьютер, на котором надо включить журнал.
4. После добавления, раскрываем «дерево» как на изображении.
5. Открываем свойства журнала «Работает». Включаем ведение журнала. Размер журнала и другие параметры подбираете опытным путем.
6. Включаем журнал на всех устройствах, где подключены принтеры.
Всё. Вы готовы предоставлять отчёты о количестве напечатанной бумаги в офисе.
Ах, да. Чуть не забыл о небольшой мелочи.<img title=" " src="/static/smiles/laugh.gif" style=«display:inline»> Собирать всю информацию в кучу будет небольшой скрипт:
Set-StrictMode -version 2
$PrintJobCounter = 1
$PerUserTotalPagesRecords = @{}
Function PrintCommandLineUsage {
Write-Host "
Параметры скрипта:
(hostname) PreviousMonth — Retrieve print job data from (hostname) based on
the entire previous month.
or
(hostname) (startdate) (enddate) — Retrieve print job data from (hostname)
based on the specified start and end
dates. The date must be specified in a
format that matches the current system
locale (e.g. MM/dd/yyyy for United States).
Examples:
powershell.exe -command `".\GeneratePrintJobAccountingReports.ps1 localhost Month`"
powershell.exe -command `".\GeneratePrintJobAccountingReports.ps1 printserver.domain.local 10/01/2011 10/15/2011`"
"
}
switch ($args.count) {
{($_ -eq 2) -or ($_ -eq 3)} {
$PrintServerName = $args[0]
Write-Host «Print server hostname to query:» $PrintServerName
}
2 {
if ($args[1].CompareTo(«Month») -eq 0) {
$StartDate = (Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0).AddMonths(-1)
$EndDate = (Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0) — (New-Timespan -Second 1)
}
else {
Write-Host "`nERROR: Two command-line parameters were detected but the second comand-line parameter was not `«Month`»."
PrintCommandLineUsage
Exit 1
}
}
3 {
$ErrorActionPreference = «SilentlyContinue»
$StartDate = Get-Date -Date $args[1]
if (!$?) {
Write-Host "`nERROR: Three command-line parameters were detected but the second comand-line parameter was not a valid date."
PrintCommandLineUsage
Exit 1
}
$EndDate = (Get-Date -Date $args[2]) + (New-Timespan -Day 1) — (New-Timespan -Second 1)
if (!$?) {
Write-Host "`nERROR: Three command-line parameters were detected but the third comand-line parameter was not a valid date."
PrintCommandLineUsage
Exit 1
}
$ErrorActionPreference = «Continue»
}
default {
$s = «comp1», «comp2», «comp3» #Список компьютеров по умолчанию
$currentdata = Get-Date
Write-Host $currentdata
$StartDate = (Get-Date -Hour 0 -Minute 0 -Second 0).adddays(-1) #По умолчанию начало вчерашнего дня
$EndDate = (Get-Date -Hour 0 -Minute 0 -Second 0) — (New-Timespan -Second 1) #По умолчанию конец вчерашнего дня
}
}
$OutputFilenameByPrintJob = «C:\PrintReports\printjob.csv» #куда сохраняем
ForEach ($PrintServerName in $s) {
$PrintEntries = Get-WinEvent -ErrorAction SilentlyContinue -ComputerName $PrintServerName -FilterHashTable @
$PrintEntriesNumberofCopies = Get-WinEvent -ErrorAction SilentlyContinue -ComputerName $PrintServerName -FilterHashTable @
if ($PrintEntries) {
ForEach ($PrintEntry in $PrintEntries) {
$StartDate_Time = $PrintEntry.TimeCreated
$entry = [xml]$PrintEntry.ToXml()
$PrintJobId = $entry.Event.UserData.DocumentPrinted.Param1
$DocumentName = $entry.Event.UserData.DocumentPrinted.Param2
$UserName = $entry.Event.UserData.DocumentPrinted.Param3
$ClientPCName = $entry.Event.UserData.DocumentPrinted.Param4
$PrinterName = $entry.Event.UserData.DocumentPrinted.Param5
$PrintSizeBytes = $entry.Event.UserData.DocumentPrinted.Param7
$PrintPagesOneCopy = $entry.Event.UserData.DocumentPrinted.Param8
if ($UserName -gt "") {
$DirectorySearcher = New-Object System.DirectoryServices.DirectorySearcher
$LdapFilter = "(&(objectClass=user)(samAccountName=$))"
$DirectorySearcher.Filter = $LdapFilter
$UserEntry = [adsi]"$($DirectorySearcher.FindOne().Path)"
$ADName = $UserEntry.displayName
}
$PrintEntryNumberofCopies = $PrintEntriesNumberofCopies | Where-Object {$_.TimeCreated -le $StartDate_Time -and $_.TimeCreated -ge ($StartDate_Time — (New-Timespan -second 5)) -and $_.Message -eq «Подготовка задания $PrintJobId.»}
if ($PrintEntryNumberofCopies) {
$entry = [xml]$PrintEntryNumberofCopies.ToXml()
$NumberOfCopies = $entry.Event.UserData.RenderJobDiag.Copies
if ($NumberOfCopies -eq 0) {
$NumberOfCopies = 1
}
}
else {
$NumberOfCopies = 1
}
$TotalPages = [int]$PrintPagesOneCopy * [int]$NumberOfCopies
$Output = $StartDate_Time.ToString() + "," + $PrintJobId + "," + $UserName + "," + $ADName + "," + $ClientPCName + "," + $PrinterName + ",`"" + ($DocumentName -replace ",", "_") + "`"," + $PrintSizeBytes + "," + $PrintPagesOneCopy + "," + $NumberOfCopies + "," + $TotalPages
Write-Output $Output | Out-File -FilePath $OutputFilenameByPrintJob -Encoding UTF8 -Append
$UserNameKey = "`"$UserName ($ADName)`""
if (!$PerUserTotalPagesRecords.ContainsKey($UserNameKey)) {
$PerUserTotalPagesRecords.Add($UserNameKey,$TotalPages)
}
else {
$PerUserTotalPagesRecords.Set_Item($UserNameKey,$PerUserTotalPagesRecords.Get_Item($UserNameKey) + $TotalPages)
}
$PrintJobCounter++
}
}
}
Write-Host «Finish.»
Скопируйте это в файл PrintJobReports.ps1
Вроде в скрипте нет ничего нет сложного, всё интуитивно понятно. На всякий случай есть комментарии, где это нужно. Запускать сценарий можно разными способами. У себя я сделал через «Планировщик». Запускается ночью, один раз, без параметров (все умолчания прописаны в самом сценарии), формирует файл с данными по всем устройствам за прошедший день. На выходе получим файл примерно такого содержания:
31.01.2019 15:17:41,5,ivanov, Иванов Иван,\\COMP1,Kyocera FS-1100,«Печать расходного кассового орд»,58599,1,1,1
29.01.2019 11:27:38,7,ivanov, Иванов Иван,\\COMP1,Kyocera FS-1100,«Табличный документ»,499408,22,1,22
29.01.2019 11:17:16,6,ivanov, Иванов Иван,\\COMP1,Kyocera FS-1100,«Табличный документ»,90231,6,1,6
Т.е. обычный файл с разделителем. Поля опять же интуитивно понятны<img title=" " src="/static/smiles/smile.gif" style=«display:inline»> «Дата, ID задания, Пользователь, Полное имя пользователя, Компьютер, Принтер, Название документа, Размер в байтах, Количество страниц, Количество копий, Количество страниц умноженное на Количество копий». Прочитать и разобрать этот файл можно разными путями. Так как у меня в сети присутствует сервер 1с, написал небольшую конфигурацию для этих целей. Работает абсолютно автономно. Теперь вроде всё. Всем удачи.
P.S. Всё это сделано для русской версии Windows. Если у вас английская, то в скрипте нужно заменить «Подготовка задания» на англоязычный аналог.
На всякий случай, готовый файл скрипта — скрипт
- 4 комментария