Centralized collection and processing of journals printing, Windows
In small offices does not always use network printers and MFPs, so to obtain statistics about the use of printing devices is difficult to obtain. Especially, if it is required to produce with minimum costs. Such data can help to determine the most widely used device to evaluate the load on them and to take timely decisions on procurement of supplies, maintenance or even replacement to more efficient and productive. This problem can be solved without additional software using the built-in log management Windows and the script on Powershell.
Using search engine you can find ready-made software for audit, office printing, such as:
the These systems are not always suitable, as they require a purchase, the free version have limited functionality, you must install as the Central server and agents on client computers, some programs work only with print server and so on. I propose to use for solving the task, the tools built in to Windows 7/2008R2 and Powershell scripts.
So, let us take initial data with the following information:
the
the
The first thing you need to prepare the infrastructure for a centralized collection of event logs from client computers.
To work subscribe to Windows events on the source computer, you need the following settings:
Create the snap in Users and Computers the new user as the full name and the username specified EventCollectorUser. Assign a complex password and put a tick "Deny password change the user and password expiration unlimited."
Next, create the new domain controller group policy and call it, for example, GPO-EventCollector.
Policy set the following parameters:
After you create a group policy, you must restart the target computers or do they gpupdate /force.
To turn the print log on the target computer using an MMC snap-in "event Viewer" on the way "the Logs of applications and services – Microsoft – Windows – PrintService – Works" (click right mouse button on the log and select "enable"). This option is suitable if the computers not so much.
If you want to enable the log for a large group PC, you can use the following method:
Update: Also, as rightly pointed out NeSvist, you can set the registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-PrintService/Operational — Enabled is 1.
Set this option to distribute group policy that we created above.
For reference: About working with the registry in GPO
the
After preparing the infrastructure, you can go directly to configuring event subscriptions on server header.
the
Collected events can be exported to CSV format by means of snap "event Viewer", the resulting data is not very informative and does not allow to obtain interesting statistics that can show leadership. So I offer the option of processing the received events by means of Powershell for convenience of their further use.
Search on the Internet was found a script log analysis Windows print Server 2003. (http://trevorsullivan.net/2009/11/06/windows-2003-print-log-parsing-script-powershell/) as there are certain differences in the Powershell cmdlets new versions, and a method of producing events differs from that proposed in the article, the script was revised.
The overall structure of the script I did not change, it is divided by functions, which are easy to modify (in the case of localization, for example). Logic of script is following:
Get list of events from "Routed events" code 307 (in case the specified log forwarded any event).
{ $PrintEntries = get-winevent -FilterHashTable @{LogName='ForwardedEvents'; ID=307;} return $PrintEntries }
Create a new PrintJob object. Adding the required fields.
Derived from properties Message field events the username, printer Name, Number of printed pages in the document, the name of the document. this Pulls all of the strings by regular expressions. At English-language magazine change of line in regular expressions on the others, respectively.
The main function of. Get a list of events in the cycle turn it to the PrintJob object. Then do the export of the resulting list of objects to the specified file. Set UTF8 encoding for correct display of the Cyrillic alphabet and the separator ";" for reading open the file in Excel. Every 100 events, writing a log, this is useful for debugging.
the
In the preparation of regular expressions for the script used Regex101.com. The website is clear, concise documentation, highlighting a search result in the source string, deciphering the meaning of a regular expression on the fly. Very informative and conveniently, recommended for use.
The script can be applied on-demand, running in the command shell, PowerShell, and you can assign as a task in task Scheduler.
To do this:
Thus, specified when you created the script directory at a specified interval to update the file with the lists of published papers.
the
the
The proposed processing script is not a universal solution and can be improved in various directions, for example,
the
So, in this article I tried to show the principle of centralized collection of event logs of Windows and their further processing by means of Powershell. This method is suitable for solving the problem in small organizations. Of course, specialized software to cope with the set objectives more efficiently, but it is expensive, more cumbersome, it brings IT specialist less new knowledge and skills, understanding of accepted software.
In the preparation of this article were used the following materials and sources:
Update: As noted NeSvist and selenite, binding to specific localization and parsing it with regular expressions — not the most effective solution. In this regard, I cite the case of processing the collected events using their representations in XML. The decision turned out to be more neat and clear.
Article based on information from habrahabr.ru
Using search engine you can find ready-made software for audit, office printing, such as:
the These systems are not always suitable, as they require a purchase, the free version have limited functionality, you must install as the Central server and agents on client computers, some programs work only with print server and so on. I propose to use for solving the task, the tools built in to Windows 7/2008R2 and Powershell scripts.
So, let us take initial data with the following information:
the
-
the
- have an Active Directory domain the
- your organization uses computers with operating system Windows 7, server OS Windows Server 2008R2 the
- Has both network and local printers and MFPs. the
- There is a need to centrally process the log printing from the printers and have the usage statistics and the burden on printers.
the
infrastructure
The first thing you need to prepare the infrastructure for a centralized collection of event logs from client computers.
To work subscribe to Windows events on the source computer, you need the following settings:
-
the
- having the user in the group Readers event log (Event Log Readers), from which will be read in the magazine the
- Access remote management (Windows Remote Management with server-header the
- Customized solution for event forwarding to the server-logs header. the
- On the event log printing (disabled by default)
Create the snap in Users and Computers the new user as the full name and the username specified EventCollectorUser. Assign a complex password and put a tick "Deny password change the user and password expiration unlimited."
Next, create the new domain controller group policy and call it, for example, GPO-EventCollector.
Policy set the following parameters:
-
the
- under "computer Configuration — preferences — control panel Settings — Service" create service record "startup: automatic (delayed start)", "service Name — the Windows remote management (MS-Management) (WinRM)", "service Action: Launch services" the
- under "computer Configuration — Policies — Administrative templates — Windows Components — Windows Remote management Service the Windows remote management" to set the "Allow automatic configuration of listeners: insert" and section "IPv4 Filter" to put the value "*". the
- under "konfiguracija computer – Policies – Windows settings – security Settings – Windows Firewall with advanced security – Windows Firewall with advanced security – inbound Rules" create a new rule. Select the item "Predefined rules" and in the list choose "Windows Remote management (HTTP — in)" the
- under "computer Configuration — Policies — Administrative templates — Windows Components — event Forwarding" to set the "Customize the ultimate Manager subscription" and under option "SubscriptionManagers" to enter the full FQDN path to the collector server.
After you create a group policy, you must restart the target computers or do they gpupdate /force.
To turn the print log on the target computer using an MMC snap-in "event Viewer" on the way "the Logs of applications and services – Microsoft – Windows – PrintService – Works" (click right mouse button on the log and select "enable"). This option is suitable if the computers not so much.
If you want to enable the log for a large group PC, you can use the following method:
-
the
- to Prepare a text file with a list of computer names. For example, d:\temp\computers.txt the
- Run the following command as the user name with domain administrator credentials:
For /F %i in (d:\temp\computers.txt) do wevtutil sl Microsoft-Windows-PrintService/Operational /e:true /r:%i
Update: Also, as rightly pointed out NeSvist, you can set the registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-PrintService/Operational — Enabled is 1.
Set this option to distribute group policy that we created above.
For reference: About working with the registry in GPO
the
Creating event subscriptions
After preparing the infrastructure, you can go directly to configuring event subscriptions on server header.
-
the
- Go to the snap-in "event Viewer – Subscription". the
- Choose right menu "new subscription..." the
- Enter the subscription name, for example, "Test Subscription". Add a meaningful description. the
- Next, select the journal that will get taken of the event. I recommend to leave everything default is "Routed events". It is worth noting that to find a way to put events in the log that was created manually, I failed. So that option is by default remains almost the only one. the
- Then click on the button "Select...". In the opened window click "Add" to add the needed computers. The "Check" button to check the availability of the target machines by remote control, the result will show in the information window. the
- Choose the events that we will collect from sources. We are interested in the event-level "Data" from "Microsoft-Windows-PrintService/Operational" with the event code 307. All other settings leave default. the
- Click on the Advanced button, in the opened window select "specific user" and specify our created user and his password. Settings optimize the delivery of events subject to "Normal". the
- Click "OK" and the subscription is created. When the event log source computers, they are within 15 minutes will be uploaded to the server the collector in the magazine "Routed events".
the
the processing Script collected events
Collected events can be exported to CSV format by means of snap "event Viewer", the resulting data is not very informative and does not allow to obtain interesting statistics that can show leadership. So I offer the option of processing the received events by means of Powershell for convenience of their further use.
Search on the Internet was found a script log analysis Windows print Server 2003. (http://trevorsullivan.net/2009/11/06/windows-2003-print-log-parsing-script-powershell/) as there are certain differences in the Powershell cmdlets new versions, and a method of producing events differs from that proposed in the article, the script was revised.
The overall structure of the script I did not change, it is divided by functions, which are easy to modify (in the case of localization, for example). Logic of script is following:
-
the
- Receive the event list from the log the
- Parsim the Message property of each event and write the fields in the object PrintJob the
- save the resulting object list in CSV format
Get list of events from "Routed events" code 307 (in case the specified log forwarded any event).
{ $PrintEntries = get-winevent -FilterHashTable @{LogName='ForwardedEvents'; ID=307;} return $PrintEntries }
Create a new PrintJob object. Adding the required fields.
Hidden text
Function CreatePrintJob()
{
$PrintJob = New-Object PsObject
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name PageCount -Value $null
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name UserName -Value $null
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name DocumentName -Value $null
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Size -Value $null
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Printer -Value $null
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Time-Value $null
return $PrintJob
}
Derived from properties Message field events the username, printer Name, Number of printed pages in the document, the name of the document. this Pulls all of the strings by regular expressions. At English-language magazine change of line in regular expressions on the others, respectively.
Hidden text
#Parsim object parameters
ParsePrintEntry Function($PrintEntry)
{
$NewPrintJob = CreatePrintJob
$NewPrintJob.PageCount = GetPageCount $PrintEntry.Message
$NewPrintJob.UserName = GetUserName $PrintEntry.Message
$NewPrintJob.DocumentName = GetDocumentName $PrintEntry.Message
$NewPrintJob.Size = GetPrintSize $PrintEntry.Message
$NewPrintJob.Printer = GetPrinterName $PrintEntry.Message
$NewPrintJob.Time = $PrintEntry.TimeCreated.ToString()
return $NewPrintJob
}
#Get the user name
Function GetUserName($PrintEntry)
{
If ($PrintEntry -eq "" -or $PrintEntry -eq $null) { return $null }
$rxUserName = [regex]"owned by ([0-9a-zA-Z.]{1,})"
$rxMatches = $rxUserName.Match($PrintEntry)
return $rxMatches.Groups[1].Value
}
#Get the printer name
Function GetPrinterName($PrintEntry)
{
If ($PrintEntry -eq "" -or $PrintEntry -eq $null) { return $null }
$rxPrinterName = [regex]"printed on (.{1,}) through"
$rxMatches = $rxPrinterName.Match($PrintEntry)
return $rxMatches.Groups[1].Value
}
#Get the print size in bytes
GetPrintSize Function($PrintEntry)
{
If ($PrintEntry -eq "" -or $PrintEntry -eq $null) { return $null }
$rxPrintSize = [regex]"Size in bytes: ([0-9]+)."
$rxMatches = $rxPrintSize.Match($PrintEntry)
return $rxMatches.Groups[1].Value
}
#Get number of pages (most important parameter)
Function GetPageCount($PrintEntry)
{
If ($PrintEntry -eq "" -or $PrintEntry -eq $null) { return $null }
$rxPageCount = [regex]"Pages printed: ([0-9]+)"
$rxMatches = $rxPageCount.Match($PrintEntry)
return $rxMatches.Groups[1].Value
}
#Get the name of the document
Function GetDocumentName($PrintEntry)
{
If ($PrintEntry -eq "" -or $PrintEntry -eq $null) { return $null }
$rxDocumentName = [regex]", (.{1,}) owned"
$rxMatches = $rxDocumentName.Match($PrintEntry)
return $rxMatches.Groups[1].Value
}
The main function of. Get a list of events in the cycle turn it to the PrintJob object. Then do the export of the resulting list of objects to the specified file. Set UTF8 encoding for correct display of the Cyrillic alphabet and the separator ";" for reading open the file in Excel. Every 100 events, writing a log, this is useful for debugging.
the
Function Main()
{
$PrintEntries = GetPrintEntriesFromLog
$Global:ParsedEntries = @{}; $i = 0
ForEach ($PrintEntry in $PrintEntries)
{
$ParsedEntries.Add($i, $(ParsePrintEntry $PrintEntry))
$i++
if ($i % 100 -eq 0)
{ Write-Host "Processed $i records" }
}
$ParsedEntries.Values | Export-Csv "D:\PrintReports\PrintUsageReport.csv" -NoTypeInformation -Encoding UTF8 -Delimiter ';'
}
#Run the main function.
Main
In the preparation of regular expressions for the script used Regex101.com. The website is clear, concise documentation, highlighting a search result in the source string, deciphering the meaning of a regular expression on the fly. Very informative and conveniently, recommended for use.
The script can be applied on-demand, running in the command shell, PowerShell, and you can assign as a task in task Scheduler.
To do this:
-
the
- to Open the task Scheduler (start – administrative tools – task Scheduler) the
- Choose "Create basic task..." the
- Enter the task name, description, choose the interval at which to run the
- Choose action "launch the program". As the program select "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" and the argument is the path to the script. the
- to Open the task properties and set the switch to "Run regardless of user registration", select the user on whose behalf the task should be performed and enter the password from him.
Thus, specified when you created the script directory at a specified interval to update the file with the lists of published papers.
the
Troubleshooting
-
the
- If you run the script an error occurs:
file could not be loaded D:\PrintReports\PrintInfo.ps1 because the execution of scripts is disabled on this system. For more
this means that security policy to executable Powershell scripts allows you to run the program. To run the created script, you must lower the security level to "Remote Signed", i.e. is allowed to run any script created locally, but scripts created on remote systems, run only if signed by a trusted publisher. To do this in a Powershell console running as administrator, you must run the command Set-ExecutionPolicy RemoteSigned.
information, see about_Execution_Policies at go.microsoft.com/fwlink/?LinkID=135170.
+ CategoryInfo: security Error: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId: UnauthorizedAccess
the - To test the forwarding and collecting events, you can use the command line tool eventcreate.exe. This utility allows you to create events manually in a journal. For example, you can create an event with ID 100 in the Application log with the following command: eventcreate /t error /id 100 /l application /d "Custom event". If everything is configured correctly and is collecting events from a specified log, then the event will be on the server header within a minute.
If the event didn't get on the server header, it is necessary to check the following:
the-
the
- If the parameters are partly set by group policy, ensure that the policy is applied. If necessary, you can enforce group policy with the command gpupdate /force the
- service Status Windows Remote Management (WinRM) Service (Windows remote management). The service should be started and set to automatic startup. If necessary, the client computer can configure the service with winrm quickconfig. This command configures the WinRM service, creates a winrm listener, and creates a firewall exception rule.
To check that the server header can be connected to a computer source using WinRM, you can use the following command: winrm id-remote:<the target computer's Name> -u<username> -p<Password>. Specify the account and password of a user with the ability to connect via winrm.
the - User EventCollectorUser is part of the group event log Readers. Only members of this group can read event on a specific computer.
the
What can be improved
The proposed processing script is not a universal solution and can be improved in various directions, for example,
the
-
the
- selection of the events by time (per day, week, month) and write them to the appropriate individual sheets of a spreadsheet or output CSV files. You can include specifying a date range using input parameters of the script. the
- adding a graphical representation of data using pivot tables for users and printing devices and graphs. This report can be directly put on the head table. the
- Configure the archiving and rotation of the journal "Routed events", add a function analysis of the corresponding archive files. It would be wise when working with a large enough number of computers (more than 50).
So, in this article I tried to show the principle of centralized collection of event logs of Windows and their further processing by means of Powershell. This method is suitable for solving the problem in small organizations. Of course, specialized software to cope with the set objectives more efficiently, but it is expensive, more cumbersome, it brings IT specialist less new knowledge and skills, understanding of accepted software.
In the preparation of this article were used the following materials and sources:
-
the
- mcp.su/windows-server-2008/event-collector-in-windows-server-2008 the
- social.technet.microsoft.com/Forums/en-US/8e7399f6-ffdc-48d6-927b-f0beebd4c7f0/enabling-print-history-through-group-policy?forum=winserverprint the
- mywinsysadm.wordpress.com/2012/07/16/powershell-audit-printer-event-logs the
- www.winblog.ru/admin/1147767392-29031101.html the
- windowsitpro.com/security/q-what-are-some-simple-tips-testing-and-troubleshooting-windows-event-forwarding-and-collec
spoiler Title
# Get events from log
$Events = Get-Winevent -FilterHashTable @{LogName='ForwardedEvents'; ID=307;}
# Array of print jobs
$Jobs = @()
ForEach ($Event in $Events) {
# Convert the event to XML
$eventXML = [xml]$Event.ToXml()
# Create new object print job and fill in the fields from the XML representation of the event
$PrintJob = New-Object PsObject
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name PageCount -Value $eventXML.Event.UserData.DocumentPrinted.Param8
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name UserName -Value $eventXML.Event.UserData.DocumentPrinted.Param3
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name DocumentName -Value $eventXML.Event.UserData.DocumentPrinted.Param2
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Size -Value $eventXML.Event.UserData.DocumentPrinted.Param7
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Printer -Value $eventXML.Event.UserData.DocumentPrinted.Param5
# Given a date from a SystemTime format to the normal view.
$date = Get-Date $eventXML.Event.System.TimeCreated.SystemTime
Add-Member -Force-InputObject $PrintJob -MemberType NoteProperty -Name Time-Value $date
# Add the print job to the array
$Jobs += $PrintJob
}
# Display the list of received print jobs to CSV
$Jobs | Export-Csv D:\PrintReports\events.csv -NoTypeInformation -Encoding UTF8 -Delimiter ';'