Archive for June 23rd, 2010

Powershell Log File Zipper…….

Wednesday, June 23rd, 2010

Another annoying repetitive task automated ! Ahhhhhhh :o)

The log files for our IIS servers build up over a couple of months and consume disk space to the point of becoming an issue. I had been manually logging on and creating a .zip file for each month and then dragging the individual files into the zip file.

Tedious and repetitive, just the sort of thing scripting was made for. Typicaly my scripts for Windows are in vbscript, but this time I decided it was time to look at powershell.

The logic was simple enough. First create a zip file for the previous month. The logfile names are in the format ‘u_ex.log’ where mm is the numerical month. I needed to get the current month, subtract one (compressing previous months logs) and then move any file with a mm figure that matched into the .zip file.

I found this article for creating the actual zip file itself. Then is was just a case of setting the paths and looping through each file in the directory (get-childitem makes this a breeze).

Debugging the script was a bit of a pain in the arse using the built in Windows tools, so I downloaded and installed PowerShell GUI from here. It’s still a work in progress in some respects, the built in intellisense isn’t 100% there just yet, but it does allow you to step through code and what the vaule of your variables and figure out what is happening.

Once I had the script working of the command line, it was just a case of scheduling the job to run on the 1st day of each month recurring. However, this proved to be almost as big a task as the script itself.

For some reason, running powershell.exe and passing the script to it as an argument, ever using the full -command “$ syntax failed to execute the script. In the end I had to create a batch/.cmd file and place the powershell command in there and schedule the batch file to run instead.

My only gripe is that the command to move the file into the zip file is asynchronus so I had to include a sleep/wait period to give the file time to be compressed before being moved into the .zip file. That being said, there will never be more the x31 files, and allowing x2 mins for each file to compress (extremely generous) means the script should never take more than x1 hour to complete, so as long as I run it during a quiet period it should not impact anything else.

I eagerly await the 1st of July to see if the scheduled job kicks in automatically on the live evironment……:o/

#declare functions here
function new-zipfile {
	param ($zipfile)
	if (! $zipfile.endswith('.zip')) {$zipfile += '.zip'}
	set-content $zipfile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
	(dir $zipfile).IsReadOnly = $false
}

#define variables here
#some strings and numbers we will need
$thismonthint = get-date -f "MM"
$prevmonthint = (get-date).addmonths(-1).tostring("MM")

$thismonthstr = get-date -f "MMM"
$prevmonthstr = (get-date).addmonths(-1).tostring("MMM")

$thisyearlongint = get-date -f "yyyy"
$thisyearshortint = get-date -f "yy"

$thislogdir = 'C:\weblogs\'
$thiszipfile = $thislogdir + $prevmonthstr + $thisyearlongint + '.zip'
$zipexists = test-path $thiszipfile

#start program here
#first pass, check for .zip files of previous months. if exists exit. if not exist, create empty .zip file
if (! $zipexists)
{
	echo 'zip file does not exist, creating zip file'
	new-zipfile $thiszipfile
}
else
{
	return
}

# move all log files where the month number matches the month number of the .zip file
# Jan = 01, Feb = 02, Mar =03 etc. etc.

foreach ($file in Get-ChildItem $thislogdir)
{
	# exclude the .zip files already in the directory (just in case we get a random month match in their filename
	if (! $file.name.endswith(".zip"))
	{
		# if the
		if ($file.Name.substring(6,2) -match $prevmonthint)
		{
			$zipfile = (New-Object -ComObject shell.application).NameSpace($thiszipfile)
			$zipfile.MoveHere($file.fullname)
			Start-Sleep -Seconds 120
		}
	}
}

squish !!