Tuesday, April 20, 2010

Audit Windows 2003 print server usage


This post provides information on a solution to provide audit logs and summary information on printer usage on a Windows print server. This will provide daily and monthly printer event logs, and summary results based on one or more log files.

Pre-requisites:

  • A scheduled task that runs every day to collect and process the logs, it doesn’t have to be on the print server.
  • 'Log Spooler Information Events' on the printer spooler in question, which will write Event ID 10 entries every time someone prints through the spooler
  • A system event log big enough to capture at least one day's logs

Create a batch file that contains the following commands. Note that you will need to modify the variables or to reference paths as appropriate, eg for dumpel.exe and the VBScript, and the print/log dir.

Set PrintDir=c:\Print
Set LogDir=C:\logs
for /f "tokens=1-8 delims=/:. " %%i in ('echo %date%') do Set DateFlat=%%l%%k%%j
dumpel -s \\%print_server% -l System -e 10 -m Print -d 1 >> %logDir%\%server%_jobs_%DateFlat%.csv
for /f "tokens=3,4 delims=/ " %%i in ('echo %date%') do copy %server%_jobs_%%j%%i??.csv %PrintDir%\PrintJobs_%%j%%i.csv /y
cscript ProcessPrinterLogs.wsf /f:%LogDir%


If you create a scheduled task to run this batch file every day at the same time, these commands will:

  1. Dump the event logs for the past day to a daily log file with YYYYMMDD suffix.
  2. Collate the daily log files into a monthly log file, by appending each daily file. For each day in a month, this command will overwrite the previous monthly log, until it runs on the last day of the month.
  3. The script processes the dumpel log entries, providing different views in the form of per-printer, per-user, per-day totals of jobs/pages/bytes (useful for graphics), as well as summary totals of the information.

This has the following advantages:

  • It’s simple and not very intensive. A SQL database with a recurring DTS job to import the logs and then using SQL Reporting Services would be a lot prettier, but really not that much more functional or useful.
  • You will have a permanent set of log files, one for each month that you can store for historical purposes, while purging the daily log file directory every so often.

The ProcessPrinterLogs.vbs script that does all the work is listed below. To run:
cscript ProcessPrinterLogs.vbs /f:%logDir%

  Const ForReading = 1, ForWriting = 2, ForAppending = 8  Set objFSO = CreateObject("Scripting.FileSystemObject") Set objShell = CreateObject("WScript.Shell")  Main()   Sub Main()     If WScript.Arguments.Named.Exists("f") Then         sSource = Wscript.Arguments.Named("f")     Else         Wscript.Arguments.ShowUsage()         Wscript.Echo "Source file or directory must be supplied"         Wscript.Quit(2)     End If      If Wscript.Arguments.Named.Exists("o") Then         sOutputFile = Wscript.Arguments.Named("o")     Else         dNow = Now             dLogDate = DatePart("yyyy", dNow)          dLogDate = dLogDate & String(2 - Len(DatePart("m", dNow)),"0") & DatePart("m", dNow)         dLogDate = dLogDate & String(2 - Len(DatePart("d", dNow)),"0") & DatePart("d", dNow)             sOutputFile = objShell.ExpandEnvironmentStrings("%Temp%")         sOutputFile = sOutputFile & "\" & Left(WScript.ScriptName, InStrRev(WScript.ScriptName,".vbs")-1) & "_" & dLogDate & ".csv"     End If      wscript.echo "Input file/dir: '" & sSource & "'"     wscript.echo "Output file: '" & sOutputFile & "'"       If objFSO.FileExists(sSource) Then          sFileSet = sSource                                        ' Process a single file         wscript.echo "Single file specified - " & sFileSet     ElseIf objFSO.FolderExists(sSource) Then         wscript.echo "Source specified was a directory, reading files from '" & sSource & "'"         sFileSet = ""         Set oFolder = objFSO.GetFolder(sSource)                                ' Get the folder         Set oFiles = oFolder.Files         For Each oFile in oFiles                                    ' For each file             sFileset = sFileset & vbCRLF & oFile.Path                         ' Append to the fileset         Next         If Len(sFileSet) > Len(vbCRLF) Then sFileSet = Right(sFileSet, Len(sFileSet) - Len(vbCRLF))    ' Trim the leading CRLF     End If      Set dPrinters  = CreateObject("Scripting.Dictionary")                            ' Create the dictionary objects     Set dusers = CreateObject("Scripting.Dictionary")     Set dDates = CreateObject("Scripting.Dictionary")     Set dJobs = CreateObject("Scripting.Dictionary")      For Each sFile in Split(sFileset, vbCRLF)                                ' For Each file         wscript.echo "Processing '" & sFile & "'"         sBuffer = ""            Set objTextStream = objFSO.OpenTextFile(sFile, ForReading)               sBuffer = objTextStream.ReadAll          For Each sLine in Split(sBuffer, vbCRLF)                            ' For each line in this file             Call ProcessLogEntry(sLine, dPrinters, dUsers, dDates, dJobs)                ' Process the log entry         Next     Next      Call ProduceOutput(sOutput, dPrinters, dUsers, dDates, dJobs)                        ' Produce the output     Set objTextStream = objFSO.OpenTextFile(sOutputFile, ForWriting, True)     objTextStream.Write sOutput     wscript.echo "Output saved to '" & sOutputFile & "', " & Len(sOutput) & " characters."  End Sub  Function ProduceOutput(ByRef sOutput, ByRef dPrinters, ByRef dUsers, ByRef dDates, ByRef dJobs)     Dim strPrinter, strPort, dtmDate, strUser, strserver, strDocumentName, intSize, intPages, strInformation, strTotal     Dim strUserTotal, strPrinterTotal, strDateTotal, strJobTotal, aJobTotal      sOutput = ""     For Each strPrinter in dPrinters.Keys                 sOutput = sOutput & vbCRLF & strPrinter & "," & dPrinters.Item(strPrinter)     Next      sOutput = sOutput & vbCRLF     For Each strUser in dUsers.Keys         sOutput = sOutput & vbCRLF & strUser & "," & dUsers.Item(strUser)     Next      sOutput = sOutput & vbCRLF     For Each dtmDate in dDates.Keys         sOutput = sOutput & vbCRLF & dtmDate & "," & dDates.Item(dtmDate)     Next      sOutput = sOutput & vbCRLF     For Each strTotal in dJobs.Keys         strJobTotal = dJobs.Item(strTotal)         aJobTotal = Split(strJobTotal, ",")         sOutput = sOutput & vbCRLF & "Total Jobs," & aJobTotal(0)         sOutput = sOutput & vbCRLF & "Total Pages," & aJobTotal(1)         sOutput = sOutput & vbCRLF & "Total Size (MB)," & aJobTotal(2)     Next      sOutput = sOutput & vbCRLF     strUserTotal = UBound(dUsers.Keys)+1     strPrinterTotal = UBound(dPrinters.Keys)+1     strDateTotal = UBound(dDates.Keys)+1     sOutput = sOutput & vbCRLF & "Printers," & strPrinterTotal      sOutput = sOutput & vbCRLF & "Users," & strUserTotal      sOutput = sOutput & vbCRLF & "Days," & strDateTotal       aJobTotal = Split(strJobTotal, ",")     sOutput = sOutput & vbCRLF      sOutput = sOutput & vbCRLF & "Average jobs/person," & CInt(aJobTotal(0)/strUserTotal)     sOutput = sOutput & vbCRLF & "Average pages/person," & CInt(aJobTotal(1)/strUserTotal)     sOutput = sOutput & vbCRLF & "Average pages/person/day," & CInt(CInt(aJobTotal(1)/strUserTotal) / strDateTotal)     sOutput = sOutput & vbCRLF & "Average pages/minute," & CInt(aJobTotal(1) / (strDateTotal * 8 * 60))  End Function  Function ProcessLogEntry(ByRef sLine, ByRef dPrinters, ByRef dUsers, ByRef dDates, ByRef dJobs)     Dim strPrinter, strPort, dtmDate, strUser, strserver, strDocumentName, intSize, intPages, strInformation      Dim aPrintJob, intOffset, strTemp, aTemp      aPrintJob = Split(sLine, vbTAB)       If UBound(aPrintJob) = 9 Then         dtmDate = aPrintJob(0) ' & " " & aPrintJob(1)         aTemp = Split(dtmDate, "/")         dtmDate = Right("00" & Trim(aTemp(1)), 2) & "/" & Right("00" & Trim(aTemp(0)), 2) & "/" & aTemp(2)        ' Trim, pad and switch to dd/mm/yyyy instead of mm/dd/yyyy         strServer = aPrintJob(8)          strInformation = Trim(aPrintJob(9))         strInformation = Right(strInformation, Len(strInformation) - InStr(strInformation, " "))    ' Remove the job ID         intOffset = InStrRev(strInformation, " ")         intPages = Right(strInformation, Len(strInformation) - intOffset)        ' Extract the number of pages from the end         strInformation = Left(strInformation, intOffset-1)                ' Trim the string              intOffset = InStrRev(strInformation, " ")         intSize = Right(strInformation, Len(strInformation) - intOffset)        ' Extract the number of bytes from the end         strInformation = Left(strInformation, intOffset-1)                ' Trim the string                  intOffset = InStrRev(strInformation, " ")         strPort = Right(strInformation, Len(strInformation) - intOffset)        ' Extract the port from the end         strInformation = Left(strInformation, intOffset-1)                ' Trim the string                  intOffset = InStrRev(strInformation, " ")         strPrinter = Right(strInformation, Len(strInformation) - intOffset)        ' Extract the printer from the end         strInformation = Left(strInformation, intOffset-1)                ' Trim the string                  intOffset = InStrRev(strInformation, " ")         strUser = Right(strInformation, Len(strInformation) - intOffset)        ' Extract the user from the end         strInformation = Left(strInformation, intOffset-1)                ' Trim the string                  strDocumentName = strInformation          If dPrinters.Exists(strPrinter) Then                         ' Does this printer already exist in the dictionary?             aTemp = Split(dPrinters.Item(strPrinter), ",")                ' Find the existing printer job/page count             aTemp(0) = aTemp(0) + 1                            ' Increment the job count             aTemp(1) = aTemp(1) + CInt(intPages)                    ' Add to the page count             aTemp(2) = aTemp(2) + CInt(intSize/1024/1024)                ' Add to the byte count             dPrinters.Item(strPrinter) = Join(aTemp, ",")                ' Update the dictionary         Else             aTemp = Array(1, intPages, CInt(intsize /1024/1024))            ' Start the job/page count             dPrinters.Add strPrinter, Join(aTemp, ",")                ' Create this item         End If              If dUsers.Exists(strUser) Then                             ' Does this user already exist in the dictionary?             aTemp = Split(dUsers.Item(strUser), ",")                ' Find the existing user job/page count             aTemp(0) = aTemp(0) + 1                            ' Increment the job count             aTemp(1) = aTemp(1) + CInt(intPages)                    ' Add to the page count             aTemp(2) = aTemp(2) + CInt(intSize/1024/1024)                ' Add to the byte count             dUsers.Item(strUser) = Join(aTemp, ",")                    ' Update the dictionary         Else             aTemp = Array(1, intPages, CInt(intsize /1024/1024))            ' Start the job/page count             dUsers.Add strUser, Join(aTemp, ",")                    ' Create this item         End If          If dDates.Exists(dtmDate) Then                             ' Does this date already exist in the dictionary?             aTemp = Split(dDates.Item(dtmDate), ",")                ' Find the existing date job/page count             aTemp(0) = aTemp(0) + 1                            ' Increment the job count             aTemp(1) = aTemp(1) + CInt(intPages)                    ' Add to the page count             aTemp(2) = aTemp(2) + CInt(intSize/1024/1024)                ' Add to the byte count             dDates.Item(dtmDate) = Join(aTemp, ",")                    ' Update the dictionary         Else             aTemp = Array(1, intPages, CInt(intsize /1024/1024))            ' Start the job/page count             dDates.Add dtmDate, Join(aTemp, ",")                    ' Create this item         End If          If dJobs.Exists(JOB_TOTAL) Then                         ' Does the total already exist in the dictionary?             aTemp = Split(dJobs.Item(JOB_TOTAL), ",")                ' Find the existing total counts             aTemp(0) = aTemp(0) + 1                            ' Increment the job count             aTemp(1) = aTemp(1) + CInt(intPages)                    ' Add to the page count             aTemp(2) = aTemp(2) + CInt(intSize/1024/1024)                ' Add to the byte count             dJobs.Item(JOB_TOTAL) = Join(aTemp, ",")                ' Update the dictionary         Else             aTemp = Array(1, intPages, CInt(intsize /1024/1024))            ' Start the job/page count             dJobs.Add JOB_TOTAL, Join(aTemp, ",")                    ' Create this item         End If     Else         wscript.echo "skipped '" & sLine & "'"     End If End Function

Monday, April 19, 2010

Is it Safe to Delete HIBERFIL.SYS and PAGEFILE.SYS?

HIBERFIL.SYS is a file the system creates when the computer goes into hibernation mode. Hibernation takes everything in memory and writes it to your hard drive as the hiberfil.sys file. If you have 512MB of memory, then hiberfil.sys will be about 512MB. If you have 1GB, the file will be around 1GB. Even if you don’t use hibernation, hiberfil.sys will still take up this huge amount of disk space.
I have 2GB of ram in my laptop, that’s why my hiberfil.sys file is 1.99GB in size! Hibernation is enabled by default in Windows XP/Vista and since I don’t use hibernation at all, I might as well turn it off to get back my 2GB hard drive space and store something else.

In Vista:
  • Open Control Panel and type in “Hibernate” in the Search.
  • Click “Turn hibernation on or off”
  • Click “Change advance power settings”
  • Scroll to and expand the “Sleep” option.
  • Select “Off” to the “Allow hybrid sleep” option.
  • Scroll to and expand the “Power buttons and lid” option.
  • Select “Hibernate” for the “Sleep button action” option. 10. Select “Hibernate” for the “Start menu power button” option.
Then the hiberfil.sys would be deleted.


Here’s how to turn off Virtual Memory.
Go to Control Panel and run System.
Click on Advanced tab and click the Settings button on Performance.
Disable hiberfil.sys and pagefile.sys
Click on Advanced tab again and click on the Change button.
Select “No paging file” and click the Set button if you want to remove pagefile.sys.
Delete pagefile.sys

I wouldn’t recommend you to turn off your virtual memory unless you have lots of RAM. Virtual memory is an area on the hard disk that Windows uses as if it were RAM. So if you have very low RAM, maybe 256MB, turning virtual memory off will be a disaster. You will notice that your computer will struggle to multitask. As for my case, I have 2GB of physical ram and disabling paging file didn’t make any difference.

Visio viewer 2007 can't open visio file (.vsd)

I downloaded and installed Visio Viewer 2007 but the program can't be found at program files. I just learned that visio file (.vsd) ext. is already associated in IE 7 but the IE7 can't open the visio file. I searched some blog and I found the solution.

The solution was to uninstall a security update "Cumulative Security Update for ActiveX Killbits for Windows 'Your Version of Windows Here' (KB973525)"

The link to the update is here: http://go.microsoft.com/fwlink/?LinkId=158202. It appears that Microsoft in it's infinite wisdom accidentally put the Visio Viewer's CLSID in the kill list. Uninstalling this update, resolved the issue and I can now open Visio documents in IE.

Thursday, April 8, 2010

Windows 7 SP1 Build 6.1.7601.16537 Leaked

First off, this build is very recent, with a compile date of March 27th. The full build string is as follows:

6.1.7601.16537.amd64fre.win7.100327-0053

The install process is much of what you would expect from a service pack installer, but one thing I noticed is the installation is MUCH faster than the install process for service packs on Vista was, which is a very welcome change. Below are some screenshots from the installation process of Windows 7 SP1:

Install1 Install2

Install3Install4

Install5Install6


After the above process takes place the system will reboot a total of two times, which is actually a rather quick process. After this happens and you log in you are presented with the following screen:

Install7


Now SP1 is installed on your machine. Below are a couple of shots that show the elements of the system that contain the SP1 branding. Note that as with vista, the main build number has been incremented by one, so you now have Build 7601.

winversystempropsregistry



So there you have it everyone, a look at the Windows 7 SP1 beta. Like I said in the beginning of this post, it should be available from the usual sources for your experimentation very soon.

Download link:
http://thepiratebay.org/torrent/5484776/Windows_7_SP1_%287601.16537.100327-0053%29_Bits_UG_DVD_Beta_Interim

http://www.demonoid.com/files/details/2200306/4651332/



Monday, April 5, 2010

Slow File and Folder Copy, Move, Transfer or Delete Operation Speed Problem in Vista Fix

Solution 1: KB938979 Vista Performance Update

One of two update hotfixes from Microsoft for Vista that has symptom above described in the list of bugs been fixed – when you copy or move a large file, the “estimated time remaining” takes a long time to be calculated and displayed. Other than calculating estimated time remaining bug, KB 938979 update also addresses many other speed issues in Vista and worth installing to improve Vista performance.

Solution 2: KB931770 Hotfix

Another official update from Microsoft is KB931770 hotfix which intends fix a bug where copying files from network place will stop at “Calculating Time Remaining” dialog window showing “0 minutes remaning” status, but unable to finish the copying process automatically. The hotfix may also works to resolve other slow file copying or moving issues in Vista.

Solution 3: Turn Off Remove Differential Compression

Remote Differential Compression (RDC) allows data to be synchronized with a remote source using compression techniques to minimize the amount of data sent across the network. Disable and turn off Remove Differential Compression feature in Vista may provide a solution to slow file copy, file move or file delete bug.

How to Disable Remove Differential Compression in Vista

  1. Click on Start button, then go to Control Panel.
  2. Click on Programs link.
  3. Under Programs & Features section, select Turn Windows Features on or off link.
  4. Unselect (untick) Remote Differential Compression checkbox.
  5. Click OK.
  6. Wait for the feature to be deactivated.
  7. When done, restart computer.

Solution 4: Disable TCP/IP “Receive Window Auto-Tuning” and/or “Receive Side Scaling”

Vista TCP AutoTuning function is new feature of new TCP/IP stack in Vista that tunes and optimizes TCP receive window size for each network connection for optimum download/upload speed, while Receive Side Scaling (RSS) allows the network load from a network adapter to be balanced across multiple CPUs. However, the implementation is not always goes the intended way, and many has disable TCP Auto Tuning to solve issues such as slow multi thread download speed and various Internet browsing problems. This workaround can also solve file copy/move slowly bug.

How to Disable Vista TCP AutoTuning and Receive Side Scaling

  1. Open an elevated command prompt with administrator rights.
  2. Type the following commands and press Enter (the second command on RSS is optional):

    netsh interface tcp set global autotuninglevel=disabled
    netsh interface tcp set global rss=disabled

  3. Reboot computer.

Solution 5: Use Alternative Copying or Moving File Operation Engine

Vista file operations using Windows Explorer on desktop may be broken, but not with other utilities that come built-in with Vista. Robocopy is a robust command line file copy program that perform efficiently, and fast. It now also has Robocopy GUI to use on desktop.

Other standard copying commands such as “xcopy” and “copy” still complete the file operations in fastest time possible. You can also opt for third party programs such as TeraCopy that able to copy and move files faster at the maximum possible speed. The freeware also supports shell integration and can completely replace Explorer copy and move functions, allowing you work with files as usual.

Solution 6: Turn Off Windows Search

This method is unconfirmed, but worth a try if none else is working. Open Services applet in Control Panel or type Services.msc in Start Search, then go to Properties of Windows Search and set the Startup Type to Disabled. Windows Search is the component to run indexing services in Vista.

Solution 7: Turn Off Indexing Services

Similar to above, but you can opt to try excluding indexing service for certain locations in Indexing Options in Control Panel, or simply disable and turn off indexing for a certain drive or enable it only for selected folders via the Properties of a drive or folder.

Solution 8: Disable Thumbnail Preview

When you open a folder in Vista with Windows Explorer, the system will generate a preview thumbnail for almost every files. This mechanism may slow down the file operation process, especially when you want to delete the files, where Vista looks like so dumb that it’s creating thumbnail first before performing operation. To disable thumbnail preview feature, check the checkbox next to “Always show icons, never thumbnails” in the Folder and Search Options.

Solution 9: Turn Off IPv6 Support

Windows Vista installs and enables implementation of Internet Protocol version 6 (IPv6) by default. If you’re not using IPv6 which is not yet common, you can try to disable IPv6 support in Vista to see if it solves the slowness problem. To disable IPv6 on your Internet network connection, go to Network Connections folder, obtain properties of the connection and clear the check box next to the Internet Protocol version 6 (TCP/IPv6) component in the list under This connection uses the following items. This method disables IPv6 on your LAN interfaces and connections

To disable IPv6 on tunnel interfaces or the IPv6 loopback interface, go to Device Manager under System Properties in Control Panel, then click the View menu and select “Show hidden devices”. Right click on now-shown “Teredo Tunneling Pseudo-Interface” listed under Network and disable it.

Solution 10: Microsoft Workarounds for Slow Large Files Transfer between Vista and 2003 or XP Computer

Microsoft provides various methods to work around a problem where whenu users copy large files to or from earlier operating systems, the copy operation may be slower than expected on some Windows Vista-based computers. Check out the workarounds here, including close navigation pane and use mapped network drive.

Solution 11: Drivers Update

Old and incompatible drivers may cause issue with slow or corrupt data transfer. So, one of the best solution is to check the motherboard manufacturer’s website for any BIOS update

and system chipsets drivers. For example, if your board is using VIA northbirdge and southbridge platform chipsets, try to download latest VIA Hyperion 4-in-1 drivers update package,drivers package for nVidia/nForce platform, or for Intel chipset, latest INF update utility.