Archive for the ‘IIS’ Category

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 !!

.NET4 Framework Install Lacks MVC

Saturday, June 5th, 2010

I just upgraded all our Windows web servers to .NET4 to keep up with the Jones and take advantage of new features and capabilities that it pertains to offer. Soon after we discovered that the bare bones framework installation lacks some of the features that our developers make use of, in this case MVC.

Our developers and anyone who touches the web solution in any shape or form (including myself) all have the full blow installation of Visual Studio 2010 installed, which comes with everything and the kitchen sink (this was a seriously long list of components on the install list) so when they run against their local IIS instances all the VS bits are in place and it works.

However, the .NET4 framework install for Server 2008 does not include all the bells and whistles of Visual Studio 2010 and so we found some bits seemed to be *missing* when we deployed the solution, specifically MVC/MVC2 associated binaries.

More verbose details can be found here after one of our developers figured out how to make the missing bits copy to the web servers as part of the deployment.

Huge thanks to Colin :o)

IIS7 HRESULT: 0×80070057 (E_INVALIDARG))…….

Wednesday, March 24th, 2010

I don’t write code. Well compileable code anyway. Now scripting, I’m ya man, but anything that does stuff ‘behind the scenes’ is frankly a little bit beyond me.

So I was filled with doom when one of our web developers was getting an error every time she tried to load her dev copy of the site into her browser. IIS7 simply gave the very detailed but unhelpful message


HRESULT: 0×80070057 (E_INVALIDARG))

Along with a pretty error page and some bits of XML. Googling that error code led me to this site which thankfully explained what was going on, and more importantly, how to fix.

Seems that when you build/compile a .NET site, it takes copies of the binaries from your solution and copies them to a temporary folder. The site is then hosted from the files in this temporary location.

Should your system crash mid-build/compile (she was using Vista, of course it crashed !) then the file(s) copying at the time may not quite be up to scratch (i.e. corrupted).

For x64 bit systems the path in question is

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files

For x86 bit systems the path is

C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

Inside the ‘Temporary ASP.NET Files’ folder will be many sub folders. You can spend time trying isolate the exact subfolder containing the knacked files, but I just deleted all the sub folders and then rebuilt the web solution again and ‘Presto’ a working site

The site owner Dan Abdinnor credits his friend Patrick Fitzsimmons for working all this out. I don’t know who you guys are, but thanks, you possibly saved me from hours of diagnostic tools and head scratching on this one !

IIS7 AppPool user account causes HTTP 503 error

Tuesday, February 9th, 2010

I don’t profess to be any kind of IIS expert, in fact, I would say I’m more of an Apache man myself. I just find it easier dealing with flat text file for application configs, frankly while I’m sure there are benefits to having the IIS config all sorted in metadata and stuff, I just find it confusing and overwhelming, gimme httpd.conf any day.

While trying to configure an IIS7 AppPool to use a not evelvated logon to run as, I recieved a HTTP 503 error and the following was logged in Appilcation area of the event viewer.

The identity of application pool user.www.somedomain.com is invalid. The user name or password that is specified for the identity may be incorrect, or the user may not have batch logon rights. If the identity is not corrected, the application pool will be disabled when the application pool receives its first request. If batch logon rights are causing the problem, the identity in the IIS configuration store must be changed after rights have been granted before Windows Process Activation Service (WAS) can retry the logon. If the identity remains invalid after the first request for the application pool is processed, the application pool will be disabled. The data field contains the error number.

Quite a few possibilities mentioned there, so I started with the first one, incorrect user. I deleted the user logon, recreated it, set the password and then re-configured the IIS AppPool to use the newly created account. But still the page gave me a 503 error.

So I looked at the new possibility, ‘Batch Logon Rights’. Comparing the local security policy MMC for the server I was having trouble with and one that was working ok I found that the group ‘IIS_IUSRS’ had been granted the ‘Logon As Batch’ right on the standalone server, but not on the server that was part of a domain ?!

Local Security Policy MMC

As the domained server was controlled by group policies I could not just add the group directly to the permission, I had to create a group policy to grant ‘IIS_IUSRS’ the ‘Logon As Batch’ right and the run a ‘gpupdate /force’ on the domain server.

Restarting IIS and testing the site again showed everything now working correctly. It seems that the ‘IUSR_USRS’ group gets granted the ‘Logon As Batch’ right automatically on standalone servers, but not ones that are part of a domain, you have to grant the rights by adding them via a group policy.