Virgin Media and its not so Superhub

There was a time when I would have recommended Virgin media to anyone. Their flagship product at the time, the 50Mb service, was fantastic for me. A rock solid service that never had any issues (other than at one time when BT cut through the fibre), gave me a guaranteed 5MB/s, and never had any noticeable packet loss or congestion.

Since Virgin have upgraded me to 100Mbps however, I have had no end of issues. Two faulty “superhubs”, an awful service during peak hours, and countless minutes of unhelpful customer service.

virginmediasuperhub Virgin Media and its not so Superhub

Using my own router and disabling the “Super”hubs built in functions has improved things – I am no longer getting the hub losing connection and resetting itself 12 times a day – but not much. Not to mention the STMs being introduced. One could conceivably hit their STM limit with only ~20 minutes of legitimate useage (eg Steam, ISO downloads etc), let alone pirated material.

The bigger issue here however is that Virgin are chasing headline speeds without actually being able to sell the capacity required; hence the new STMs on its flagship product, and countless threads on the user forums about unuseable connections.

The worst of it? I have been told personally that the support team have detected “over-utilisation” on my UBR, but it is 3% below their threshold to raise it as a problem with the network team. In other words, I am going to have to put up with a dreadful connection during peak hours (when I might, oh I don’t know what to play a computer game, or the other half might want to watch IPlayer on our Smart TV), and endure it getting significantly worse until they will even raise it as an issue.

Cheers Richard, cheers Usain!

Creating IIS 6 Directories by C#

I’ve been writing this for a while today and couldn’t figure out why I couldn’t get the application to create within IIS. The virtual directory created without problems, but after that nothing happened. It turns out that the msdn library was incorrect!

Here is a working IIS 6 virtual directory creator. The only paramaters that need to be changed are in the // Set comment.

// IIS 6 Virtual Directory Builder and Configuration
// http://r-dunn.co.uk/ieatpenguin/computing/software/962/
// Please feel free to use and distribute

// Set variables: Site_Name,Path_to_wwwroot,Virtual_Directory_Name,Path_to_virtual_dir
// Change the port number after "ServerBindings" if you wish to use a different port.

using System;
using System.IO;
using System.DirectoryServices;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;

namespace System_DirectoryServices_DirectoryEntry_ConfigIIS
{
  class Program
  {
    static void Main(string[] args)
    {
        CreateSite("IIS://Localhost/W3SVC", "555", "Site_Name", "Path_to_wwwroot");
        SetSingleProperty("IIS://Localhost/W3SVC/555", "ServerBindings", ":8080:");
        CreateVDir("IIS://Localhost/W3SVC/1/Root", "Virtual_Directory_Name", "Path_to_virtual_dir");
    }

    static void CreateSite(string metabasePath, string siteID, string siteName, string physicalPath)
    {
      //  metabasePath is of the form "IIS://<servername>/<service>"
      //    for example "IIS://localhost/W3SVC" 
      //  siteID is of the form "<number>", for example "555"
      Console.WriteLine("\nCreating site {0}/{1}, mapping the Root application to {2}:", 
          metabasePath, siteID, physicalPath);

      try
      {
        DirectoryEntry service = new DirectoryEntry(metabasePath);
        string className = service.SchemaClassName.ToString();
        if (className.EndsWith("Service"))
        {
          DirectoryEntries sites = service.Children;
          DirectoryEntry newSite = sites.Add(siteID, (className.Replace("Service", "Server")));
          newSite.Properties["ServerComment"][0] = siteName;
          newSite.CommitChanges();

          DirectoryEntry newRoot;
          newRoot = newSite.Children.Add("Root", "IIsWebVirtualDir");
          newRoot.Properties["Path"][0] = physicalPath;
          newRoot.Properties["AccessScript"][0] = true;
          newRoot.CommitChanges();

          Console.WriteLine(" Done. Your site will not start until you set the ServerBindings or SecureBindings property.");
        }
        else
          Console.WriteLine(" Failed. A site can only be created in a service node.");
      }
      catch (Exception ex)
      {
        Console.WriteLine("Failed in CreateSite with the following exception: \n{0}", ex.Message);
      }
    }

    static void SetSingleProperty(string metabasePath, string propertyName, object newValue)
    {
      //  metabasePath is of the form "IIS://<servername>/<path>"
      //    for example "IIS://localhost/W3SVC/1" 
      Console.WriteLine("\nSetting single property at {0}/{1} to {2} ({3}):",
          metabasePath, propertyName, newValue, newValue.GetType().ToString());

      try
      {
          DirectoryEntry path = new DirectoryEntry(metabasePath);
          PropertyValueCollection propValues = path.Properties[propertyName];
          string oldType = propValues.Value.GetType().ToString();
          string newType = newValue.GetType().ToString();
          Console.WriteLine(" Old value of {0} is {1} ({2})", propertyName, propValues.Value, oldType);
          if (newType == oldType)
          {
              path.Properties[propertyName][0] = newValue;
              path.CommitChanges();
              Console.WriteLine("Done");
          }
          else
              Console.WriteLine(" Failed in SetSingleProperty; type of new value does not match property");
      }
      catch (Exception ex)
      {
          if ("HRESULT 0x80005006" == ex.Message)
              Console.WriteLine(" Property {0} does not exist at {1}", propertyName, metabasePath);
          else
              Console.WriteLine("Failed in SetSingleProperty with the following exception: \n{0}", ex.Message);
      }
    }

    static void CreateVDir(string metabasePath, string vDirName, string physicalPath)
    {
      //  metabasePath is of the form "IIS://<servername>/<service>/<siteID>/Root[/<vdir>]"
      //    for example "IIS://localhost/W3SVC/1/Root" 
      Console.WriteLine("\nCreating virtual directory {0}/{1}, mapping the Root application to {2}:",
          metabasePath, vDirName, physicalPath);

      try
      {
        DirectoryEntry site = new DirectoryEntry(metabasePath);
        string className = site.SchemaClassName.ToString();
        if ((className.EndsWith("Server")) || (className.EndsWith("VirtualDir")))
        {
          DirectoryEntries vdirs = site.Children;
          DirectoryEntry newVDir = vdirs.Add(vDirName, (className.Replace("Service", "VirtualDir")));
          newVDir.Properties["Path"][0] = physicalPath;
          newVDir.Properties["AccessScript"][0] = true;

          // Create Application, set appropriate documents and permissions
          newVDir.Invoke("AppCreate", new object[1] { 1 });
          newVDir.Properties["AppFriendlyName"].Value = vDirName;
          newVDir.Properties["EnableDirBrowsing"][0] = false;
          newVDir.Properties["AccessRead"][0] = true;
          newVDir.Properties["AccessExecute"][0] = true;
          newVDir.Properties["AccessWrite"][0] = false;
          newVDir.Properties["EnableDefaultDoc"][0] = true;
          newVDir.Properties["DefaultDoc"][0] = "ReportsIsapi.dll?Login,ReportsIsapi.dll";
          newVDir.Properties["AspEnableParentPaths"][0] = true;
          newVDir.CommitChanges();

          Console.WriteLine(" Done.");
        }
        else
          Console.WriteLine(" Failed. A virtual directory can only be created in a site or virtual directory node.");
      }
      catch (Exception ex)
      {
        Console.WriteLine("Failed in CreateVDir with the following exception: \n{0}", ex.Message);
      }
    }
  }
}

Don’t forget to use a double ‘\\’ in your pathnames to avoid the compiler interpreting them as an escape sequence. I certainly did.

Backing up The Latest File – Name Unknown

It’s a common enough issue for me that I want to be able to backup the latest backup of a database, and using variables to set date and time I never quite know what the filename of the backup will be.

::copy latest file to network server
set LF=
for /F %%i in ('dir /Od /b *.sql') DO set LF=%%i
:
echo%TIME% on %DATE%: Latest Backup is %LF% >> Backup.file
:
xcopy /Y %LF% \\networkserver\bugzilla

My solution is to sort the backup directory by date, and create a variable based on the filename of the most recent file.

I then echo the time and date to a file (Backup.file) so that I have a log of the backup process that I can check should I need to in the future.

Finally, the script copies the latest backup to a network location.

This was used in conjunction with my bugzilla backup script, hence the directory names, but it can of course be used for anything.

Automated Backup of Bugzilla Database on Windows

Bugzilla isn’t really designed to be used on Windows, but once set up its fairly easy to administer.

One obviously important thing is backing up the database. Using the niftily built in mysqldump I used the following solution. Note this assumes default settings were used in the installation of Bugzilla.

First, add mysql to the windows path if it hasn’t been done so already, by running up a command prompt:

PATH=%PATH%;C:\Program Files\Bugzilla\mysql\bin\

I then use a command file to create the backup dump, and then append the date and time to the file name. Note I have also created a user (backup) on the bugzilla database with a limited set of privileges (Select, Lock Table, Show Databases, Event).

rem commmand to dump the database to file
mysqldump -ubackup -pbackup Bugs > c:\bugsbackup\bz.sql

rem set date and time into useable file format
set _my_datetime=%date%_%time%
set _my_datetime=%_my_datetime: =_%
set _my_datetime=%_my_datetime::=%
set _my_datetime=%_my_datetime:/=_%
set _my_datetime=%_my_datetime:.=_%

rem rename file
ren "c:\bugsbackup\bz.sql" bz_%_my_datetime%.sql

This command file can of course be added to scheduled tasks and run as frequently as you want.

Event 41 Kernel-Power

Just a quick heads up for people that have this problem as it took me a while to figure out. This was my problem on a Windows 7 64bit Service Pack 1 install on an i5 CPU over-clocked to 4.0GhZ, with a Corsair CX650W. I attempted to put a GTX 580 into my computer, but when I did kept getting this problem. Despite my PSU being rated high enough (on the 12V rail) to supply power, it isn’t sadly.

These are the new “budget” range from Corsair, so perhaps I shouldn’t have been surprised, but it’s a bit irritating given that the specifications of the PSU show it being more than capable. Oh well!

SecurityTools

This is a nasty little program that masquerades as a security program that has found lots of viruses on your PC, and will clean them if you unlock it – eg if you hand over your credit card details.

The easiest fix I’ve found is using ComboFix, and then deleting the [random letter/numbers] folders found under ‘\Documents And Settings\All Users\’.

Windows Home Server v2 (Vail) is dead in the water

I’m a big fan of windows home server. They failed to deliver on some things, such as Media Centre integration, but that doesn’t really bother me. It’s a decent piece of server kit with a nice UI built over the top of Server 2008.

The best feature of it has to be Drive Extender, a disk management tool that allows you to pool your drives, of any size, and provides one click duplication, making installing new disks and taking backups a breeze for the home user. The clue is in the title: Windows Home Server.

Vail has been in the works for a while, and a recent post on the WHS blog has announced that the number one feature has been stripped. I’m fortunate enough, I guess, in that I understand how RAIDs work, and know how to set them up. However, I use WHS because I don’t have too. I spend enough time at work with computers that I don’t want to at home.

Absolutely unbelievable. Microsoft manage to alienate their core customer base (of this product) in one fell swoop.

Still, at least it saves me the cost of the upgrade.

Userenv Error 1500/1505/1508 – Profile Unable to Login

Windows cannot log you on because your profile cannot be loaded. Check that you are connected to the network, or that your network is functioning correctly. If this problem persists, contact your network administrator.

This annoying error message plagued me for quite a long time until I eventually found the solution. The problem appears to be with the pagefile not being able to perform user profile allocation properly.

After a fair bit of searching and tinkering, I eventually hit upon the following solution:

  • First set the pagefile to by managed by the system.
  • Load regedit, and find: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
  • Create a new DWORD called PoolUsageMaximum. Set this to 60 (Decimal).
  • Create/Modify PagedPoolSize (DWORD) to ffffffff (Hex).
  • Reboot.

What this does is simply force the Memory Manager in windows to attempt to trim the pagefile when it is 60% full, rather than its default 80%. This therefore starts the pagefile trim earlier, hopefully enabling the computer to cope with surges in memory demand more efficiently.