Monday, April 19, 2010

How To Shrink a VMWare Disk With Windows 2008 R2

First off, the lesson to be learned:

Never ever create a bigger disk for your VM than necessary. It is WAY simpler to grow it later or attach more disks compared to shrinking the existing one!

Update - November 2010
With the new VMWare converter v4.3 you don't have to use v3.03 any more

(Solution is located at the bottom of the article)

I was recently assigned the task of moving a VMWare image created in VMWare Player 3 over to our ESX server (ESXi 4). In theory a simple task, in practice a lot of grief. Why you might ask?

The person creating the image had allocated a physical disk of 500gb, just to be on the safe side, while only 19gb were actually needed. This is perfectly dandy under VMWare Player since you don’t have to actually allocate all this space on your host disk, but when moving over to ESX, all 500gb will be allocated, and it is very much a waste on the SAN.

Jogged by an earlier memory that you could copy and resize just the partitions of the disk with VMWare converter made me fire up VMWare Converter 4. I went back and forth all over the menus but couldn’t find the options I was looking for. Naturally my next step was to install VMWare Converter 3.03 (actually it took me cose to 3h to get to that conclusion). And there the options were. What product manager decided to pull an excellent feature from a newer release?

Next I had to wait for the conversion to finish, dum di dum.. and for it to crash at 97%. There are many articles on the 97% crash in VMWare Converter, and in my case it was that it couldn’t configure the newly created machine. The disk had converted just fine, but wouldn’t boot. (It took me three conversions at 97% to figure this out). The reason it couldn’t configure it, is because Windows Server 2008 R2 is not supported in v3 of Converter, neither is it in v4.

Ok, so now I have a new vmdk file of 25gb, which boots under VMWare Player with the following Windows boot error: Status: 0xc0000225. In order to solve this I booted from the R2 dvd image inside VMWare converter and did this sequence:

  1. Select your keyboard layout and click "Next", and on the next screen click "Repair your computer"
  2. At the System Recovery Options screen, select your instance of Windows Server 2008 R2 OS from the list, and click "Next"
  3. Select the "Command Prompt" option and type:
    cd recovery
    startrep
  4. Click “Finish” when done, and Windows starts normally.

One step left, I uninstalled VMWare Converter 3.03 and installed v4. Then I started a conversion to move it over to the ESX server. (This last step could have worked with 3.03 as well, but I didn’t try it) Converting it to ESXi went perfect except that I had to remove and re-add the NIC to get it up and running.

Recipe:

  1. Shrink partitions with VMWare Converter 3.03
  2. Fix Windows boot with Repair option on Windows Server 2008 R2 media
  3. Convert image to ESXi with VMWare Converter
  4. Remove and add NIC

Tuesday, April 13, 2010

MSDN Partner Benefits for Visual Studio 2010

vs2010[Update - link to the VS2010 and MSDN licensing white paper]

The company I work for is a Microsoft Gold Partner with and MSDN subscription, and this includes licenses for the new Visual Studio 2010 released yesterday. As I’ve been singled out to administer Microsoft licenses I dived into the Microsoft Partner site to figure out what licenses we are entitled to use regarding Visual Studio 2010.

Friday, April 9, 2010

Show “Message Options” in Outlook 2010

Every now and then it’s interesting to look at the smtp headers in an e-mail and with Outlook 2010 they seem to have take a leave of abscense. But do not fear, this is how to get them back:

Choose Options in back office menu.

image

This will bring open the options screen for Outlook 2010

image

  1. Click “Customize Ribbon”
  2. Choose to filter by “Commands Not in Ribbon”
  3. Find Message Options

Next you need to create a new group, which you can place under the “Home” tab.

image

  1. Select “Home”
  2. Click “New Group”

Now it’s time to add the “Message Options” to the group we just made by clicking the “Add” button. And click “OK” to close the dialog.

image

In your ribbon you now have a new group with the “Message Options” command

image

When you are viewing a message and click this new button you will see the headers of the actual message like we wanted.

image

Tuesday, April 6, 2010

Compiling Linq to SQL the Lazy Way

In the March issue of MSDN magazine there was an article about precompiling Linq queries in order to optimize query speed for queries being executes numerous times.

This was perfect for the current project I’m working with, and I set out to change my code which originally looked like this:

string Original(int refId)
{
var query = DbContext.Notes
.Where( note => note.CaseId == refId )
.Select(note => note.Text);
return string.Join(";", query);
}

Creating a static compiled query along the lines of the article changed the code to this:

private static Func<DataContext, int, IEnumerable<string>> _compiledQuery;
private Func<DataContext, int, IEnumerable<string>> GetQuery()
{
if (_compiledQuery == null)
{
_compiledQuery = CompiledQuery.Compile((DataContext db, int refId) =>
db.Notes
.Where( note => note.CaseId == refId )
.Select(note => note.Text));
}
return _compiledQuery;
}

string Compiled(int refId)
{
var query = GetQuery().Invoke(DbContext, refId);
return string.Join(";", query);
}

This is your regular code with checking if it’s been created and if not instantiate it. What I don’t like with this approach, now that I’m a .Net 4.0 guy, is that you might compile it twice if two threads access it at the same time since it’s not thread safe. Putting double locking in there would also cloud readability.

Certainly no big issue, but since we now have the wonderful Lazy<T> operator we can write the code like this instead:

private static Lazy<Func<DataContext, int, IEnumerable<string>>> NotesQuery = new Lazy<Func<DataContext, int, IEnumerable<string>>>(
() => CompiledQuery.Compile((DataContext db, int refId) =>
db.Notes
.Where( note => note.CaseId == refId )
.Select(note => note.Text))

);

string Lazy(int refId)
{
var query = NotesQuery.Value.Invoke(DbContext, refId);
return string.Join(";", query);
}

Not as clean as the first version, but certainly less messy than the intermediate one. Using Lazy<T> on shared instances is a good way to ensure it’s created and to avoid threading issues. And if you never use it, which could be the case for a function in a general busuiness layer, you won't compile it if you don't need it.

If we could hide some of the signature it would look and read even better.