Welcome to TechNet Blogs Sign in | Join | Help

The long tail, Music and the small bookshop

I've talked about the millennial thinking before. I've heard it  said that the "iPod Generation" don't think about "Current Music" vs "Old Music". When I bought LP records there was never much back-catalogue in the shops. Growing up in Brighton there were second hand record stores which you could trawl if you wanted something which was long gone, but something which had gone out of the shops recently didn't show up. But, if you get most of your music by downloading, then there's no division into current and old. Music gets added to servers but it could be back catalog just as easily as it new releases - and server capacity can increase in a way that shelf space in a bricks and mortar shop never can. I recently went to see Gary Numan re-touring the 1979 Replicas Album. The audience was a mixture of 40-somethings who remembered the album from new, and students who'd discovered Numan from the various people who link to him and know Replicas from downloading it. At Radio 1's big weekend last week (great bit of Deep Zoom, by the way) - it was young fans who complained that Madonna didn't play her early stuff (we're talking 1983 music here - before some of them were born ).  Having heard Annie Lennox on Desert Island Disks this morning her Music from 1982/3 sounds every bit as good today [she picked the Beatles' Penny Lane as one of her 8 songs - I'd love to know what their download stats are like]. There are plenty more examples if you look, and of course this is what the idea of the long tail is about. Good music, (and good movies and good books too) will continue to find a market forever if you don't have to take them off the shelf. The same idea applies to blogs, Wikis and a lot of other "user generated content". If this blog were a newspaper column, it would appear, be read and disappear. As a blog the text remains - potentially forever, and thanks to search engines is discoverable and consumable - there are plenty of ramifications in that.

Two years ago now a couple of friends of mine announced they were going to open a bookshop. Part of me envied them, because I worked in a small bookshop before getting my first "proper" job after University and I remember it fondly. Part of me remembers running a business and the stress that went with it and would say "Never again"; that part also wondered if they had the resources to cope with a slow start or any spell of poor sales.  And part of me said "are they crazy ? Going up against Amazon etc on-line, and only a few miles from Oxford where book buyers are very well catered for".  It's pretty obvious that if you're going to make a success of it you can't compete on selection or price with the Oxford stores - much less with Amazon, but if you can make a place where people like to shop they will reward you with their loyalty. How to make such a place is a the challenge. Well Nicki and Mark seem to have cracked that because this week they picked up the Booksellers Association New Bookshop of the Year award. I'm sure it helps that they have a blog, but you have to more than that - things like this for example. Well done folks.

Posted by jamesone | 0 Comments

iSCSI, clustering and Hyper-V

One of the things I've been saying I'd blog for a while is how to set up a cluster on Hyper-V. Since Hyper-V does not support sharing SCSI disks between machines, you need to use iSCSI - which is all fine and good if you're doing it in production with real workloads and a proper budget; but a bit of a pain if you're doing it in a lab or training environment. Inside Microsoft I can get what I need courtesy of storage server, but what about the rest of the world ? There are several  iSCSI products with free evaluation versions so I was going to try a couple out, document them and post the results. Well my colleague in Ireland Gavin McShera, has saved me the trouble, with a blog post which explains it all. Once you've set-up iSCSI you Gavin links to the article on setting up a 2 node file serving cluster and you can see how easy clustering really is in 2008.

On knowing your sh*t

It's been an interesting few days, Monday was the Glasgow road-show event and Thursday was our day in Newcastle. The team didn't look upon flying with any great enthusiasm. So rather than returning home, drawing breath and heading North again we decided to stop en-route for an extra day and night: since we'd missed off-site event that the rest of our group had to spend time doing team stuff and thinking about goals for the financial year that starts on July 1st, we used the time for that - while enjoying some of the best countryside the UK has to offer. It was time well spent and  - thinking as a shareholder - I was glad to see a reasonable chunk of money saved (not quite so glad that a quirk of our expense policy means I'm paying a little of the cost myself) 

And so to Newcastle; we've visited Newcastle twice and got a good reception both times so it's a place I'm glad to come back to. (Some audiences seem pleased  that we bother going to them at all. London audiences expect us to go there and are the hardest to please.) Instead of being Travel weary, we were in a good frame of mind and delivered the best event we've done on this trip. Last time we were in Newcastle  Jonathan Noble met us and we ended up entering a pub quiz (and got close to winning!), so we gave him the task of finding another one and were joined by half dozen more "community" people. The quiz was fun and we might have won it, but we came in a contented third. There was an end-of-evening Jackpot prize for a one-off question: 25p to buy a slip, a £100 prize and one question asked after the slips were sold. The question. What are coprolites ?

Some years back a friend of mine - another of the Davids - bought the board game of Who wants to be a Millionaire ? Being on a few people's phone-a-friend list I did fairly well and found myself at the "£1,000,000" question. It was "What date was the battle of Hastings" - everyone assumes 1066, but not what year, but what day-of-the-year.  I'd once sent my Dad a birthday card which said on the outside "Do you know what day it is ?" and on the inside I'd written "The 925th anniversary of the battle of Hastings ? ", because he (and Mrs Thatcher if I remember correctly) both have the day of the battle as their birthday. So when the answers were  "13th of August" , "13th of September", "13th of October", or "13th of November" it was too easy. While we're on battles and anniversaries a different David celebrates wedding anniversary on Trafalgar day. I don't know how this stuff sticks in my head, but it's a useful trait for a technical chap.

I don't know why I know about Coprolites. But I do know they're fossilized dinosaur droppings. Whether to para-phrase something from the film broken arrow I don't know if I was more surprised that dinosaur poo CAN be fossilized, or that it is common enough that we have a word for it it . So £100 came my way. One Geordie - a good 20 years my senior - asked me with a huge grin on his face if "that means you know a lot about old sh*te" quite a few Microsofties would say that was a fair description.  I told my daughter about football that "you win as a team or lose as a team" and I didn't think of the prize as my money.  The winning team in the main quiz  put their prize in the Pub's charity boxes (RNLI and RNIB) and when I suggested that we do the same, all of my team agreed. It might be the first time our charity matching scheme has been presented with a pub receipt to support a claim - all being well the two charities should get £50 each; and that still doesn't wipe out the money we saved.

Posted by jamesone | 2 Comments

An e-mail message I was unusually pleased to receive.

KC had a post recently about "E-mail overload" - so called, and arguing we shouldn't point the finger at mail the whole time for the problems of information overload (her follow-up is worth reading too).  I've talked about the rubbish that lands in my inbox before... I won't go over that ground again.

When Steve and I heard that Scotty Macleod was well enough to post something on Dmitry's blog we both thought we should go and see him in hospital. I hate going into hospitals and I wasn't going to and see Scotty until he was well enough to appreciate it.  Scotty dropped each of us a quick thank-you note and apologized for not sending something longer.  His recovery still has a way to go, but I don't think I've ever been so pleased to find that someone could send an email. And Scotty if you're reading, don't worry Short is good .

Posted by jamesone | 0 Comments

More on the Hyper-V API

In which we see how to set the number of CPUs

I started with getting MSVM Computer System objects - which I showed back in February. With these objects I can ask for the state of the VM to be changed to Running, Stopped or Saved.

To do things in a proper Powershell Style I re-wrote and re-wrote my functions so I have GET-Vm (which returns one or more VM(s) by name), Choose-VM, which puts up a list and returns one or more VM(s). Plus Start-VM, Stop-VM and Suspend-VM. Over various iterations these have moved from demanding a single MSVM Computer System object, to accepting an or object or display name, then to accepting and of array either, to allowing input to be piped in. Since Stop-VM is a bit brutal, that same February Post showed using the ShutDown integration Component

Next I moved onto the Msvm_ImageManagementService, and a few weeks back I looked at how Virtual Hard disks can be created , mounted and Compacted.

From there it was on to the related idea of Snapshots which I covered here and here; Snapshots are handled through the Msvm_virtualSystemManagementService. This is actually a very important WMI class. I mentioned Taylor's post which shows how to manipulate the Exchange of Key/Value pairs (the Host's KVPs are managed through this object). But there are 6 other methods I want to introduce here they are Create-, Modify- & Destroy- VirtualSystem and Add, Modify and Remove Virtual System Resources.

Creating and Modifying work in the same way. Identify the machine (unless it is being created) and pass a block of XML which describes how you want the machine, or the resource attached to it to be. If you're think ahead and saying "Can I dump that XML out to a file ?" you can: both the Virtual System Management Service WMI object and the MMC console provide interfaces to Export or Import the Machine.  There are quite a lot of things which we want to be able to manipulate.

  • Legacy Network Card
  • VM-Bus Network Card
  • VM-Bus SCSI Controller
  • IDE DVD Drive
  • Virtual DVD Disk (which is inserted into the drive)
  • IDE Hard drive
  • SCSI hard drive
  • Virtual Hard disk-image (inserted into the drive)
  • Memory size
  • CPU cores and reservation
  • The VM itself

And for each of these we can get the XML by

  • Building it up from Scratch
  • Reading it from a file
  • Getting the existing value from WMI (for modification)
  • Getting a default from WMI (for creating)

The first 2 are usually a pain, so typically the process goes:

  1. Get a ResourceAllocationSettingData (RASD) object
  2. Modify one or more of its properties.
  3. Covert it to XML formatted Text,
  4. Pass the XMl as one of an array of arguments to one of the Methods of the Msvm_virtualSystemManagementService.

For example: here's how we set the number of CPUs - we get a variation on the generic RASD object, the Msvm_ProcessorSettingData object for the VM in question.

    Filter Set-VMCPUCount
{Param ($VM , $CPUCount)
$procsSettingData=Get-WmiObject -NameSpace  "root\virtualization" `
-query "select * from MsVM_ProcessorSettingData 
                                where instanceID like 'Microsoft:$($vm.name)%' "
$procsSettingData.VirtualQuantity=$CPUCount
$SettingXML=$procsSettingData.GetText([System.Management.TextFormat]::WmiDtd20) $arguments=@($VM.Path.Path, @($SettingXML) , $null) $Result=$VSMgtSvc.InvokeMethod("ModifyVirtualSystemResources", $arguments) if ($Result  -eq 0) {"Success"} else {"Failure, return code: $Result "} }

The process is almost identical for memory, except get the Msvm_MemorySettingData object and set 3 properties named, .Limit, .Reservation   and VirtualQuantity which are all set to the desired memory size in megabytes

In the next few posts I'll look at using the RASD objects to add disks and Network cards, plus how we can create and configure the VM itself.

Moving VMs to Hyper-v...

There are 3 things I get asked regularly about Hyper-V. The first is "When can I get it ?". I've covered this before, the product group have committed to ship by August 2nd, and I've thought for a while that they're looking good to beat that. At MMS Bob Muglia said how pleased we were with performance and we're running the main Technet and MSDN sites on Hyper-V already. Question 2 is "Can you compare X with feature Y in VMware ?". And the third is "Will I be able to move my VMs from X to the release version of Hyper-V ?". Where X might be Virtual PC, Virtual Server, Pre-release Hyper-V, or VMWare. So let's go over the basic rules.

  1. In many cases Virtualization installs its own drivers and management components into the child OS. Sometimes it is possible to remove these under another Virtualization environment, sometimes it isn't (for example if you used the extensions from Virtual Server before R2 SP1 they won't uninstall under Hyper-V). So if you're changing products it's usually easiest to remove these first. As you move between builds of the same product, it's a good idea (and sometimes a requirement) to install the latest ones in the child VMs.  [With Linux VMs you should check if a update needs new integration components and since these are provided separately make sure they're available].  We're moving to one version of the Integration components disk for all supported Windows OS's, which streamlines the process. . Server 2008 core can't auto-run disks and depending on the OS auto run may be disabled, so simply selecting ‘Insert Integration Services Setup Disk’  may not get the job done. Some of the components look like new hardware, so make sure you cancel the Found New Hardware wizard before installing them
  2. We call OSes without Integration Components "unsupported". This word tends to panic people. It doesn't mean you become an Outlaw in the eyes of PSS. Supported means if a flaw is exposed, it will get fixed. We have "Quick Fix Engineering" to provide patches to customers in this situation.  A VM running should look like a standard PC, so it should run OS/2, NT 3.x and 4, Novell NetWare 4 and 5, DOS 5 and 6. Some people might say in that case the Virtualization system "supports" those OSes , but if it exposes a latent flaw in an OS which is out of support, it won't get fixed; doesn't matter whose OS it was or whose Virtualization. If an out of support OS exposes a flaw in Hyper-V that doesn't show up any where else, it is only professional pride of the product group that drives a fix.
  3. A VHD is a VHD. You can take a VHD from any product which supports the format and mount it in Hyper-V. In itself that doesn't guarantee that the OS will boot and run properly, but you can mount the disk (as I showed here) and fix it off line. You wouldn't do that without making a copy of the VHD first would you ? Good.
  4. VMWare doesn't use VHD files. We've published our format and they've published theirs so there are conversion tools - we usually call this Virtual to Virtual migration, and we do it in SCVMM.
  5. Hyper-V's SCSI controller is what we call a synthetic one (VM-bus devices are "synthetic", non-VM bus ones are emulated). Synthetic devices are not available until the OS has booted, so Hyper-V must boot from IDE. (In the same way it can PXE boot from the Legacy NIC, but not the VM-bus one). When the OS is booted it also loads components which speed up IDE access substantially so there's no great speed advantage to using SCSI (there was in Virtual Server). If you were booting from SCSI before, using the same drive attached to an IDE controller is not normally a problem.
  6. Generally moving a VHD between Virtualization systems has the same effect as moving a hard disk between physical computers. You see a different BIOS, CPU, Mainboard, Network card etc. This may trigger re-activation. You can use the same product key - if activation tells you the key has been used, go through the telephone service. I've done this, so I know it is not onerous, although doing thousands of servers might be.
  7. Don't expect to move saved state files between builds. I know from personal experience you can't move saved states between Virtual Server 2005-R2 release and Service pack one builds, don't expect to do it between different builds of Hyper-V either, and if you had any thoughts of saving the state of a virtual server VM and bringing it back as a hyper-V one, I commend your optimism.  Online snapshots contain virtual machine saved-states: you can apply snapshots and shut the machine down and snap shot again to give an offline snapshot
  8. There is a KB article (949222) which explains updating from Beta to release candidate requires VM configurations to be recreated. The Beta-RC change was big enough to cause this but it shouldn't be repeated.

Those are all the bits I can think of, but if I've missed something I'll cover it in a later post

On Ninjas.

andrew2 Over the weekend one of the many Davids I count among my friends mailed me a curious job title from his organization. Yesterday, in one of those moments of serendipity Viral told me about one of the guys in Redmond who has the job title of "Zune Ninja" - he explains how the the title came about here. A while back I mentioned Tom Lehrer, and Plagiarize. Viral's good friend James Senior is the one whose name is cursed, when we found out he published first.

So while we're on Ninjas, I should say that when I drew the team cartoons using Janina Köppel's Excellent SP-Studio I couldn't find a way to capture Andrew so I tried doing him as SQL Ninja. This seems like a good time for that cartoon to come to light.

Posted by jamesone | 0 Comments

A couple of Virtualization links

Over on the Virtualization blog Taylor Brown has posted some PowerShell examples.  The first one on Mapping Worker process IDs to VMs wasn't that interesting (to me) in itself, but was a sign of interesting things to come, and the next one on creating VHDs was a covering ground I'd gone over (here). The third one is on key/value pairs and it's worth taking a moment to explain these. Put very simply when you install the Hyper V-Integration components there is more than just the drivers for an Integrated mouse, faster display, disk and network. There's a shutdown component (which I talked about here) - this allows the Parent partition to tell a child "start a proper OS shutdown; and there's a Key Value Pair (KVP) exchange component. This allows the child to say to the parent "I'm running Server 2008 SP1" or the parent to pass information to the child -and do so in a "clean" way.

Taylor asks what else readers might be interested in, so Taylor, if you're reading this. YES please show us how we can add Key/Value pairs, at either end and also show how we can read them in the child.  
And if you're looking for ideas, I'd like to see how you can set the Virtual System Global Setting Data items like Automatic Startup Action and Automatic Shutdown Action.

While we're looking at links , I mentioned that SCVMM V2 beta is available for download, there's a lot of information about the new version on the SCVMM home page.

Posted by jamesone | 0 Comments

Ways to tidy up my PowerShell - including making a hash of stuff

Please excuse the bad pun... When I first wrote the function I posted to display the state of virtual machines, I used a construction which has been familiar to programmers since time immemorial.

  If X=1 output this

If X=2 output that

etc

Most modern programming languages, including PowerShell, have some kind of switch construction which is a little tidier but they're still bulky...
I had put constants for each of the states in the .PS1 file which holds all my PowerShell VM functions. But this was more as a way of having a note of them than something I was going to use in my code. I could have written the Start-vm function (in the same post) like this 

   $VM.RequestStateChange($Running)

and re-coded my display function as

   switch ($_.EnabledState) { $Running {"Running"}
$Stopped {"Stopped"}
                         $Paused {"Paused"}
etc

but it still needs a line for each state. For completely separate reasons I was looking at hash tables. It takes one line to create a hash-table of return codes:

    $VMState=@{"Running"=2 ; "Stopped"=3 ; "Paused"=32768 ; "Suspended"=32769 ; 
"Starting"=32770 ; "Snapshotting"=32771 ; "Saving"=32773  ; "Stopping"=32774 }

So I changed the way I start and stop machines: one function does the work: expanding arrays, converting strings to computerSystem objects and actually changing the state: like this

   Function Set-VMState 
   {Param ($VM , $state)
    if ($VM -is [Array]) {$VM | ForEach-Object {Set-VMState -VM $_ -State $state} }
    if ($VM -is [String]) {$VM=(Get-VM -Machinename $VM) }
    if ($VM -is [System.Management.ManagementObject]) {$VM.RequestStateChange($State) } 
   } 

Using the hash Table and then I have Start, Stop and Pause functions like this:

   Filter Start-VM
   {Param ($VM)
$if ($vm -eq $null) ($vm=$_} Set-VMState -VM $VM -State $vmStates.running }

I also made a change to accept input from the pipe e.g. Get-VM "James%" | start-VM , there are two changes (a) use a FILTER instead of a FUNCTION and (b) pick up the piped input in $_ . So I've got quite a few functions where I should  change this.

HashTables are a one-way lookup: $VMstates.running returns the value with a key of "Running" - 2 in the Start-VM filter.  If I have "2" and want to get back to "Running" there isn't a built in way(that I know of). However PowerShell has a GetEnumerator which dumps out the whole hash table as Key/value pairs, which that makes it easy to get the name we want.

   function Convert-VMStateID
    {Param ($ID)   
($vmState.GetEnumerator() | where {$_.value -eq $ID}).name }

and using the choose-list function I showed before before , choose-VM becomes a one liner

Function Choose-VM

{choose-list -data (Get-VM) -fieldList @(@{Label="VM Name"; Expression={$_.ElementName}},
@{Label="State"; Expression={Convert-VMStateID -ID $_.EnabledState}}) }

(In principle it is a one liner ... in  practice I'm going to have a -multi switch to allow single or multiple selections.

One other thing I've done in this tidying up exercise is to make sure I name my parameters in scripts. This means I really should go back to my Choose-list function and rename the "Field list" parameter to "Property" to match Powershell's built-in cmdlets (just as I have been trying to use existing Verbs and write my nouns in the singular !).  Identifying parameters by position doesn't make for readable code:  the following two lines are equivalent, but which would you rather see in a script (not the one you'd rather type at the command line !)

Set-VMState -VM $VM -State $vmStates.running  
Set-VMState  $VM  $vmStates.running 

 

Ah, the joy of feedback

As I mentioned before we're getting updates on the feedback from the roadshow: George has a report for us the next day. On one of our past roadshows I had a serious sense of humour failure about the speed we got feedback - the system then cost a fortune and delivered information too late to act on it. I changed my presentation based on a reported comment which turned out to be unrepresentative and made it less effective.  So this change is one I'm particularly pleased with. Numbers give us something measurable, but the comments are things we can act on. But there's not much we can do when we get successive comments which say "Very well presented, nice to have two presenters covering the topics." and "Chit chat between presenters grated."

So let me just explain why we've taken to having two people on stage. One of things that we know people hate is "Death by PowerPoint" (confusingly some people also want us to provide a slide deck which would stun an Ox). Of the 85 answers to "what was best about the day" we had in London about 1 in 6 picked out demos .

  1. Demoing the product. eye-test
  2. Live demonstrations.
  3. Windows Server 2008 Core demo, explanations regarding powershell.
  4. Demonstration.
  5. I much prefer the hand-on demos than watching power point slides.
  6. Live demos, not all power point.
  7. How to manage Windows Server 2008 presentation.
  8. Excellent demonstrations, little sales pitch (except for hyper-v!).
  9. The material presented, not death by Powerpoint but much more Demo focused. Kept it much more interesting!
  10. The venue was fantastic and demo of installing windows 2008.
  11. The openness of the talks The tech demos.
  12. Live demonstrations.
  13. I liked the fact that we were able to see live demos of the products’ in use and to be able to ask questions.
  14. Quality of speakers and good demos.

Here's the thing though. Demos are HARD. PowerPoint is EASY. Now I say "easy", actually to speak about something technical, to do it lucidly (not reading) and be interesting, to do in front of audience of between 200 and 600 people without being overcome with nerves, and - given the range of the audience - make sure that at any given time 95% of the room can understand you but you're not patronizing more than 5% .... this is stretching the definition of easy. Building a demo which shows the point, which you can actually do on stage, which is repeatable isn't too hard. If that demo involves writing code or entering long command lines  there is always a risk of errors. When you have a dozen or more (virtual) machines on the network the chance that one is on when it should be off (e.g. you have two DHCP or Remote boot servers for different demos) or off when it should be on becomes greater than 50:50. Everyone has seen a demo fail and the presenter battle to get working long past the point when they should give up. And when you need to concentrate on what you're doing you have a thousand eyes staring at you and every instinct you have is yelling "KEEP TALKING". A second presenter can

  • Do the next part of the presentation, while you fix a problem
  • Explain what you're doing when what you have to type needs you to shut up and concentrate
  • Do a step of the demo when you've stepped out to answer a question from the floor

They can also be a stooge "So James what's this great feature here do then ? " - but if they do their job right they can ask the question that the audience want to know, or even say "James, at the last event you explained what that did, would it be good to share that again ?". Bottom line ? Having a co-presenter improves my delivery

A huge amount of effort goes into to these events and we're seeing dozens of positive comments - some by e-mail and some on our blogs as well, and it's good to know we've pleased a large slice of the audience.

There will always be a few who can't be pleased. There was the person in London who wrote "I was under the impression that Windows Server 2008, Visual Studio 2008 and SQL Server 2008 were going to be the focal points for the day." who must have clicked the link to register without reading the description.

And then in Manchester we had a couple of comments in the "What would make things better"

  • An understanding by microsoft to move to a new Operating system (Vista) is not just a technology jump but a huge staff training exercise.
  • Stop banging on about Vista and its benefits. Microsoft has to accept that they have misjudged the market and need to put the customer first. By implying Vista SP1 will fix everything is ignorant on Microsoft's part. We can not keep re-training users just because Microsoft have brought out a new interface/Operating system.

Sorry... "Don't talk about benefits of a new product". Why ever not ? Why come to events about new products if you don't want to hear about them ? Accept that we've "misjudged the market" - that would mean starting to believe that most IT managers are Luddites who don't give a stuff about user productivity or security or the proportion of their own time that is needed just to maintain the status quo. "We can't keep re-training users just to make them more productive". If that were the case we'd still be on DOS, or Windows 3.1 or Windows 95. I doubt if either of these guys have even used Vista. Contrary to what you might think most people who work at Microsoft UK (many of whom are agency staff) work in non technical roles - Sales, Marketing, HR and so on. One great boss in my pre-Microsoft days had sold Custard Powder (he worked for Bird's selling it to supermarkets after the famous factory explosion) and he said he knew no more IT than he did about Custard powder. Our marketing people got 2 hours on vista and office 2007, tops. The greater productivity that you get from both pretty quickly cancels out the initial dip that comes from finding your way round a new environment. With more and more Vista PCs going into homes it won't be long before you have to spend time training people how to use the unfamiliar - and less productive - older software.

Posted by jamesone | 1 Comments
Filed under:

Something for the photographers: Silverlight Deep-zoom formerly "Sea-Dragon"

With all the other stuff I've been doing lately I'm champing at the bit to get out and take some more photos. Still here I am slaving over a hot laptop.

Search suggests haven't mentioned Sea-Dragon before - but I've talked about Photosynth, which is one of the technologies that use it. We've been saying since at least last October that Sea-Dragon is going into Silverlight.  Which is exciting stuff, it's also getting a new name "Deep zoom".  Eileen picked up some stuff on this - we have Deep Zoom Composer available for Download. I've had a brief play with it but it's output is really intended to go into something else*; more interesting - to me at least is Photo Zoom. Imagine a "contact sheet" view of your photos with pretty much unlimited zoom in and out. That, in a nutshell is Photozoom. As yet it is not a fully featured photo gallery - it doesn't have the tags and other text that I'd want but as a proof of concept of where this is heading it's exciting stuff.

We always have bit "in the works" that I can't really talk about, but an interesting bit of software came my way this week, and the folks behind it have said I can talk about what it produces. What they've given some of us is a test harness for both ideas, and code to implement them. In what form these see the light of day outside the company and when - if at all - remains to be seen.

So here is one of my favourite pictures, party because I sold it a print of it to someone whose London Office is in there

st pauls Click for the Deep zoom version

The original was 38 Mega-Pixel image and the print was 150x21 CM in size (60" x 8" ) an 8:1 aspect ratio is lousy to view on screen and even worse if you want to store it online.
But now I have a version set up for deep zoom. - I can find the window of my patron's office, but I can move around it interactively much like looking at a big print hanging on the wall.

Before you click through (a) It needs Silverlight 2 Beta installed. If you get an error about Invalid XML character after installing Silverlight you need to close and restart the browser. (b) The experience is OK with the glidepoint device on my laptop, but it's much better with a wheel mouse.

*Update. My colleague Marc Holmes gave me some info, which is now on his blog, to show me how to upload my frist DeepZoomComposer project to silverlight. You can see it here nothing too fancy, just a few pictures that I happen to like. in one project.

Posted by jamesone | 1 Comments

Hyper-v Snapshots part 2.

In my last post I explained how snapshots work and gave a little bit of PowerShell for creating a one . In the post before that I talked about creating a generic  choose-tree function. What I wanted was to be able to call Choose-tree  List_Of_Items First_Item  PathPropertyName, ParentPropertyName, PropertytoDisplay and get a tree view I can choose from: like this

    $folders=dir -recurse | where-object {$_ -is [system.io.directoryInfo]}
    choose-tree $folders (get-Item (get-location) ) "PSPath" "PsParentPath" "Name"

0    +windowsPowershell
1    | |--Nivot
2    | |--Pics Which one ?: 2

The key thing in this is that PowerShell lets us use variables/parameters to hold field names. The logic is pretty simple. Take an array of items, and tell the function which one to start at, Output that item, if it has any Children call the function recursively for each of them. Checking for children is where this ability to pass property names is important, because I can use  where-object {$_.$parent -eq $startat.$path.ToString()} to say "where the field I said holds the parent, matches the field I said holds the path" I put a "ToString" on the end because I found it doesn't like being passed "path.path" and that's needed for some WMI items; toString() returns the path in this case but it's safe for strings too. When the function calls itself it specifies how many levels deep in the tree the current item is - each level of recursion adds 1 to $indent in the function.

I wrote an "Out tree" before doing "choose-tree", most of the code below is associated with making choices When processing the topmost item it sets up a counter to allow the user to choose the items, and because the output order might not be the same as the input order it also sets up an array to hold ordered items. Once all the child items have been processed it prompts the user for a selection  and returns the item at that position in the array. 

The only thing that I've done here that is out of the ordinary for me is I don't like using the -f operator on strings because it makes for unreadable code. "{0, -4}" -f $counter. Says "Put argument at position 0 into this string , right justified to 4 characters", which is just what I need, and I've put in the rest of the output line into the same construction.

   Function Choose-Tree
   {Param ($items, $startAt, $path=("Path"), $parent=("Parent"), 
    $label=("Label"), $indent=0, [Switch]$multiple)
    if ($Indent -eq 0)  {$Global:treeCounter = -1 ;  $Global:treeList=@() } 
$Global:treeCounter++
$Global:treeList=$global:treeList + @($startAt)
$children = $items | where-object {$_.$parent -eq $startat.$path.ToString()} if   ($children -ne $null)
{ $leader = "| " * ($indent)
"{0,-4} {1}+{2} "-f  $Global:treeCounter, $leader , $startAt.$label | Out-Host
$children | sort-object $label |
ForEach-Object {Choose-Tree -Items $items -StartAt $_ -Path $path `
                      -parent $parent -label $label -indent ($indent+1)}
     } else { $leader = "| " * ($indent-1)        
"{0,-4} {1}|--{2} "-f  $global:Treecounter, $leader , $startAt.$Label  | out-Host } if ($Indent -eq 0) {if ($multiple) { $Global:treeList[ [int[]](Read-Host "Which one(s) ?").Split(",")] }
else           {($Global:treeList[ (Read-Host "Which one ?")]) } 
                      } }

And so to snapshots. 

The parent partition and every child MsVM_ComputerSystem WMI object which represents it. The "Name" field in this object is actually a GUID. There is a second object MsVM_VirtualSystemSettingData: each VM, and each of its snapshots has one of these objects. The Settings data object for VM itself has it's GUID in both the InstanceID and systemName fields, but the Snapshots have their own instanceID with the VMs GUID in the system name field. As with most of my functions I things up so I can pass the MsVM_ComputerSystem object or pass a string and use Get-VM  to convert it. Then I it's one Get-WMObject operation to get the Snapshots.

   Function Get-VMSnapshot
   {Param( $VM=$(Throw "You must specify a VM") )

if ($VM -is [String]) {$VM=(Get-VM -machineName $VM) }
Get-WmiObject -NameSpace root\virtualization -Query "Select * From MsVM_VirtualSystemSettingData Where systemName='$($VM.name)' and instanceID <> 'Microsoft:$($VM.name)' " }

Time to combine choose-tree and get-snapshot to choose my snapshots from a tree. As I said above , the Name field is actually a GUID, and the display name for the Snapshot is in the elementName . So I display the tree of choices,starting with the "Root" snapshot. [Note I'm aware that I don't cope with the situation where you delete a root snapshot with two children and get two roots]

   Function Choose-VMSnapshot
   {Param ($VM=$(Throw "You must specify a VM"))
    $snapshots=(Get-VMSnapshot $VM )
    Choose-Tree -items $snapshots -startAt ($snapshots | where{$_.parent -eq $null}) `
        -path "Path" -Parent "Parent" -label "elementname" }

Now I can choose my snapshots, it's easy to tell a function like Remove-snapshot or apply-snapshot what I want. Here's Remove-Snapshot , which I can call with something like
Remove-snapshot -snapshot (choose-Snapshot Core). Pretty simple stuff, I use the variable pointing to to the virtual System Management Service, as I did when creating a new snapshot this time I just need to invoke the RemoveVirtualSystemSnapshot method. As with the new snapshot it should return 4096 for "started processing in the background" , and I return the Job ID.

   Function Remove-VMSnapshot 
   {Param( $snapshot=$(Throw "You must specify a snapshot") ) 
    $arguments=($snapshot,$Null) 
    $result=$VSMgtSvc.InvokeMethod("RemoveVirtualSystemSnapshot",$arguments) 
    if ($result -eq 4096){ $arguments[1] } 
    else                  {"Error, code:" + $result} 
   }

Finally I might want to apply a snapshot , and this needs us to specify the VM and snapshot. I've written this so that if the Snapshot is omitted the user is prompted to select it. It's the same process again, except this time we use the ApplyVirtualSystemSnapshot Method

   Function Apply-VMSnapshot
   {Param( $VM=$(Throw "You must specify a VM"), $SnapShot=(choose-VMsnapshot $VM))
    if ($VM -is [String]) {$VM=(Get-VM -machineName $VM) }
    $arguments=@($VM,$snapshot,$null)
    $result=$VSMgtSvc.InvokeMethod("ApplyVirtualSystemSnapshot", $arguments)   
if ($result -eq 0) {"Success"} elseif ($result -eq 4096) {"Job Started" | out-host $arguments[2]} else {"failed"} }

If you're wondering what to with the Virtual Hard disks I showed I'll get round to that soon.

Hyper-v and Snapshots (Part 1)

The machine is running quite happily and has never been snapped. Late on Monday make a snapshot. This does two thingsHyper-V-Snapshots

1.If the Machine is running or in a saved state we make a copy of memory

2. We stop writing changes to its VHD and start writing changes to a new AVHD file. (Lets call this AVHD-1)

At any point when we want to revert, we go back to the original hard disk and the Monday memory state. Throughout Tuesday changes are written to the AVHD-1then on Tuesday night we do another Snapshot. The same thing happens

1.If the Machine is running or in a saved state we make a copy of memory

2. We stop writing changes to AVHD-1 file and start writing changes to a new AVHD file. (Lets call this one AVHD-2)

Now we can revert to two points, Monday's memory state and the original VHD or Tuesdays memory state and the combination of the original VHD and AVHD-1

Lets assume that on Wednesday something happens to cause us to go back to Monday's state. We can either (a) Keep AVHD-2 and save the memory state as it was on Wednesday or (b) Discard AVHD-2 and memory state. Either way the server now starts a new AVHD file - lets call this one AVHD3. Thursdays changes get written to this, and on Thursday night as before we do another snapshot and start AVHD4 for Friday's changes and keep the memory state as it was on Thursday.

Now we can apply 3 states (or 4 if we kept Wednesday's). We often talk about "rolling back" to a snapshot, but here, some of the snapshots we can apply aren't simply forward or backward, hence Hyper-V talks about applying snapshots.

It also talks about Deleting snapshots which causes some confusion. Deleting a snapshot means foregoing the ability to return to that point - we can't apply a deleted snapshot, that's obvious enough. The saved memory state (if there is one) is deleted but what about the data in the AVHD file ? If a Snapshot has children we can either delete the whole subtree, or we can delete just the parent snapshot. Internally Hyper-v works out when it can merge and/or delete AVHD files - a process which can take some time (you can tell if this operation is pending because the edit button for the hard disk in the machine's settings is grey'd out). 

Now for the obligatory bit of powershell, because of course this is scriptable.

   Function New-VmSnapshot  
{Param( $vm=$(Throw "You must specify a VM") )
if ($vm -is [string]) {$vm=(Get-VM $vm) }

$arguments=($vm,$Null,$null) $result=$VSMgtSvc.invokeMethod("CreateVirtualSystemSnapshot",$arguments) if ($result -eq 4096) { $arguments[2] }  else  {"Error, code:" + $result}
}

In an earlier post I described Get-VM and explained that I set up a variable

   $vsMgtSvc = Get-wmiObject -nameSpace root\virtualization -class Msvm_virtualSystemManagementService

All the work here is done by the CreateVirtualSystemSnapshot method, and we pass it the Machine and 2 nulls. Normally it will return 4096 - the code for "started processing in the background" and the second Null magically contains the job ID so the function returns that. So you can invoke the function as $JobId=(New-VmSnapshot  $Tenby) and make tracking the job afterwards that bit easier. There are two more methods which we can call, RemoveVirtualSystemSnapshot, and ApplyVirtualSystemSnapshot oddly the latter only requires the machine and the snapshot reference, even though the snapshot says which machine it came from but trying to apply a snapshot to a new, clean VM fails. Maybe it's something that's under consideration for a future version. I'll describe these two in my next post.

A little more on PowerShell

I've been showing PowerShell on the roadshow, and Steve warning me about it becoming the "Look-how-clever-I-am-with-PowerShell show". Actually, I quite like the idea of a "Look-how-clever-PowerShell-makes-you show". Working on some of bits and pieces of PowerShell for managing hyper I've found a couple of new corners which I thought I'd share.

I wanted to show the tree of snapshots taken of a Hyper-v Virtual Machine ... and let the user choose one of them.  I ended up with a semi-generic "Choose-Tree" function, and that sent me back to the choose functions I've written about before. I wanted to have something totally generic like this

   choose-list (Get-WmiObject win32_diskdrive) @("DeviceID", "Model")

ID DeviceID           Model
-- --------           -----
0 \\.\PHYSICALDRIVE0 Hitachi HTS721010G9SA00 ATA Device
1 \\.\PHYSICALDRIVE1 Generic USB Card Reader USB Device
2 \\.\PHYSICALDRIVE2 Multi Flash Reader USB Device

Which one ?:

The idea is simple enough, pass the function an array of data and other array of the field names I want displayed, put a counter alongside them and let the user enter the index into the array for the item they want.

This led me to using variables and parameters in places I haven't done before One was using a variable to hold a field name. Like this

   $foo="TotalPhysicalMemory"
   (Get-WmiObject win32_computersystem).$foo

Very useful if I need to pass a parameter to a function to tell it which property to use from the objects it was passed. Building a tree for example, which field is displayed, which gives a node's parent, and so on. Then I started looking at using an array of strings to hold the field names, like this

   $foo=@("TotalPhysicalMemory","Model")
Get-WmiObject win32_computersystem | format-table -property $foo

That works very nicely too. Because Powershell lets us mix types of item in an array we can put in hash tables which store custom fields. So a design formed... Pass data and Fields as parameters, add the counter custom-field that I was already using in my choose functions to the Fields array (put it an array and join it with the array of fields passed to the function), and use that in a format-table command. Since some of Choose functions had multiple selections and some single I had a "Multiple" parameter and that changes the prompt / selection at the end. So my generic choose-from a-list function ends up as half a dozen lines.

   function choose-List
   {Param ($Data , $fieldList , [Switch]$Multiple)
    $global:Counter=-1
    $fieldlist=@(@{Label="ID"; expression={ ($global:Counter++) }}) + $fieldList
    $data | format-table -autosize -property $fieldList | out-host
    if ($Multiple) { $Data[ [int[]](Read-Host "Which one(s) ?").Split(",")] }
    else           { $Data[        (Read-Host "Which one ?")           ] }
   }

Each "choose" function - choose VM, Choose network etc then becomes one line.

Technorati Tags: ,

SCVMM: If you go down to connect today, you're sure of a nice surprise

There were rumours that it would be announced at MMS, but I didn't want to comment on them until the announcement was made. System Center Virtual Machine Manager has gone beta.

On the (recently revamped) home page of http://connect.microsoft.com, if you click Connection Directory or See all Connections you'll find

System Center Virtual Machine Manager

Virtual Machine Manager 2008 (VMM) is a comprehensive virtual management solution optimized for Windows Server® 2008, Microsoft Virtual Server, and VMware infrastructures.

That's exciting news. If you're working on Virtualization and would like some assistance drop me a mail - ideally with the word "Airframe" in the title and I'll give you some information about a support programme which we're running.

 

More Posts Next page »
 
Page view tracker