<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.conchango.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>James Saull's Blog</title><link>http://blogs.conchango.com/jamessaull/default.aspx</link><description>The ethical slacker</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>SQL Server Enterprise Edition. Not all indexes can be re-built online.</title><link>http://blogs.conchango.com/jamessaull/archive/2008/08/08/sql-server-enterprise-edition-not-all-indexes-can-be-re-built-online.aspx</link><pubDate>Fri, 08 Aug 2008 16:25:25 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:12181</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/12181.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=12181</wfw:commentRss><description>&lt;p&gt;When designing your application schema you need to spend some time planning for operations. You may plan to rely on the Enterprise Edition of SQL Server to bring you online index rebuilding to ensure that index maintenance does not require downtime. The excerpt below from Microsoft SQL Server Books Online is important to remember because if you choose certain datatypes then online index rebuilds may not be available to you:&lt;/p&gt; &lt;li&gt;Clustered indexes must be created, rebuilt, or dropped offline when the underlying table contains large object (LOB) data types: &lt;b&gt;image&lt;/b&gt;,&lt;b&gt; ntext&lt;/b&gt;, &lt;b&gt;text&lt;/b&gt;, &lt;b&gt;varchar(max)&lt;/b&gt;, &lt;b&gt;nvarchar(max)&lt;/b&gt;, &lt;b&gt;varbinary(max)&lt;/b&gt;, and &lt;b&gt;xml&lt;/b&gt;.  &lt;li&gt;Nonunique nonclustered indexes can be created online when the table contains LOB data types but none of these columns are used in the index definition as either key or nonkey (included) columns. Nonclustered indexes defined with LOB data type columns must be created or rebuilt offline. &lt;li&gt;Indexes on local temp tables cannot be created, rebuilt, or dropped online. This restriction does not apply to indexes on global temp tables.&lt;/li&gt; &lt;p&gt;&lt;a title="http://technet.microsoft.com/en-us/library/ms190981.aspx" href="http://technet.microsoft.com/en-us/library/ms190981.aspx"&gt;http://technet.microsoft.com/en-us/library/ms190981.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Just a warning, in case you are planning for a very high availability solution.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=12181" width="1" height="1"&gt;</description><category domain="http://blogs.conchango.com/jamessaull/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Windows Home Server, the iPod and the XBox</title><link>http://blogs.conchango.com/jamessaull/archive/2008/08/05/windows-home-server-the-ipod-and-the-xbox.aspx</link><pubDate>Tue, 05 Aug 2008 08:56:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:12129</guid><dc:creator>James.Saull</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/12129.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=12129</wfw:commentRss><description>&lt;p&gt;With all my music safely stored on the Windows Home Server (and &lt;a href="http://www.amazon.com/gp/browse.html?node=16427261"&gt;Amazon S3&lt;/a&gt; courtesy of &lt;a href="http://www.jungledisk.com/"&gt;Jungle Disk&lt;/a&gt;) I installed the Home Server client software on the wife's laptop (so it would get backed up). I mapped a drive the Music share and then told iTunes to "Add a folder". I pointed it at the mapped drive and that was that. I was quite surprised just how long iTunes took to "add the folder". It appears to scan all the file names, metadata and probably a whole lot more - either way it is very intensive on the network and takes far longer than you'd expect. This makes it annoying that it is not very multithreaded. Of course adding music to this folder other than through iTunes means that, by the looks of it, we have to keep telling it to add this folder. It is not very good at automatically keeping up to date. Seriously - what is the fuss about iTunes? it is a ~70MB fat client app that seems to struggle with the basics. Importantly though, iTunes knows about our WHS music repository and can therefore create play lists and sync them to the iPod. Success with gripes!&lt;/p&gt; &lt;p&gt;I then fired up the XBox, navigated to the "Media" tab and chose to add a media source. It had already detected my Windows Home Server. That was it. I then clicked on the "Albums" list and it thought about it momentarily before displaying all the albums. The experience was the same when selecting "Artists". Either way - significantly faster than iTunes. What is quite nice is that whilst it is playing an album you can go back to the "Media" tab and navigate to the photos stored on the Windows Home Server and kick off a slide show of a folder and all its sub-folders. It was nice to have the XBox playing music whilst slide showing all the pictures of the kids.&lt;/p&gt; &lt;p&gt;I haven't tried to show video content on the XBox yet.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=12129" width="1" height="1"&gt;</description></item><item><title>When is a PowerShell script not really a script anymore? Why not just code it as a C# command line application?</title><link>http://blogs.conchango.com/jamessaull/archive/2008/08/04/when-is-a-powershell-script-not-really-a-script-anymore-why-not-just-code-it-as-a-c-command-line-application.aspx</link><pubDate>Mon, 04 Aug 2008 20:14:40 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:12126</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/12126.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=12126</wfw:commentRss><description>&lt;p&gt;After all, can't I just use notepad and csc.exe as long as I can remember "public static void main"...&lt;/p&gt; &lt;p&gt;First of all, why was it written as a script in the first place? What were the perceived advantages? After all, just because you can doesn't mean you should!&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Transparency: scripts can be opened in a text editor even in the production environment. Systems administrators can see what it is doing. They aren't the sort of people familiar with Reflector, and they probably use PowerShell for many of their tasks anyway.&lt;/li&gt; &lt;li&gt;Debug: a corollary of transparency. If a script starts to fail in production it can be easy to debug and modify a copy of that script right there in the production environment, and not necessarily by the original developer. I don't just mean by printing the output to screen - stepping through style debugging.&lt;/li&gt; &lt;li&gt;Modifiable: contentious this one. A system administrator can modify the script as environments change. This is very quick and easy to do without a full-bore compile/deploy cycle from a development team. Agreed, many of the things likely to change will be in a configuration file (you could argue that is all a script is, so why have yet another text file unless it is shared). However, if the script is being modified in the deployed environment then it is not part of the solution it was originally deployed with anymore - this could be remedied with a sleight of configuration management though. &lt;/li&gt; &lt;li&gt;Purpose: with all the CmdLets available in the base deployment or the &lt;a href="http://www.codeplex.com/PowerShellCX"&gt;Community Extensions&lt;/a&gt; or &lt;a href="http://powergui.org/kbcategory.jspa?categoryID=21"&gt;PowerPacks&lt;/a&gt; etc. you get some enormous re-use to do the sorts of tasks that it was intended for: managing files, working with the contents of files and objects flowing down a pipeline.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Scripts can be well written feats of engineering: aesthetic, efficient, well factored, readable, maintainable, instrumented, documented, following a common convention/style, deployable etc. I think the issue gets tough when the coding gets complex and starts using a great deal of .Net BCL to get the job done. Sometimes it makes sense to move this code into CmdLets or Plain Old C# Objects (POCO) which you can manage in a more rigorous development practice - critically: unit tested and strongly typed where it helps. These functions we have to feel more comfortable wrapping up (inside Unit Tests, Code Coverage, Static Analysis, FxCop, StyleCop, NDepends etc.) and gaining the purpose that is clearly better expressed within an object oriented .Net project at the expense of the transparency, modifiability and general "Operations" friendliness. I would definitely feel better with a 1000 lines of unit tested C# expressed as objects, interfaces and so forth. It's why the PowerShell folk gave us the continuum from the one-liner, through scripts to CmdLets and even custom hosts etc. The trick is to spot where you are on that continuum and refactor as you move along it; recognising the trade offs and benefits.&lt;/p&gt; &lt;p&gt;When I see a PowerShell script that is managing variables and composed of simple routines and CmdLets fulfilling a simple role I feel comfortable; but when I see hundreds of lines of PowerShell mostly made up of calls into the BCL it makes me feel as if it has lost its way and is perhaps better served being moved into CmdLets or Plain Old C# Objects developed in a traditional C#/Visual Studio environment. I don't want to see PowerShell used as an excuse to slap some script together, and move away from the rigour of our engineering practices.&lt;/p&gt; &lt;p&gt;What do you think defines a script and what defines a C# Command Line EXE / DLL / CmdLet? Is it complexity? Who will be maintaining it? The programming style? Simplicity vs Complexity? Is it the reuse of blending the CmdLets that brings speed and efficiency to a certain set of tasks?&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=12126" width="1" height="1"&gt;</description></item><item><title>PowerShell + VMWare</title><link>http://blogs.conchango.com/jamessaull/archive/2008/07/29/powershell-vmware.aspx</link><pubDate>Tue, 29 Jul 2008 13:18:34 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:12032</guid><dc:creator>James.Saull</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/12032.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=12032</wfw:commentRss><description>&lt;p&gt;Our development endeavours often include many tens of developers each with their own managed virtualised development environment. Typically, on top of these, there are multiple test and pre-production environments (each with clusters or load balanced clusters). We can therefore easily end up with 50+ Virtual Machines on a single project. The development/test cycle is very fluid creating atypical management demands on the environment. It is fair to say that these environments easily pass the threshold where scripting management routines becomes worthwhile. To help with this, VMWare have released a whole host of PowerShell CmdLets to wrap up the management web services. If it has got PowerShell in it, it gets my vote!&lt;/p&gt; &lt;p&gt;So here are the VMWare PowerShell libraries:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.vmware.com/sdk/vitk_win/index.html"&gt;http://www.vmware.com/sdk/vitk_win/index.html&lt;/a&gt;  &lt;p&gt;&lt;a href="http://www.ntpro.nl/blog/archives/561-VMware-Infrastructure-Update-Manager-PowerShell-Library.html"&gt;http://www.ntpro.nl/blog/archives/561-VMware-Infrastructure-Update-Manager-PowerShell-Library.html&lt;/a&gt;  &lt;p&gt;Here is a blog covering the VMWare Infrastructure Toolkit (VI as they call it - sounds like my favourite text editor):  &lt;p&gt;&lt;a title="http://blogs.vmware.com/vipowershell/" href="http://blogs.vmware.com/vipowershell/"&gt;http://blogs.vmware.com/vipowershell/&lt;/a&gt;  &lt;p&gt;And here is a book on it:  &lt;p&gt;&lt;a href="http://halr9000.com/article/541"&gt;http://halr9000.com/article/541&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In fact I just noticed &lt;a href="http://powergui.org/index.jspa"&gt;PowerGUI&lt;/a&gt; integration to VI Client:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.conchango.com/blogs/jamessaull/WindowsLiveWriter/PowerShellVMWare_C930/image_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="303" alt="image" src="http://blogs.conchango.com/blogs/jamessaull/WindowsLiveWriter/PowerShellVMWare_C930/image_thumb.png" width="394" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=12032" width="1" height="1"&gt;</description></item><item><title>Windows Home Server Power Pack 1 and WHS+USB 1.0 == Misery!</title><link>http://blogs.conchango.com/jamessaull/archive/2008/07/23/windows-home-server-power-pack-1-and-whs-usb-1-0-misery.aspx</link><pubDate>Wed, 23 Jul 2008 20:39:11 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11973</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11973.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11973</wfw:commentRss><description>&lt;p&gt;I pushed too much data on to the Windows Home Server (WHS) and I started to get health warnings indicating which files it could no longer duplicate. My data was stored OK, just at risk. Given that the WHS experience was going well I ordered up a Lacie 500GB external USB 2 drive. To tide me over, I plugged in a little 100GB host powered USB drive and added it to the pool. Slowly the data balanced out across the three drives with enough space for all content to be duplicated. I then continued to copy more data on to the server. Transfer rates were abysmal! 500k/s. Oh dear. All my content finally copied over and eventually my critical health warning went away as it finally migrated enough data off the smallest system drive.&lt;/p&gt; &lt;p&gt;The Lacie 500GB drive arrives and I plug it in. A couple of clicks later it is added to the storage pool. It starts to balance the content whilst I right click the little 100GB host powered drive and remove it from the storage pool. WHS can see that there is enough storage and drives to successfully duplicate content across the remaining drives and so it starts to migrate content off... how slow?! it can only have about 30GB on it. Max! Anyway, time for bed.&lt;/p&gt; &lt;p&gt;By the next morning all the content has migrated off the drive. I go to the WHS to remove the drive... Ah... I'd forgotten that this old machine still had USB 1.0 ports. In the darkness under the desk it would appear that I had rediscovered them when I had plugged in the 100GB drive! Copying files and balancing storage with the 500GB drive plugged into USB 2.0 is now going up to 8MB/s (given I have a 10/100 switch in the way it won't get much higher than that). When MS say they don't recommend USB 1.0 they weren't kidding. Copying large AVCHD files onto the WHS is nice and fast and I can happily watch the HiDef videos directly off the WHS.&lt;/p&gt; &lt;p&gt;Applied WHS Power Pack 1 last night. All straight forward. Go get it here: &lt;u&gt;&lt;a href="http://download.microsoft.com/download/8/b/d/8bd7fe82-34cc-4026-b8e5-e9e10902312c/WHS-KB944289-v1-x86-ENU.exe"&gt;http://download.microsoft.com/download/8/b/d/8bd7fe82-34cc-4026-b8e5-e9e10902312c/WHS-KB944289-v1-x86-ENU.exe&lt;/a&gt;&lt;/u&gt;&lt;/p&gt; &lt;p&gt;and read about it here: &lt;u&gt;&lt;a href="http://blogs.technet.com/homeserver/archive/2008/07/21/power-pack-1-come-and-get-it.aspx"&gt;http://blogs.technet.com/homeserver/archive/2008/07/21/power-pack-1-come-and-get-it.aspx&lt;/a&gt;&lt;/u&gt;&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11973" width="1" height="1"&gt;</description></item><item><title>Windows Home Server</title><link>http://blogs.conchango.com/jamessaull/archive/2008/07/15/windows-home-server.aspx</link><pubDate>Tue, 15 Jul 2008 12:03:24 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11847</guid><dc:creator>James.Saull</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11847.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11847</wfw:commentRss><description>&lt;p&gt;I successfully installed Windows Home Server on a 7 year old Athlon 1800 with 512MB of RAM and two ATA drives (100GB and 200GB). My first concerns were: would the BIOS support booting from the DVD drive and was it a USB 2 card in there? Thankfully yes on both counts. One day I will save up for one of these lovely machines from tranquil-pc: &lt;a title="http://www.tranquilpc-shop.co.uk/acatalog/HOME_SERVERS.html" href="http://www.tranquilpc-shop.co.uk/acatalog/HOME_SERVERS.html"&gt;http://www.tranquilpc-shop.co.uk/acatalog/HOME_SERVERS.html&lt;/a&gt;. Atom power devices with Terabytes of internal storage, expandability and very low power consumption - think half a light bulb, and even then they can be sent to sleep during the day when you are out of the house. But for the time being, I am extending the life of my home built tower...&lt;/p&gt; &lt;p&gt;It performed a large number of reboots and the aged machine took a long time to get through the install so when it got to applying updates I switched off the screen and went to bed. All very uneventful.&lt;/p&gt; &lt;p&gt;Originally I was using Robocopy scripts to mirror data between the two drives. I had to copy this data off on to a USB drive because installing Windows Home Server formats all drives. &lt;/p&gt; &lt;p&gt;Next steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Selectively bring back data and put it into a new folder structure.  &lt;li&gt;Install the WHS client on wife's laptop and hope that iTunes is happy to use the shares as libraries!  &lt;li&gt;Install &lt;a href="http://www.jungledisk.com/homeserver/index.aspx"&gt;Jungle Disk for Windows Home Server&lt;/a&gt; to backup my data into the cloud.  &lt;li&gt;See whether I can get Windows Media Center to happily consume content from Windows Home Server.  &lt;li&gt;See whether I can get XBOX 360 to consume content from Windows Home Server.  &lt;li&gt;Buy a sizeable external HDD so there is plenty of space to back up the laptops.  &lt;li&gt;Configure backups of my laptop and wife's laptop - AC powered, but hibernated/sleeped laptops should wake-up and backup in the middle of the night.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;A useful link for Windows Home Server addins: &lt;a title="http://www.wegotserved.co.uk/windows-home-server-add-ins/" href="http://www.wegotserved.co.uk/windows-home-server-add-ins/"&gt;http://www.wegotserved.co.uk/windows-home-server-add-ins/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11847" width="1" height="1"&gt;</description></item><item><title>At the time, did you know it was the last time?</title><link>http://blogs.conchango.com/jamessaull/archive/2008/06/16/at-the-time-did-you-know-it-was-the-last-time.aspx</link><pubDate>Mon, 16 Jun 2008 21:50:20 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11477</guid><dc:creator>James.Saull</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11477.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11477</wfw:commentRss><description>&lt;p&gt;As a parent you watch your kids go through phases, just you aren't always aware that you are entering a phase or leaving one. For example, when is the last time you actually change a nappy? When was the last time you used the buggy to cart them around? You probably don't realise it at the time. One day you do it not realising it, and then the next day you forget to take the buggy out, then you realise that you didn't really need it and then you don't bother... unwittingly that day was the last day.&lt;/p&gt; &lt;p&gt;When was the last moment I wrote a line of Korn Shell, PERL, Java or VB6? Once upon a time those languages dominated my daily life, and then one day, unknowingly, it was the last day. When will it be the last day that I actually turn a line of C#? Will it be because my colleagues can't take it anymore? Or will it be because, by chance, I find myself on an engagement that forces me to use some special functional programming language to solve a massively parallel computing task and then I never end up with the opportunity to use C# again? Who knows. I wonder what that line of C# will look like? Probably just a closing brace and I won't even know it.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11477" width="1" height="1"&gt;</description></item><item><title>NUDA</title><link>http://blogs.conchango.com/jamessaull/archive/2008/06/04/nuda.aspx</link><pubDate>Wed, 04 Jun 2008 22:43:54 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11327</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11327.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11327</wfw:commentRss><description>&lt;p&gt;With plenty of people anticipating the massively multiple core CPU era, &lt;a href="http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access"&gt;NUMA&lt;/a&gt; architectures in regular workstations, and all the wonderful developments in &lt;a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;parallel extensions&lt;/a&gt; to development languages and &lt;a href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;software transactional memory&lt;/a&gt; to take advantage of them; I see one big bottleneck that looks set to defeat most of this on regular desktop computing: disk IO. My laptop is dual core and is always disk bound. Is disk going to keep up? How long before I can reasonably (just like dual core is very reasonable in a laptop) have multiple large solid state disks in my laptop?&lt;/p&gt; &lt;p&gt;Will they develop NUDA? Non Uniform Disk Architecture? In other words a disk subsystem that I don't have to micro manage that dovetails into NUMA. Once memory is exhausted the OS has to go to pagefile, but that page file should be held on striped solid state disks, and when that is exhausted it should be on striped hard disks and eventually very large storage on non-striped large disks. Or perhaps more like a continuation of NUMA where it would not stripe the disks but instead devote solid state disk volumes to each memory bank so that it's page file is closest and not competed for. That might not work though: if a thread and memory got migrated to a different set of cores and memory it would have to migrate disk data too which would be very bad. Better to stick with shared storage and striping.&lt;/p&gt; &lt;p&gt;Ramble Ramble.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11327" width="1" height="1"&gt;</description></item><item><title>Invoke-RemoteCommand - PowerShell CmdLet to tide me over until PowerShell V2</title><link>http://blogs.conchango.com/jamessaull/archive/2008/06/04/invoke-remotecommand-powershell-cmdlet-to-tide-me-over-until-powershell-v2.aspx</link><pubDate>Wed, 04 Jun 2008 22:22:02 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11326</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11326.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11326</wfw:commentRss><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;To tide me over until &lt;a href="http://blogs.msdn.com/powershell/archive/2007/11/06/what-s-new-in-ctp-of-powershell-2-0.aspx"&gt;PowerShell V2&lt;/a&gt; ships and we can perform remote PowerShell out of the box, I have created a simple WMI based CmdLet that will asynchronously execute a command - remotely. You might find it useful too.&lt;/p&gt; &lt;p&gt;The main limitation is that it does not track the result of the remote execution. You should be able to call any .EXE such as "cmd.exe /c" or "powershell.exe -command".&lt;/p&gt; &lt;p&gt;Here is the C# snippet - I don't code much so use with caution!&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;using System;&lt;br&gt;using System.Collections;&lt;br&gt;using System.Collections.Generic;&lt;br&gt;using System.ComponentModel;&lt;br&gt;using System.Diagnostics;&lt;br&gt;using System.IO;&lt;br&gt;using System.Management;&lt;br&gt;using System.Management.Automation; &lt;br&gt;using Microsoft.PowerShell.Commands; &lt;/p&gt; &lt;p&gt;namespace JamesSaull.PowerShell&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// InvokeRemoteCommand is a PowerShell CmdLet using WMI to execute a command on a remote server.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;example&amp;gt;Invoke-RemoteCommand -TargetServerName WEB01 -RemoteCommand "cmd.exe /c mkdir c:\temp\testfolder"&amp;lt;/example&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Cmdlet("Invoke", "RemoteCommand")]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class InvokeRemoteCommand : DCPCommandLet&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Fields&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string remoteCommand;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string targetServerName;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string username = string.Empty;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string password = string.Empty;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Command Arguments / Public Properties&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Name of the server where the command should be executed.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position = 0, HelpMessage = "Name of the server where the command should be executed.", Mandatory = true)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ValidateNotNullOrEmpty]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string TargetServerName&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return targetServerName; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { targetServerName = value; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The command to be executed. e.g. cmd.exe /c mkdir c:\temp\testfolder&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position = 1, HelpMessage = "The command to be executed. e.g. cmd.exe /c mkdir c:\temp\testfolder", Mandatory = true)]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ValidateNotNullOrEmpty]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string RemoteCommand&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return remoteCommand; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { remoteCommand = value; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Username used to authenticate and authorise against Target Server. Not allowed for local connections.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position = 3, HelpMessage = "Username used to authenticate and authorise against Target Server. Not allowed for local connections.")]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ValidateNotNullOrEmpty]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Username&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return username; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { username = value; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Password used to authenticate and authorise against Target Server.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter(Position = 4, HelpMessage = "Password used to authenticate and authorise against Target Server.")]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ValidateNotNullOrEmpty]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Password&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return password; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { password = value; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Overriding CmdLet&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Currently this CmdLet does not allow usage in a pipeline so it only overrides EndProcessing and not ProcessRequest or BeginProcessing.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void EndProcessing()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.EndProcessing();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExecuteCommand();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Private Methods&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// This is where the actual work is done. It uses WMI to create Win32_Process on the Target server and asynchronously invokes the supplied command. There is no exception handling to ensure that exceptions bubble up to the shell as no remedial action can take place here.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void ExecuteCommand()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConnectionOptions connection = new ConnectionOptions();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Point of contention: should we allow empty passwords? Currently this is disallowed by the ValidateNotNullOrEmpty attribute.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!string.IsNullOrEmpty(username))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // By default, unless you specify connection.Authority, it will use NTLM not Kerberos&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.Username = username;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connection.Password = password;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\CIMV2", targetServerName), connection);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; scope.Connect();  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagementClass classInstance = new ManagementClass(scope, new ManagementPath("Win32_Process"), null);  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagementBaseObject inParams = classInstance.GetMethodParameters("Create");  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inParams["CommandLine"] = remoteCommand;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagementBaseObject outParams = classInstance.InvokeMethod("Create", inParams, null);  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11326" width="1" height="1"&gt;</description></item><item><title>Partition, Federate, Aggregate and Synchronise</title><link>http://blogs.conchango.com/jamessaull/archive/2008/06/04/partition-federate-aggregate-and-synchronise.aspx</link><pubDate>Wed, 04 Jun 2008 22:01:02 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11325</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11325.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11325</wfw:commentRss><description>&lt;p&gt;It is common practice to use a partitioning function to scale out a solution. For example, you may divide a database among four equal geographical regions and have four separate installations of the database each with the same database but only a quarter of the data. When these four databases outgrew the single physical infrastructure they could be split out on to&amp;nbsp; separate physical machines with a region on each. When throughput of each machine was in jeopardy you could change the partitioning scheme to be more granular - e.g. sub regions. With 40 sub regions you could house 4 sub regions per physical server and have 10 physical servers. And so on and so on. Clearly the application tier needs to be aware of the partitioning scheme and be able to resolve the request it is dealing with to the server that is able to process it. DNS is an example of this resolution by resolving the partition to the handling resource. E.g. &lt;a href="http://www.conchango.com"&gt;www.conchango.com&lt;/a&gt; resolves to an IP address which directs your resource request to the appropriate resources.&lt;/p&gt; &lt;p&gt;Remember the partitioning scheme should take in to account how the data is used and not just logical groupings. Ideally your architecture will include the ability to easily re-partition.You may be motivated by reducing the sheer data volumes - solved by creating many smaller databases devoted to a much more manageable data partition. You may be motivated more by sheer TPS (Transactions Per Second) with a perfectly reasonable data volume - solved perhaps by load balancing across identical servers. Ease of re-partitioning allows you to identify hot areas of data attracting activity and break that into many partitions so that you can give each server equal amounts of hot and cold partitions. These hot/cold areas may not be fixed for all time...&lt;/p&gt; &lt;p&gt;Anyway my point is not about comparing all the possible schemes! Get to the point!&lt;/p&gt; &lt;p&gt;Either way you slice it you introduce two key problems...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Aggregate&lt;/strong&gt;. You are likely to have queries that span partitions. Typically this would be a reporting requirement but sometimes it can be part of the OLTP solution. Spanning partitions might mean different tables, different databases, different servers, different continents... ETL/Data Warehousing techniques have solved this problem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Synchronising&lt;/strong&gt;. You might struggle to partition the data because queries need to span the entire dataset; therefore you may create four identical copies of the database and put a load balancer across the top (another form of partition and resolve). But what if the data is Read/Write? Then you must use a replication scheme for the updates so write-reads are consistent even when each part is served by different servers. This will give the problems of replication latency (i.e. you make an update on server 1, but your subsequent read happens against server 2 too soon and the update you made appears to have been lost because it has not arrived on server 2 yet). To avoid replication latency you may use a distributed transaction but this is not ideal as it will defeat scalability. Synchronising can also lead to merge conflicts... There are a variety of solutions but they are dependent on the nature of the problem.&lt;/p&gt; &lt;p&gt;Just thought I'd mention it, because although a lot of people partition and synchronise they forget about the aggregation issue.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11325" width="1" height="1"&gt;</description><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>People and Process over Technology</title><link>http://blogs.conchango.com/jamessaull/archive/2008/05/20/people-and-process-over-technology.aspx</link><pubDate>Tue, 20 May 2008 20:42:54 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:11176</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/11176.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=11176</wfw:commentRss><description>&lt;p&gt;As technology and engineering zealots there is nothing we can't build. Seriously. It is all a question of time, resource and budget. And there's the rub. There comes a point in almost any business process where we hit those points of diminishing returns with technology. All those edge cases where the coincidence of a series of unfortunate events and utterly rare occurrences all align to undermine the beautiful solution. Sometimes the solution is nigh on impossible, or the number of permutations and outcomes to cater for so magnificent. The huge amount of effort required to analyse, test, develop, document, deploy and maintain just can't possibly be justified.&lt;/p&gt; &lt;p&gt;That is not a defeat. That's just economics. I often see this happen especially during business continuity and disaster recovery conversations. The doomsday scenarios are imagined but the solution's Recovery Time Objective remains 1 micro second and the Recovery Point Objective is absolutely no loss of data. When people calm down and realise that such a solution would require the bending of known laws of the universe and cost a significant fortune people start to become more reasonable. How about the call centre people answering the phone use paper and pencil should the system be catastrophically lost. Would that be reasonable? Allow the system 1 hour to be restored into service and have people input the paper-persisted records offline. That might work out a whole lot better!&lt;/p&gt; &lt;p&gt;The other one I often see is a straight through processing system with enormously convoluted compensating transactions and business rules to try and cover everything that could possibly happen with an application. Would it be OK to put the order into an exception bucket where people make judgement calls? Ring the customer back and confirm some details? The emphasis on this solution would be to make it re-entrant and idempotent in all the right places but it could cope with a great deal of edge cases - especially the ones you don't know about or could not imagine.&lt;/p&gt; &lt;p&gt;The important point is to know when to transition your thinking from pure-play technology to a "people and process" solution. In fact you should almost certainly factor this into any solution because you can't anticipate everything. Once the system is in production and you notice certain patterns developing in the "people and process", you can design a solution and put it on the work backlog alongside the demonstrable business case.&lt;/p&gt; &lt;p&gt;People and Process. Factor it in. Then factor it out. Iteratively. If you see what I mean.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11176" width="1" height="1"&gt;</description><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Engineering+Practices/default.aspx">Engineering Practices</category></item><item><title>History is our greatest teacher</title><link>http://blogs.conchango.com/jamessaull/archive/2008/04/24/history-is-our-greatest-teacher.aspx</link><pubDate>Thu, 24 Apr 2008 13:05:49 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:10788</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/10788.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=10788</wfw:commentRss><description>&lt;p&gt;IT is old enough now to see itself repeating itself. It is also old enough for a lot of us not to remember a lot of it and benefit from the history lessons. "Plus ça change, plus c'est la même chose&lt;strong&gt;"&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;One particular example that made me smile was VMWare talking about &lt;a href="http://news.zdnet.co.uk/software/0,1000000121,39378363,00.htm"&gt;Lifecycle Manager&lt;/a&gt; the ability to use virtualisation to create resources and monitor them and allow you to assign cost metrics. This has sort of thing has been done before and you can see the mainframe guys just nodding sagely.&lt;/p&gt; &lt;p&gt;Sometimes it is the just the economics of the time that make certain techniques more or less relevant. We exploded into distributed computing and despite the total immaturity of the platform it thrived because of the economics. In a lot of enterprises they are trying to rebuild/reinvent the mainframe again; just not on rare proprietary hardware and software.&lt;/p&gt; &lt;p&gt;It'd be nice to have the time to explore more history of I.T. to find inspiration to tackle modern problems. For example, I am sure those mainframe folk will know all the complexities and difficulties of centralised resources (disk, network, CPU etc.) being cross charged to different departments by usage (peak and off peak etc.).&lt;/p&gt; &lt;p&gt;Many of Leonardo da Vinci's designs could not be realised during his time because the materials or manufacturing had not advanced enough. We can apply some new technologies to the old ambitions. Once upon a time centralised mainframes were great, but it was troubled by being such a vast expense the entire company would have to be on board to justify its cost. Today, the economics of hardware, software, datacentre space and management are different. Today we can build dedicated grids or ones that scavenge idle desktop CPU cycles. We can build very large servers for virtualisation or lots of little ones to allow for more autonomy of the business units. We can have DAS, NAS or SAN. We are even seeing more and more "cloud" technologies like Amazon's S3 or EC2 creeping into the equation.&lt;/p&gt; &lt;p&gt;So what problems did they have in the past that feel similar to the ones we have today? How did they solve them, and how would modern evolutions topple the equations toward a much more favourable result today?&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=10788" width="1" height="1"&gt;</description></item><item><title>Abstractions and Facades vs Fundamentals</title><link>http://blogs.conchango.com/jamessaull/archive/2008/04/21/abstractions-and-facades-vs-fundamentals.aspx</link><pubDate>Mon, 21 Apr 2008 20:54:48 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:10744</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/10744.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=10744</wfw:commentRss><description>&lt;p&gt;Abstractions are a beautiful thing, and it is said that any problem in technology can be solved with another level of abstraction or indirection. Tremendous. But like with most things, there is a flip side.&lt;/p&gt; &lt;p&gt;Once upon a time you would program by hardwiring hardware. This evolved to general purpose hardware and machine code. Higher level abstractions came along with assembler; then C with compilers and so on and so forth. Now we regularly use things like Visual Studio, the Dynamic Language Runtime and Iron Python. Other technologies take the same trajectory. One moment you are writing angle brackets onto a HTTP stream to do SOAP and then next you are adding a service reference to your C# project and you never see an angle bracket ever again because even the XML configuration file has a GUI editor!&lt;/p&gt; &lt;p&gt;All the abstractions are clearly a great thing but the flip side is when things go wrong. If you are relying on SQL Server, for example, and you are not seeing the performance you expect you might employ some basic knowledge of the abstraction by profiling and having SQL suggest indexes. What next? Peel away some of the abstraction. Maybe you need to know about query plans and statistics or files and filegroups and disk configurations. This is what specialists are for. Subject Matter Experts. People who invest in knowing the abstractions and a significant number of layers beneath. &lt;/p&gt; &lt;p&gt;However, there are fundamentals, and whatever the abstractions are we should know these fundamentals (even if some of those are abstractions in their own right!). Each domain will have different fundamentals. What would you choose as your fundamentals? TCPIP, DNS, SMB? XSD, XML, WSDL, SOAP, WSI? HTTP, FTP? Two phase commit? Distinguish between throughput and latency, processes and threads? The list actually gets pretty big. Some fundamentals are just engineering concepts: parallel versus serial or centralised versus distributed etc.&lt;/p&gt; &lt;p&gt;Why am I writing this post? With the explosion of technologies, frameworks and versions it would seem a lot of people are having to trade a knowledge of fundamentals for a vast but cursory knowledge of very high level abstractions and I feel it is hurting. Is it a sign of my age? Is it just that today's abstraction are tomorrow's fundamentals? After all, if I think my vague understanding IL is clever, it is still not machine code, fetch execute cycles and binary (I can't even remember what two's compliment is!) but you have to draw your own boundary at some point!&lt;/p&gt; &lt;p&gt;Fundamentals allow you to decompose your solution and see it for what it really is. It won't matter how many shiny bits it has, it is just the composition of fundamentals. For example, you'll be able to use reflector and see that the code is a single threaded foreach loop making cross machine calls. There is no magic in that - the solution is clear.&lt;/p&gt; &lt;p&gt;I am feeling it more and more lately that great teams are a combination of the generalist and the specialist. They both know their fundamentals and engineering concepts - this can never be lost, but one invests in knowing a very broad range of abstractions and one delves deep. But either way both should recognise what fundamentals are relevant to their domain and keep investing in them too.&lt;/p&gt; &lt;p&gt;I think one of the hardest abstractions I have ever worked with was VB and MTS. It was very productive to crank out COM components in VB. But when things started to go a bit wrong, you were so far from the next level of abstraction you were in a world of pain! Remind me: what is a Single\Multi Threaded Apartment? What is Activation? What is Thread Local Storage and Thread Affinity? I didn't know I just wanted to write my VB!&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=10744" width="1" height="1"&gt;</description><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Engineering+Practices/default.aspx">Engineering Practices</category></item><item><title>Nothing feels quite like going live</title><link>http://blogs.conchango.com/jamessaull/archive/2008/03/14/nothing-feels-quite-like-going-live.aspx</link><pubDate>Fri, 14 Mar 2008 10:01:04 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:10179</guid><dc:creator>James.Saull</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/10179.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=10179</wfw:commentRss><description>&lt;p&gt;Today the &lt;a href="http://news.bbc.co.uk/1/hi/uk/7294618.stm"&gt;Queen is to open Heathrow Terminal 5&lt;/a&gt;. It seems strange that Terminal 5 is finally opening. I worked for BAA for a large chunk of 2003 when everyone talked about the very distant go live in March 2008. My project was incrementally delivered during 2003, so my stuff went into service a long time ago; but finally 2008 is here!&lt;/p&gt; &lt;p&gt;Divert two rivers, extend the Piccadilly line, extend the Heathrow Express, 5 floors each the size of ten football pitches etc. I found it interesting how various construction exercises were rehearsed elsewhere because when you are spending £4.3bn you really don't need a delay with so many interdependencies - that is millions every day being impacted. Then there were all the other subtle constraints; like doing Europe's largest ever construction program inside the busiest international airport. For a start that means you have a radar ceiling - don't go putting up high cranes and confusing some critical systems! Find a different way.&lt;/p&gt; &lt;p&gt;Whilst on the project, with my excellent panoramic view of the airport, I watched the final Concorde flights come in. The evening flights to New York used to remind me that it was time to head off home!&lt;/p&gt; &lt;p&gt;So, today, I am having a personal little high seeing this achievement climax. I'll bet there are loads of people out there who contributed their myriad skills in many ways and celebrating too. Well done whoever you are and whatever you did.&lt;/p&gt; &lt;p&gt;What did I do? In retrospect, it was a form of Master Data Management for all the assets that go into making Terminal 5, from the HVAC to door furniture. It was all built using SQL Server, ASP .Net and Crystal Reports. Like T5 itself we applied some very rigorous quality to our solution from a very detailed NAnt build including FxCop, NUnit, NDoc, NCover, (NMock was too immature) and XCopy deploy/undeploy - I never even met the operations team that took our documentation and deployment assets - we just handed it over and it worked! We were an agile 2 pizza team with the primary stakeholder sitting at the same desks seeing the solution from the continuous builds. Wasn't much call for Sprint reviews!&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=10179" width="1" height="1"&gt;</description></item><item><title>Putting the Swiss Army Knife into SSIS</title><link>http://blogs.conchango.com/jamessaull/archive/2008/02/07/Putting-the-Swiss-Army-Knife-into-SSIS.aspx</link><pubDate>Thu, 07 Feb 2008 11:34:00 GMT</pubDate><guid isPermaLink="false">e847c0e7-38d9-45c0-b593-56747303e088:9690</guid><dc:creator>James.Saull</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.conchango.com/jamessaull/comments/9690.aspx</comments><wfw:commentRss>http://blogs.conchango.com/jamessaull/commentrss.aspx?PostID=9690</wfw:commentRss><description>&lt;p&gt;I heard recently that developers imprint on their first ever programming language. My &lt;u&gt;actual&lt;/u&gt; computing career started with the Korn shell on AIX UNIX quickly followed by PERL and Java a while later. Maybe this is why I am constantly enthralled to have finally got KSH, PERL and Java all in one: PowerShell. When you read &lt;a href="http://www.amazon.co.uk/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202382447&amp;amp;sr=8-2"&gt;The UNIX Programming Environment&lt;/a&gt; by Kernighan and Pike, everything beautifully falls into place - so much elegance. Anyway, its the way I feel about PowerShell too.&lt;/p&gt;&lt;p&gt;One particular e-commerce solution we are building using Microsoft Commerce Server 2007 has a sizeable ETL sitting behind it. It ingests nearly 100 million rows of data (which will grow considerably in future phases) to compose a catalogue with many millions of products and variants. PowerShell is used to manage the transport/protocols in ensuring the multiple data feeds are ready for the ETL process. Microsoft SQL Server Integration Services then manages the process of preparing this data for importing into Commerce Server 2007, for which we have custom SSIS tasks.&lt;/p&gt;&lt;p&gt;It is one thing to have PowerShell running on the outside of SSIS, or even &amp;quot;shelled out to&amp;quot;; but how about being able to actually embed and write PowerShell directly inside SSIS? You&amp;#39;d want it to share the variables, write to the SSIS logger and be aware of executing in the context of SSIS. My colleague &lt;a href="http://blogs.conchango.com/richardcase/default.aspx"&gt;Richard Case&lt;/a&gt; has done exactly this, please browse &lt;a href="http://blogs.conchango.com/richardcase/archive/2008/02/06/PowerShell-Script-Task-for-SSIS.aspx"&gt;here&lt;/a&gt; for his blog post and the custom &lt;a href="http://blogs.conchango.com/richardcase/archive/2008/02/06/PowerShell-Script-Task-for-SSIS.aspx"&gt;SSIS PowerShell task&lt;/a&gt;. Give him some feedback.&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=9690" width="1" height="1"&gt;</description><category domain="http://blogs.conchango.com/jamessaull/archive/tags/SSIS/default.aspx">SSIS</category><category domain="http://blogs.conchango.com/jamessaull/archive/tags/Commerce+Server/default.aspx">Commerce Server</category><category domain="http://blogs.conchango.com/jamessaull/archive/tags/PowerShell/default.aspx">PowerShell</category></item></channel></rss>