Challenge: Changing the stored credentials on 64 instances of IIS every 30 days

I'm no web farmer, and don't have responsibility for any web farms. But here's an interesting challeng I've been asked about, second hand.

Say you have 64 instances of IIS 6.0, running on 64 different machines.

You've set the credentials in IIS to use a particular domain user, say "MyDomain\MyIISAdmin"

But every 30 days the password will be changed, in line with corporate policy.

The "solution" according to one company was "Well you'll just have to change it manually because microsoft have no solution to this."

I don't buy that for a second! What would be your plan of attack? How would you crack this tough nut?

 

SecretGeek: live and dangerous!!

This Tuesday, 20th November, I'll be speaking the Queensland MSDN User group.

If you're in the Brisbane region, please come along!

Time: 17:30 for 18:00 - 19:30
Location: Microsoft Brisbane office, Level 9, Waterfront Place, 1 Eagle St, Brisbane

Here's the topic...

Coming out of the garage: Build your own tiny software company.

Brisbane's most handsome developer answers such age old riddles as:

  • Why is a MicroISV better than a license to print money?
  • What simple steps can I take to turn my latent ideas into a source of passive income?

A walkthrough of what's involved in establishing your personal software empire, without resorting to cyber crime.

Leon is an independent .net consultant, responsible for TimeSnapper.com and secretGeek.net.

(While they mention my incredible good looks they fail to mention that I'll be sporting a plush moustache, which I'll explain below)

Robert Crago will also be speaking, on Mobile PC Development, and in particular:

A Pen is NOT a Mouse

Robert will demonstrate how ease of use can dramatically improve only if the full power of the pen is harnessed. New ways of inputting and selecting will be demonstrated, along with several innovative pen-centric controls for both TabletPC and Windows Mobile devices. Windows Mobile 6.0 WispLite ink and handwriting recognition will be featured. End users will learn what to look for in a great pen-powered application.

I'm very much looking forward to it and hope to see every last one of you there, regardless of your geographical dispersal.

Due to my current independent status, you'll observe that this is the first time I've spoken to anybody other than my invisible pet cat in over three weeks. It should be amusing and very confronting. Bring tranquilisers.

Now about that moustache...

1 in 6 men suffer depression and most do not seek help.

Untreated depression is a leading risk factor for suicide. Bummer!

Last year in Australia, almost 20,000 men were diagnosed with prostate cancer, and almost 3000 died.

All through November I'm growin a mo, to bring ridicule upon myself and attention to this important cause.

To donate:
go to http://www.movember.com/au/donate, enter my registration number 83250 and your credit card details. Seven dollars ought to do it.

For Aussies:
You can instead send a cheque, payable to the "Movember Foundation", with my registration Number: 83250.

Send it to:

PO Box 292,
Prahran VIC 3181.
Donations over $2 are tax deductible.

Money raised by Mo-vember is donated to the Prostate Cancer Foundation of Australia and beyondblue - the national depression initiative, which will use the funds to create awareness, fund research and increase support networks for those men who suffer from prostate cancer and male depression.

Thanks for your support, and I hope to see ya on tuesday.

(False bravado regarding personal appearance is a trick i stole outright from that ugly misfit, justice gray. Cheers justice!)

 

New Sniglet: An Ungument

An ungument is the complete opposite of an argument. And when you compare the difference between an ungument and an argument, you may realise that only an ungument has any merit.

An ungument is where two people converse, each of them willing to have their opinion changed by the other person.

Contrast this with an argument, where two people, each fixed in their own belief, use rhetoric and device to try and convince an audience that their opponent is wrong in their belief.

Unguments are just as feisty as arguments -- as a person may have many objections that need to be overcome before they will gratefully relinquish their old opinion.

Once an argument/ungument is concluded you may hear this kind of thought expressed by the loser/winner:

"Ah, I lost the argument, yes, but I won the ungument, and know more now than I once did. My fellow ungumenter has a way to go and hopefully one day he can lose his own arguments and gain an ungument for himself."

It's better to win an ungument than an argument.

 

Revolutionary (versus Evolutionary) Code Generation

It's just about time to throw out all my code and rewrite it in {x}. Again.

Many of the changes to the .net framework in the last few years have allowed me to get away with just refactoring some of my code, or perhaps discarding the ugliest portions of it. Over time it seems to reduce down, like a knob of butter simmering on a hot plate.

But with the syntax changes in 3.0, it seems that almost everything I've written can be rearranged into a simpler style. And the biggest effects will be felt in the data access code: this means my use of code generation is set to change drastically.

First up -- a short run down of my general approach in regards to code generation.

The Evolutionary Approach

1. Write good code, manually.

Even if you'll eventually 'generate' the code, you want to first be an expert at writing it manually.

This is the wax-on, wax-off part of the game.

2. Move logic away from the user interface, into 'business' classes.

User interface and 'business logic' will each go through big changes -- indpendently of each other. Separating the two is such common advice that it's often treated gospel to many. Either way, it's usually worth it.

3. Refactor code into small reusable portions where possible.

You want to avoid repetition. So where the same code is repeated in slightly different ways, you extract this into a small helper class, or a utility function.

The code is now smaller, and neater -- but it's not gone altogether.

4. Convert what's left into templates

Take the remaining code, look at what overall patterns exist and convert the code into templates (CodeSmith for me, kiddo!) to accomodate accordingly.

A fair rule of thumb is that you should have carefully written it by hand three times before extracting it into a template.

Now, when the code generator does its work, the generated code will be the best possible code.

In theory.

So if things are going well...

The goal is to have:

  1. no repetition in manual code.
  2. no need to customize generated code.
  3. no logic in forms/code behinds.
  4. 'business logic' in 'business classes'
  5. Generated code where necessary. Less is more.

And this is evolutionary because?

Over time, as the framework improves... the libraries and templates evolve, just a little bit.

For example, when nullable types were introduced, it became easier to talk to the database (where fields are natually 'nullable').

Hence, the templates were improved in places, and the helper functions were reduced or improved in places.

Generics were a big change. Writing 'type-safe' collections went from being 'code-intensive' to trivial, e.g.(List<Person>). This made the 'list template' simpler, but didn't get rid of it altogether.

The introduction of partial classes meant that rather than customizing a generated class through inheritance, it could be done by adding a partial class. This was neat -- but hardly reduced the code that was generated.

I mentioned a revolution...

Now, I'll probably move to using Linq to SQL -- and a lot of the fundamental code generation will now be handled by the Linq To Sql generator. This is a revolutionary moment: and revolutions are not without their bloodshed.

I'm expecting trouble. I'm expecting confusion. I'm expecting mistakes.

Linq to SQL will be generating code using the goodness of Linq. Great, wonderful, shiny. But. Unlike my own CodeSmith templates, it'll be generating the sort of code that I don't yet have the experience to write manually. That's a worrying shift.

And what of the generated code it replaces? Will it replace everything that my current DAL's do? And where it falls short, can I customise the generator? Or do I need to generate extensions through a separate tool?

How good is the Linq to SQL ORM designer? I've seen already that I can't right click on a table and 'refresh'. This was a glaring oversight that annoyed me in the first five minutes... What else is in store? Is this thing ready to be part of the core process in big 'line of business' apps?

Actually... shiny new tools to play with... I guess the answer is... Bring It On!

(am i the only one who accidentally types 'ling' when i mean 'linq'? (no))

Also -- by the way, since no one I've spoken to seemed to realise this: you can get Linq to work on .net 2.0 sp1 machine, if you include the right dll's with your project.

 

Fix and continue in Smalltalk

'Fix and continue' in smalltalk is similar to edit and continue in .net. But listen to how well it's described in this screencast from James Robertson. I love the metaphor he uses:

"In most environments, when you're in the debugger, what you've got is a dead patient and you're a forensic pathologist. The best you can do is figure out what killed the poor guy and then hope that the next version doesn't die of the same thing.

"In smalltalk you're a surgeon. You've got the guy laid out on a table. He's under anaesthesia, but you can patch him up and send him on his way."
James Robertson

This is reminiscent of the old medical saying:

You can always make a correct diagnosis - but sometimes, you have to wait until the autopsy
(via Dr Karl)

For an interestng rant against edit and continue, read what frans bouma said on the topic in 2003. (If you're not yet familiar with Frans -- then you might like to read his 2003 rant against stored procedures too.)

On a different track, check out this amazing Douglas Adams DocuFantasy Video from 1990. He does a pretty nice job of pre-empting YouTube, the internet, and of covering the pre-history of the pre-internet as it stood at that time. A clippy like butler 'agent' even makes an appearance.

 

Who's the customer?

css, html,

The customer is always right, right... but who is the customer? Would you recognise them if you met them?

You're a company that makes its money from selling ads as part of its search results. Who's the customer?

  1. The companies who wish to advertise
  2. The people who perform the searches

You work for a company -- you sell software to pharmacies, and that software is used by its sales staff to help diagnose members of the public. Who's the customer?

  1. Your boss
  2. The pharmacies
  3. The staff at the pharmacies
  4. The people who are diagnosed

Anyone?

 

Designer vs Developer

Microsoft Australia have put out a site named "Designer vs Developer" where the challenge is to guess whether someone is a designer or a developer.

On the one hand this is the most ridiculous piece of thinly veiled marketing I've ever seen.

On the other hand -- it's really addictive, and far too entertaining!

The surprise for me was just how bad I am at telling a designer from a developer. I averaged below 50% -- worse than you'd expect from guessing alone.

Designer vs Developer -- take a guess.

 

The great big leaky sales funnel: a micro-ISV primer

1,000,000 people read about timesnapper...

50% don't click on the link to the website. (500,000 people remain)

50% visit the site, don't bother to download it. (250,000 people remain)

50% begin to install, but get distracted and forget. (125,000 people remain)

50% install TimeSnapper, but never run it again. (62,500 people remain)

50% run it, but can't work out how to use it. (31,250 people remain)

50% can use it, but don't find it very useful. (15,625 people remain)

50% want to buy it, but can't find the website again. (7,812 people remain)

50% find the website, but can't see where to purchase it. (3906 people remain)

50% find where to purchase it, but don't like the price. (1953 people remain)

50% don't mind the price, but don't trust paypal. (977 people remain)

50% trust pay pal, but enter the wrong credit card details. (488 people remain)

And that's how 1,000,000 people can become your first 500 precious customers!

Double the effectiveness of any one step in the chain, and you double the number of customers at the end of it all.

Obviously, once you've found a customer, treat 'em good. Listen to what they suggest in the forums, help them when they have problems.

(I'm currently preparing a talk for the Queensland MSDN user group -- November 20 -- about building a micro ISV. The above thought struck me, so i decided to share it here.)

Please come along! I'll blog more about it in time, of course.

 

Fluidic APIs are stupid... NOT!

People rave about Ruby with its fancy schmancy ability to construct internal DSL's (Domain Specific Languages). The oft-touted example is:

20.minutes.ago

In .net we now have 'extension methods', which let us do all sorts of lingustic gymnastics, including 20.minutes.ago (albeit with a few extra brackets in C#) (phil haack posted an example 6.months.ago)

But the examples are all a little contrived: 20.minutes.ago happens to form a logical chain where each word passes a value to the following word. But very few phrases are like that.

The real question is: can we turn all of our .net code into fluidic and beautiful prose?

Can we implement, for example, the Shakespeare Programming Language as an internal DSL, in C#?

Here goes...

No, actually, I'm not that brave. I'm going to try something far simpler -- converting a common line of real C# into a more grammatically correct form.

Here's the common line of C#:

if (!this.IsPostBack)

It would translate into plain english as:

"if this is not a post back"

So, subtituting spaces for dots, brackets and so on, a fluid interface might say:

if (this.is.not.a.postback))

...Can it be done?

If I went easy on myself I could change it to:

I could do it the cheaty way, and create a 'is_not_a_postback' method... but that's against the spirit of the thing.

The tricky bit is the word 'not' -- i figured it would create a clone of the object, then use reflection to visit each boolean property, and set the value to it's logical opposite. That's bad though, cause firstly "IsPostBack" is a readonly property -- so we can't reverse it (without accessing internal state... heh heh) and secondly, setting those properties might have unwanted side effects... so forget it.

At this point I could either email some of the world's greatest .net minds and get them to work on the problem around the clock while i head off to sleep. Or I could apply a model-driven architecture approach:

If the facts don't fit the model -- it's time to change the facts.

Yes, I think a more appropriate modern grammatical form of our code would be:

"if this iz a postback... NOT!!" Now, I think I can implement that as:

if (this.iz.a.postback.__NOT__)

(again -- with a few extra empty brackets in C#)

iz, and a can be implemented as what i'd term "empty non-modifier repeater extension methods" or "pass through" methods, both implemented like this:

    public static Object iz(this Object obj)
    {
        return obj;
    }

postback is a "synonymous extension method", a simple wrapper on IsPostBack:

    public static bool postback(this System.Web.UI.Page pg)
    {
        return pg.IsPostBack ;
    }

__NOT__ is "the logical inversion extension method", embellished with Textile-style __underlining__ and some nice SHOUTING.

    public static bool __NOT__(this bool that)
    {
        return !that;
    }
Now adjust your syntax highlighting so that braces and dots are the same colour as the background and we have:
if  this iz   a   postback   __NOT__   

With a few more empty non-modifiers we can expand our code into the more common English form:

   if  this iz  um  
      like   a   well   um   like  
      a   youknow   postback   um   thing
      i_mean  __NOT__   mkay   yeh  

And maybe now i see why Microsoft really added extension methods. It's bound to um, y'know like, encourage more kids to become programmers. NOT.

 

TimeSnapper Special - 9 More Days

We are extending the special price on TimeSnapper for nine more days.

If you've been dying to buy it -- or meaning to try it -- now is the time.

2 year anniversary special

TimeSnapper is "an automatic screenshot journal" -- it creates a time-lapse movie out of everything you do on your computer. This increases your productivity, helps you create timesheets, helps you recover lost text, helps you retrace your steps, helps with testing, makes you smarter, healthier and more attractive to other people.

Download it. Buy it. Someone even made a youtube movie about it. Now that is success.

A big thank you to the people who've downloaded it or purchased it in the past few weeks. We've put some of your feedback in the testimonials page. Cheers.

TimeSnapper -- special extended

TimeSnapper -- special extended

TimeSnapper -- special extended

TimeSnapper -- special extended

Thanks to wigflip for the obligatory advertainment generators.