Thursday, March 21, 2013

printer statistics via SNMP

At work we have some multi-function copiers that do the whole print, scan, copy, deal.  What do you do if you want to track printer usage?.  You can either enable monitoring of print jobs on the print server, if your users go through a print server, or you can track the page counts on the printers themselves, if they are network printers.

In addition to tracking page counts, this script tracks how many sheets of paper are left in each of the trays (if your network printer is advanced enough to do that), and dumps all the information to a csv file.  Right now I'm running the script every hour or so to track what happens if I adjust some default settings.

For this you will need net-snmp, which you can get at: http://sourceforge.net/projects/net-snmp/files/net-snmp%20binaries/ if you're using windows, if you're using linux do apt-get install snmp or yum install net-snmp depending on your distro so that you get snmpwalk installed.

For linux you'll probably need to create a bash script of your own, based on the nagios script I used at:  http://exchange.nagios.org/directory/Plugins/Hardware/Printers/SNMP-Printer-Check/details

Without further ado here's my batch script (for windows):



@echo off
set snmpexe=c:\usr\bin\snmpwalk.exe
rem make sure to include the .exe at the end
rem netsnmp binaries are available from:
rem http://sourceforge.net/projects/net-snmp/files/net-snmp%20binaries/
rem shouldn't need to change anything between this and ":appendfile"
set prnip=%1
echo checking on the amount of paper left in the trays for printer %prnip%
for /f "tokens=2" %%W in ('date /t') do set dater=%%W
for /f "tokens=1,2 delims=:" %%t in ('echo %time%') do set timer=%%t:%%u
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set curdate=%%f%%d%%e
for /f "tokens=3 delims=/" %%y in ('echo %dater%') do set curyear=%%y
rem reset variables for when we run this multiple times (usually on different printers),
rem in the same enviroment (don't want previous valuse affecting this run).
set tray0=x
set tray1=x
set tray2=x
set tray3=x
set tray4=x
set pgcount=x
if "%1" == "" goto usage
if NOT exist %snmpexe% goto usage

if exist prn-%prnip%-%curyear%.csv goto appendfile
:newfile
echo this tells you how many sheets are still in each input tray/cassette in a printer
echo date ,time ,envelope ,tray1 ,tray2 ,tray3 ,tray4 ,pagecount >> prn-%prnip%-%curyear%.csv


:appendfile
rem this is for a printer with 4 regular trays and a "multi-purpose" tray, you
rem many need to change this a bit if your printer hardware is a little different
rem this is based on code from
rem http://exchange.nagios.org/directory/Plugins/Hardware/Printers/SNMP-Printer-Check/details
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.8.2.1.10.1.1') do set tray0=%%c
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.8.2.1.10.1.2') do set tray1=%%c
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.8.2.1.10.1.3') do set tray2=%%c
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.8.2.1.10.1.4') do set tray3=%%c
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.8.2.1.10.1.5') do set tray4=%%c
for /f "tokens=4" %%c in ('%snmpexe% -v1 -c public %prnip% 1.3.6.1.2.1.43.10.2.1.4.1.1') do set pgcount=%%c

echo %date% ,%timer% ,%tray0% ,%tray1% ,%tray2% ,%tray3% ,%tray4% ,%pgcount% >> prn-%prnip%-%curyear%.csv

goto end

:usage
echo usage: input-tray-count.bat ip-of-printer
echo this requires snmpwalk in the specified location
echo this will tell you how many sheets you have left in each input tray/cassette in a printer

:end

Monday, March 18, 2013

company CA without a cert server

For those who administer a network, sometimes you need to create a root certificate.  This can be for an internal web-server, or for deploying internal software, or for other reasons.  In many places you have a server setup who's sole purpose it get generate SSL and maybe other certificates for the company.  If you don't wan't to dedicate an entire server to this task though because you don't need to be constantly generating new certificates there is an alternative.

OpenSSL is an open source program (hence the Open part), that allows you to generate SSL certificates, everything from a root certificate (for your company root CA), to a regular certificate that's signed by the root CA.

If you're on a linux machine do your usual apt-get install openssl or yum install openssl, and skip the next paragraph for windows.

If you're on windows, you'll need to go to: http://www.openssl.org/related/binaries.html, and follow the links till you can download the openssl binary (full version) for window at  http://slproweb.com/products/Win32OpenSSL.html (you may need to download and install the visual C++ redistrutable).  You'll also want to add c:\openssl-win32\bin to your system's path or have the DLL's installed to the c:\windows\system32 directory.

To create a root certificate go to the c:\openssl-win32\bin directory and type:
openssl req -nodes -new -x509 -keyout my-ca.key -out my-ca.crt -days 3650 -config openssl.cfg
-leave the e-mail address blank.
-the above root ca will be valid for 13 years.

make the following directories, demoCA, demoCA\newcerts, and demoCA\private
under c:\openssl-win32\bin?
so you should have c:\openssl-win32\bin\demoCA\newcerts as one of your paths



move the *-ca.crt file to demoCA
the *-ca.key file to demoCA\private
in the openssl.cnf file go to the CA_default section and make sure that private_key = $dir/private/my-ca.key
and change certificate = $dir/my-ca.crt
(change my-ca.key to whatever you typed in the openssl command above)


type echo 01 > \demoCA\serial
and in explorer navigate to the demoCA folder and create a new text file
and name it index.txt (don't put anything in it).



to create server certificates for wsus:
openssl req -nodes -new -keyout servername.key -out servername.csr -days 1825 -config openssl.cfg
for Common Name enter servername.company.com
leave email address blank, and hit enter for challenge password and optional company name.

then sign it using the ca (certifies for 5 yesrs)
openssl ca -out server.crt -in server.csr -days 1825 -config openssl.cfg

then export it to pfx format for iis:
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile my-ca.crt
type in a password for the pfx
ignore message about "unable to write 'random state'




Thursday, March 7, 2013

rrd illegal time fix, and editing xml with sed


And now for some BASHing...

If you use rrd, and do a reboot of your computer, on rare occasion you might run into an error like the following (I put xxx in some places for privacy).  

ERROR: Cannot update /var/www/mrtg/xxx/10.x.x.5_xx.rrd with '1359389221:4100149299:563322753' /var/www/mrtg/xxx/10.x.x.5_xx.rrd: illegal attempt to update using time 1359389221 when last update time is 1359402962 (minimum one second step)

That long 10 digit number starting with 1359... is a unix time stamp, which is just the number of seconds that have elapsed since january 1st 1970.  If you can't figure out the cause of this error, you can edit the rrd files.  Unfortunately they are in a binary format and need to first be exported to xml, edited, and then converted back to binary format.  While there is a python script for editing xml files exported from rrd databases, it required a library which I was unable to properly install on my linux machine.  So I decided to create a bash script using sed, and not bother with python (or it's libraries)


Remember this is a BASH script, not a BATCH script.  So if you're going to run this on a windows machine you'll need to install cygwin first, and run it from inside of cygwin.  



#!/bin/bash
# you will probably want to run this as
# find . -iname "*.rrd" -print0 |xargs -0 -I {} rrd-fixer.sh {}

#first we convert the rrd file to xml format
rrdtool dump $1 > $1.xml
#we need to figure out the current unix date (epoc format, number of seconds
#since 1970)
udate=`date +%s`
#the heart and soul, take out the bad last update stamp, and replace it with
# one mrtg (or other rrd based tools), won't barf on
sed -e "s/<lastupdate>1[0-9]\{9\}/<lastupdate>$udate/" $1.xml > $1.fixed.xml
#rrdtool won't overwrite the bad rrd file on it's own, so have to remove
#it ourselves
rm $1
#convert the .xml file back to .rrd format
rrdtool restore $1.fixed.xml $1
#cleanup the xml files
rm $1.xml
rm $1.fixed.xml

# ---------- end of bash script --------------------------

note: if you want to run this on a folder with many rrd files (like mrtg or smokeping will often create), you will probably want to run the script in the following manner:
find . -name "*.rrd" -print0 |xargs -0 -I {} rrd-fixer.sh {}
or if you want to simplify it:
ls -1 *.rrd |xargs rrd-fixer.sh



fyi, the python script I came across is at: http://pierre.palatin.fr/old/rrd-repair

Thursday, February 28, 2013

net send for windows vista/7/8

Remember back in the day of NT/2000/XP, where you could type
net send computername some message here?

If you tried to do a net send with any version of windows since xp (vista/7/8), you've probably noticed that Microsoft removed net send entirely (with xp sp2, they disabled the service, but you could easily re-enable it).

Microsoft probably did this for security/anti-spam.  Back in the days when I was in college, I would often be getting net send spam.

You can use msg.exe which will send a message to a terminal server (has to be a server vision of windows), or to display a popup on your local computer.  If we combine that with psexec we have a way to replicate the functionality,

psexec \\remotecomputer msg.exe * /server:remotecomputer some message here

However this doesn't work very well if you have many computers (say a whole office?) that you need to send a message to.
So here's a script to make it easier if you have multiple computers:

rem --------beginning of netsend7.bat-------------------------


@echo off

rem this is for sending messages to computers using psexec and msg.exe

rem instead of net send. as net send doesn't exist in windows after xp

rem NEEDS PSEXEC.EXE in the the path or same folder.




if "%~1" == "" goto error




rem need to convert the list of computers

rem from comma to space delimited

for /f "tokens=*" %%c in ('echo %~1') do set comps=%%c

echo the computers are %comps%




rem extract the message from the command line

for /f "tokens=1,* delims= " %%p in ('echo %*') do set msg=%%q

echo the message is: %msg%




rem call the subroutine for each message.

for %%c in (%comps%) do call :submsg %%c







goto end




:submsg

set subcomp=%1

rem echo messaging %subcomp%, with message %msg%

psexec \\%subcomp% msg.exe * /server:%subcomp% %msg%

exit /b




:error

echo make sure to include quotes at the beginning and

echo end of the list of computers, but not the message,

echo usage "comp1,comp2,comp3,etc..." some message to the computers




rem check for psexec

where /q "$path:psexec.exe"

if %errorlevel% == 0 goto end

echo .

if not exist psexec.exe echo you need to have psexec.exe somewhere in the path.




:end


rem --------end of netsend7.bat-------------------------



If you want to accomplish the same thing without psexec, there is a guy who figured out a method using vbscript and setting a remoteRPC key in the registry on every computer you're messaging to:


Wednesday, February 27, 2013

synchronizing cross platform

If you've been in the computer field at all for the past few years, you've heard of the cloud, amazon s3, ec2, dropbox, windows live, carbonite, google docs, etc....

What if you don't want to store everything in the cloud, either it's too private, or don't want to run afoul of some data privacy laws (hippa?), or it would just cost too much to store all of the hours of baby videos you took.

Now you could use robocopy, or rsync, but these are both one direction.  If you have a laptop that you edit information on along with a desktop (or another laptop?), you probably want to sync your information between the two not just do a one direction backup.

Unison is the program I've been using to keep various repositories of information in sync.   It's cross platform, bi-directional, and doesn't involve the cloud, you control where everything is.

my usage is:
unison -batch profile.prf

the -batch option automates the synchronization process, without it, unison will ask about each and every file that it's copying, should it copy, delete, overwrite one, etc..., so you should probably run it just the first time without the -batch option (if at all).

profile.prf is the name of the configuration file (in the .unison folder if you don't specify a path to it), it can be any name though (pro.prf, home-sync.prf, etc...).

it'll also run over ssh like rsync does, or run a server also like rsync.

a unique feature of unison which I enable is for it to store previous versions of files into a separate folder (or you can store them in a hidden folder in the listing of folders being synchronized).

one of my .prf files, this is for windows, but unison on linux works just as well, just change the folders.

#######------start of prf file--------------

root = //server1/share/synced-folder1
root = //server2/share/synced-folder2

path = subfolder1
path = subfolder2
path = subfolder3

#as this is for windows, don't use fastcheck for unix usually
fastcheck = true
backup = Name *
#ignore any hidden folders, and cd images
ignore = Name {,.}*{.iso}
#where unison stores it's previous versions
backupdir = c:\Users\user1\unison-bak
#where to store the logs
logfile = c:\Users\user1\unison-logs\info-db
#the maximum number of previous versions
maxbackups = 10
#######------end of prf file--------------

Tuesday, February 26, 2013

sysinternals tools hanging due to license

You probably have come across (either in this blog or on other sites), various tools from sysinternals (psexec, psinfo, pskill, etc...).

While these are great tools, for the sysadmin, especially when it comes to automating and scripting, you may have noticed that they been absorbed my microsoft.  On it's own, being acquired by microsoft isn't necessarily a bad thing, however microsoft does now insist that you agree to a license the first time you use a sysinternals tool as a particular user on a particular machine.  This can be very problematic when running scripts on remote machines via psexec (the sysinternals tool will hang and not give you any indication that it's because you need to agree to a license).

One way to get around this is to put in registry keys onto the remote computer that you already accepted the eula,
reg.exe ADD HKCU\Software\Sysinternals\PsKill /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PsList /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PsInfo /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PSexec /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Process Explorer" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Process Monitor" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Autoruns" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\TCPView" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\RootkitRevealer" /v EulaAccepted /t REG_DWORD /d 1 /f

many thinks to http://peter.hahndorf.eu/blog/post/2010/03/07/WorkAroundSysinternalsLicensePopups  for the information, please go there for a more complete listing of registry entries for each of the sysinternals tools.  

Monday, February 25, 2013

Monitoring free space

Previously I described one unusual method to help clear out space on windows, details are here, If you want to make sure your windows server (or workstation), doesn't get too low on free space you can use some of the many monitoring tools out there which eat up system resources when you use them and/or cost an arm and a leg.  My solution is to have a script which goes out and checks the drives, and saves the information to a csv file so you can check for trends using any spreadsheet program.  It will also send out an e-mail if the space is too low.  I run this script from the windows task scheduler at 7am and 7pm, against all the different servers.

Usage:  drv-space.bat  servername

note: e-mail functionality requires blat.exe which you can get at http://www.blat.net/, and you will have to set some variables in the script also.


rem -----begin script --------

@echo off
set tech=network.admin
set techdom=company.com
set mailserver=mail.company.com
set machinednsdomain=company.com
set blatexe=c:\utils\blat.exe
set freespacenum=1000000000
rem shouldn't need to change any variable below here
rem usage drv-space.bat servername
set server=%1
echo processing server %server% at %date% %time%
for /f "tokens=2" %%W in ('date /t') do set dater=%%W
for /f "tokens=1,2 delims=:" %%t in ('echo %time%') do set timer=%%t:%%u
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set curdate=%%f%%d%%e
for /f "tokens=3 delims=/" %%y in ('echo %dater%') do set curyear=%%y
echo checking drive space
for /f "tokens=3" %%s in ('dir \\%server%\c$ ^|find "free"') do set drvct=%%s
for /f "tokens=3" %%s in ('dir \\%server%\d$ ^|find "free"') do set drvdt=%%s
for /f "tokens=3" %%s in ('dir \\%server%\e$ ^|find "free"') do set drvet=%%s
rem strip out the commas from the values
set drvc=%drvct:,=%
set drvd=%drvdt:,=%
set drve=%drvet:,=%
echo checking if we have at least a gig on drive c. 
if %drvc% LSS %freespacenum% goto emailwarning
goto savetocsv
:emailwarning
echo on 
echo we got less then 1 gig
rem if we have less then one gig we need to send an e-mail, but only if we haven't already done so today.  
if exist %temp%\%server%-%curdate%-low-space-msg.txt goto savetocsv
echo apparently need to email about %server% at %time%, only %drvc% bytes free
echo drive c on %server% has only %drvct% bytes of free space on it as of %date% %time% > %temp%\%server%-%curdate%-low-space-msg.txt
%blatexe% %temp%\%server%-%curdate%-low-space-msg.txt -to %tech%@%techdom% -server %mailserver% -f %COMPUTERNAME%_drv-space-check@%machinednsdomain% -s "%server% low on free space"
:savetocsv
if not exist %server%-free-space-%curyear%.csv echo date ,time ,drive c ,drive d ,drive e >> %server%-free-space-%curyear%.csv
echo saving to csv %time%
echo %date% ,%timer% ,%drvc% ,%drvd% ,%drve% >> %server%-free-space-%curyear%.csv

rem -----------------end of script----------------