<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://consultingblogs.emc.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">James Saull's Blog</title><subtitle type="html">The ethical slacker</subtitle><id>http://consultingblogs.emc.com/jamessaull/atom.aspx</id><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/default.aspx" /><link rel="self" type="application/atom+xml" href="http://consultingblogs.emc.com/jamessaull/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.20423.1">Community Server</generator><updated>2008-12-15T20:37:40Z</updated><entry><title>Cloud DevOps where is your voice?</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2010/11/29/cloud-devops-where-is-your-voice.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2010/11/29/cloud-devops-where-is-your-voice.aspx</id><published>2010-11-29T11:59:00Z</published><updated>2010-11-29T11:59:00Z</updated><content type="html">&lt;P&gt;To be honest I am completely overwhelmed by the onslaught of technologies emerging as serious contenders for building the cloud generation of architectures and applications. On the one hand I am truly grateful that there are super-smart engineers building a new generation of technologies but I am suffering &lt;A href="http://en.wikipedia.org/wiki/Future_Shock"&gt;Future Shock&lt;/A&gt;!&lt;/P&gt;  &lt;P&gt;It appears to me that most conversations are led by the application development community. I am referring to conversations about applications on Google’s AppEngine, Microsoft’s Azure, Amazon’s Web Services, Joyent, GoGrid, Heroku, EngineYard and so on.&lt;/P&gt;  &lt;P&gt;Naturally the next generation of applications being built are probably formed first in the minds of developers and architects. My bias probably means I gravitate towards those conversations too.&lt;/P&gt;  &lt;P&gt;What seems to be missing is the voice of Ops. Sure - there are people talking about Puppet, Chef, Capistrano, Mcollective and the like. But I mean the voice of the people talking about running a 24/7 Network Operations Centre and an ITIL service around apps deployed on App Engine (for example). It won’t be long before all the Python, MongoDB, Hadoop, GigaSpaces&lt;SUP&gt;*1&lt;/SUP&gt; systems are being demanded by developers to deploy on Eucalyptus/AppDrop&lt;SUP&gt;*1&lt;/SUP&gt; in regular on-premise data centres when they can’t do it in the public cloud. This won’t be an issue if the Ops knows how to deploy, patch, monitor, fix, recover, capacity plan and generally manage these sorts of topologies for business critical systems. I’d take a wild guess at this not being the case… Never met a MongoDBA?&lt;/P&gt;  &lt;P&gt;I think what I am saying is: if the forward planning Ops folks can wade in vocally and share their view of emerging technologies, then they can help influence the process of technology natural selection. They can help identify those that are fit for operations; and in turn not be asked to support the unsupportable! Wade in or forever hold you peace!&lt;/P&gt;  &lt;P&gt;Change is happening at an accelerated pace and compelling economics will cast aside all who stand in its way. Be part of the change.&lt;/P&gt;  &lt;P&gt;&lt;SUP&gt;*1&lt;/SUP&gt; Just a smattering of unrelated technologies that probably aren’t as well known in the on-premise application development&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17959" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author><category term="Engineering Practices" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Engineering+Practices/default.aspx" /><category term="Cloud Computing" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Cloud+Computing/default.aspx" /><category term="DevOps" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/DevOps/default.aspx" /></entry><entry><title>Managing future shock to find commercial advantage</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2010/04/13/managing-future-shock-to-find-commercial-advantage.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2010/04/13/managing-future-shock-to-find-commercial-advantage.aspx</id><published>2010-04-13T15:35:15Z</published><updated>2010-04-13T15:35:15Z</updated><content type="html">&lt;p&gt;If I interpret the &lt;a href="http://en.wikipedia.org/wiki/Main_Page"&gt;Wikipedia&lt;/a&gt; entry correctly, &lt;a href="http://en.wikipedia.org/wiki/Moores_law"&gt;Moore’s law&lt;/a&gt; started as an observation that perhaps transitioned into a self fulfilling prophecy: “…[this law] is now used in the semiconductor industry to guide long-term planning and to set targets for research and development.”. I wonder if there isn’t a more human explanation and lucky dose of coincidence for the longevity of this law – i.e. it was initially true for one reason but soon gave way to another that happened to be similar. &lt;/p&gt;  &lt;p&gt;If our civilisation, and all its economics, generates the demand for improving products and services then is it also naturally limited in its ability to successfully cope with a certain rate of change? And, therefore, will the demand for change remain constant? If throughput in innovation is properly matched to this demand then it would be no surprise that we don’t deviate much from Moore’s law (or variants of it). I suppose, in terms of &lt;a href="http://en.wikipedia.org/wiki/Theory_of_constraints"&gt;Theory of Constraints&lt;/a&gt;, I am describing our current state of civilisation as the constraint to adopting innovation rather than a constraint of our ability to innovate. After all, why invest and innovate faster than you can ship it?&lt;/p&gt;  &lt;p&gt;If, tomorrow, Intel brought to market a chip with 1000 cores what would we do with it? We couldn’t really exploit it. Throughput would have massively outmatched demand and Intel would have missed the opportunity to sell 16, 32, 64, 128 core systems. What if Canon had released a 28MP DSLR as one of the early generation digital cameras? Not only would USB 1.0, hard drives and narrow band internet connections have struggled but the mass market computers couldn’t cope with that resolution. Again innovation throughput would have exceeded demand.&lt;/p&gt;  &lt;p&gt;Another scenario of innovation throughput exceeding demand would be Canon releasing a new camera every month doubling resolution. Logistics and marketing are obvious impediments but also consumers couldn’t afford that rate of change. It’d be a Greek geek tragedy and a form of “&lt;a href="http://en.wikipedia.org/wiki/Future_shock"&gt;future shock&lt;/a&gt;”. Medical innovation also often has to throttle back whilst cultural/religious/legal alignment takes place.&lt;/p&gt;  &lt;p&gt;War is often cited as a time that demand for innovation rises, and we see innovation throughput rise too. There is usually less impedance as activities such as marketing get dropped and people’s willingness to adapt is heightened through necessity. This shows us that human ability to innovate is not the bottleneck – it is elsewhere in the system.&lt;/p&gt;  &lt;p&gt;Maybe &lt;a href="http://en.wikipedia.org/wiki/Moores_law"&gt;Moore’s law&lt;/a&gt; is much more an observation than a law. It just represents our current civilisation’s rate of adopting change during steady state (i.e. excluding total world war and imminent environmental doom) and not our ability to innovate. I certainly see this all the time within our consultancy. Our ability to technically innovate and deliver advanced solutions is never the bottleneck. It almost always sits further on in the value chain. The &lt;a href="http://en.wikipedia.org/wiki/Theory_of_constraints"&gt;Theory of Constraints&lt;/a&gt; not only tells us to match throughput to demand, but also to address those constraints. This is why as a technology consultancy we also focus on Business Change Management and User Centred Design to directly address the constraint of adopting the change. This ensures that our clients and their consumers can successfully adopt innovation for their advantage and not settle for the plodding pace set by averages. If we didn’t we’d be delivering &lt;a href="http://en.wikipedia.org/wiki/Future_shock"&gt;future shock&lt;/a&gt;! For example: delivering technology to bring social media experiences such as Facebook and Twitter within an enterprise is not hard for us, but there’d be no demand for this change if the business and the users couldn’t understand the vision and integrate it into their working practices.&lt;/p&gt;  &lt;p&gt;We’re ready when you are…&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=17098" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author></entry><entry><title>Trendy brands still make mistakes. How many will be tolerated?</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/11/09/trendy-brands-still-make-mistakes-how-many-will-be-tolerated.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/11/09/trendy-brands-still-make-mistakes-how-many-will-be-tolerated.aspx</id><published>2009-11-09T20:54:23Z</published><updated>2009-11-09T20:54:23Z</updated><content type="html">&lt;p&gt;Quite a day: Google &lt;a href="http://news.zdnet.co.uk/security/0,1000000189,39867168,00.htm"&gt;Chrome/Gears bug&lt;/a&gt; could have allowed hackers to execute malicious code on the user’s system and the &lt;a href="http://news.zdnet.co.uk/security/0,1000000189,39867163,00.htm"&gt;iPhone gets worms down under&lt;/a&gt;. Trendy brands can't escape the reality that building robust/secure software is not trivial. Will they be smart enough to avoid the pit Microsoft fell into (and climbed out of) or will they go through the same cycle?&lt;/p&gt;  &lt;p&gt;Have these firms managed to combine innovation with robust security engineering and will they support the software they release today for the next 5+ years and keep their customers safe? Let’s hope so because it would be a shame not to learn from the mistakes of others.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16531" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author></entry><entry><title>Agile infrastructure and how Cloud Computing can help Performance and Scalability</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/08/17/agile-infrastructure-and-how-cloud-computing-can-help-performance-and-scalability.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/08/17/agile-infrastructure-and-how-cloud-computing-can-help-performance-and-scalability.aspx</id><published>2009-08-17T10:49:00Z</published><updated>2009-08-17T10:49:00Z</updated><content type="html">&lt;P&gt;In an ever more agile world with test driven development and emergent design, has cloud computing come along at a perfect time to solve some of the age old problems of performance and scalability management? Let’s first look at a couple of the classic problems:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;At the start of the project, management are pulling together budgets as they build a business case. They need to know how much the physical infrastructure is going to cost? How many web front ends? How much storage? How much memory and CPU in the database server? How many environments and how similar do they need to be to the production environment? System Test, End to End Test, Integration Test, Operational Acceptance Test, User Acceptance Test, Pre-Production, Disaster Recovery, Development and Build etc. The thing is, you only have a high level architecture at this point and some high level requirements. Unless the solution is just like the solution you just built then how on earth can you accurately answer these questions? Perhaps you plan to use a new technology stack on a new range of infrastructure. Perhaps the expectation is that this is going to define the next generation of rich highly personalised web chocolaty goodness that has never been attempted before. You probably don’t have all the requirements yet and there is no point denying it. Agile tells us to expect change – it is inevitable. But what if an apparently subtle change will devastate performance/scale? Perhaps you won’t be able to cache as much as you’d hoped and therefore you won’t be able to offload stress on the database. Perhaps concurrency will force everything to be “serialisable” when everyone expected it to be “read uncommitted”. Either way, in many scenarios there can be a very low level of certainty in defining the production infrastructure let alone all the supporting test environments that support it. &lt;STRONG&gt;Problem number 1: being forced to accurately specify all environments a long time in advance of developing the solution which will then be fixed for all time and most likely leads to big overestimation or under-estimation.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Those responsible for ensuring the performance and scalability of the solution insist on having a replica of the production environment (that you aren’t yet able to specify) so that they can reliably test and “accept” the product. Given that the team responsible for prematurely guesstimating the infrastructure are gigantically unconfident they compensate by scoping the infrastructure as huge as they can imagine they could ever need. And someone else then doubles it. The replica performance / scale environment then becomes a totally untenable proposition (unless it can be justified to double up as the Disaster Recovery environment) and is forced to become a scaled down version and probably virtualised. Clever people then try to create a model that interpolates the difference between the big real environment and the small virtualised environment and behind their backs they cross their fingers and touch wood. &lt;STRONG&gt;Problem number 2: to genuinely performance/scale/load/stress test the solution will require an environment that is an exact replica of production; the prohibitive cost of which leads to dissimilar environments and undesirable consequences.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Enter cloud computing. Sprint after sprint the solution takes shape as does the infrastructure required to support it. Because the solution is targeting the cloud it is simple to have an exact replica for both production and performance testing. The performance testing environment only exists, and therefore paid, for the time that tests are being conducted. As tests provide feedback and the solution changes shape in response, so does the required infrastructure in a perfect feedback loop. The provisioning and payment of infrastructure is perfectly matched to the demand for it. When the solution goes live it is accurately known that the amount of infrastructure in use is exactly what is needed (as proven) with no risk to capital expenditure – and that is if we ignore the big cloud benefit of elasticity that continually matches production resources with actual demand as opposed to a best effort business model (yet another estimate). Also, if the current solution demands 50 web front ends it is easy to balance this expense with the labour costs that may be incurred to improve efficiency and reduce infrastructure to 20 WFEs. As efficiency is improved, infrastructure and operational expense are released. Again a direct correlation between effort to optimise and the affect on the bottom line is clear.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Ultimately the cloud can provide a clear cost model that solution architects can optimise towards. Continuously evolving solutions can have continuously evolving infrastructure. This can be fed back into the sprint planning and prioritised (i.e. “it is clear the solution is going to require considerable resources to meet demand and this needs to be addressed &lt;U&gt;now&lt;/U&gt; as a matter of priority”). It also means that you can easily build test environments to support performance and scalability (including “how would the solution handle 10x the demand”) and ultimately know that you only use what you need when you have met your performance and scale goals.&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16067" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author><category term="Architecture" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Architecture/default.aspx" /><category term="Engineering Practices" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Engineering+Practices/default.aspx" /><category term="Cloud Computing" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Cloud+Computing/default.aspx" /></entry><entry><title>Peculiar behaviour in PowerShell with dot sourcing and $LASTEXITCODE</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/08/07/peculiar-behaviour-in-powershell-with-dot-sourcing-and-lastexitcode.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/08/07/peculiar-behaviour-in-powershell-with-dot-sourcing-and-lastexitcode.aspx</id><published>2009-08-07T13:29:35Z</published><updated>2009-08-07T13:29:35Z</updated><content type="html">&lt;p&gt;Here is a script called SimpleExit.ps1&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Exit 99&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And here it is in use:&lt;/p&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;PS C:\temp&amp;gt; . .\SimpleExit.ps1 &lt;font color="#ff0000"&gt;(Dot sourcing it so that variables in the script are made “global” )&lt;/font&gt;       &lt;br /&gt;PS C:\temp&amp;gt; $LASTEXITCODE       &lt;br /&gt;99 &lt;font color="#ff0000"&gt;(You expected that – a variable set in the script was made “global” and therefore accessible by the calling shell/scope)&lt;/font&gt;&lt;/font&gt; &lt;/p&gt; PS C:\temp&amp;gt; $LASTEXITCODE = 0 &lt;font color="#ff0000"&gt;(Let’s reset it now)&lt;/font&gt;   &lt;br /&gt;PS C:\temp&amp;gt; $LASTEXITCODE   &lt;br /&gt;0   &lt;br /&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;PS C:\temp&amp;gt; .\SimpleExit.ps1 &lt;font color="#ff0000"&gt;(If we don’t dot source it, then $LASTEXITCODE in the script is NOT global and therefore not accessible by the calling shell/scope)&lt;/font&gt;       &lt;br /&gt;PS C:\temp&amp;gt; $LASTEXITCODE &lt;font color="#ff0000"&gt;(so let’s see what the value of $LASTEXITCODE is now…)&lt;/font&gt;       &lt;br /&gt;99 &lt;font color="#ff0000"&gt;(Yikes! So even though $LASTEXITCODE was set to 99 in a child scope it is visible in the parent – is this the magic of the Exit Keyword?)&lt;/font&gt;       &lt;br /&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Here is a script called MainTest.ps1&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Write-Host &amp;quot;Started MainTest and here is the call stack:&amp;quot;      &lt;br /&gt;Get-PSCallStack       &lt;br /&gt;$LASTEXITCODE = 100       &lt;br /&gt;Write-Host &amp;quot;LASTEXITCODE just set to 100&amp;quot;       &lt;br /&gt;Write-Host &amp;quot;Now going to execute InnerTest by dot sourcing it...&amp;quot;       &lt;br /&gt;. .\InnerTest.ps1       &lt;br /&gt;Write-Host &amp;quot;Finished executing InnerTest and the LASTEXITCODE is: $LASTEXITCODE and it should be 10&amp;quot;       &lt;br /&gt;Exit 1&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;and a script called InnerTest.ps1:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Write-Host &amp;quot;Started InnerTest and here is the call stack:&amp;quot;      &lt;br /&gt;Get-PSCallStack       &lt;br /&gt;Write-Host &amp;quot;LASTEXITCODE is $LASTEXITCODE and it should be 100&amp;quot;       &lt;br /&gt;Write-Host &amp;quot;Setting LASTEXITCODE to 10&amp;quot;       &lt;br /&gt;Exit 10&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now observe how dot sourcing affects the behaviour of calling these scripts:&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;PS C:\temp&amp;gt; &lt;strong&gt;C:\temp\MainTest.ps1&lt;/strong&gt;       &lt;br /&gt;&lt;font color="#ff0000"&gt;Started MainTest and here is the call stack:&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;MainTest.ps1      &lt;br /&gt;prompt       &lt;br /&gt;&lt;font color="#ff0000"&gt;LASTEXITCODE just set to 100        &lt;br /&gt;Now going to execute InnerTest by dot sourcing it...         &lt;br /&gt;Started InnerTest and here is the call stack:&lt;/font&gt;       &lt;br /&gt;.       &lt;br /&gt;MainTest.ps1       &lt;br /&gt;prompt       &lt;br /&gt;&lt;font color="#ff0000"&gt;LASTEXITCODE is 100 and it should be 100        &lt;br /&gt;Setting LASTEXITCODE to 10         &lt;br /&gt;Finished executing InnerTest and the LASTEXITCODE is: &lt;strong&gt;100 and it should be 10&lt;/strong&gt;&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;PS C:\temp&amp;gt;&lt;strong&gt; . C:\temp\MainTest.ps1&lt;/strong&gt;       &lt;br /&gt;&lt;font color="#ff0000"&gt;Started MainTest and here is the call stack:&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Lucida Console"&gt;.      &lt;br /&gt;prompt       &lt;br /&gt;&lt;font color="#ff0000"&gt;LASTEXITCODE just set to 100        &lt;br /&gt;Now going to execute InnerTest by dot sourcing it...         &lt;br /&gt;Started InnerTest and here is the call stack:         &lt;br /&gt;&lt;/font&gt;.       &lt;br /&gt;.       &lt;br /&gt;prompt       &lt;br /&gt;&lt;font color="#ff0000"&gt;LASTEXITCODE is 100 and it should be 100        &lt;br /&gt;Setting LASTEXITCODE to 10         &lt;br /&gt;Finished executing InnerTest and the LASTEXITCODE is: &lt;strong&gt;10 and it should be 10&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;/hr&gt;  &lt;p&gt;The crux here is that when you DON’T dot source MainTest.ps1 the variable $LASTEXITCODE flows down into the child script (InnerTest.ps1) which can see the value is 100, but when it calls “Exit 10” that does not modify the value of $LASTEXITCODE in the parent script MainTest.ps1. However, when we call MainTest.ps1 by dot sourcing it then the value is modified by the child script because it is global. &lt;strong&gt;But&lt;/strong&gt; if you go back to the simple example at the top you will notice that it doesn’t matter whether I dot source or not, Exit 99 modified the value $LASTEXITCODE of the root shell!&lt;/p&gt;  &lt;p&gt;Dot sourcing is like saying “make everything in the executing script a global variable” and this would explain why if I &lt;strong&gt;don’t&lt;/strong&gt; dot source MainTest.ps1 then it has its own locally scoped version of $LASTEXITCODE and why the value stays at 100. This makes it super annoying too! If I use “Exit 10” in a child script then it won’t be “bubbled up” properly because the calling script itself was not dot sourced! And it is apparently inconsistent with my first example which indicates that if the regular PowerShell shell calls a script that uses “Exit 10” it will bubble up! AGH!&lt;/p&gt;  &lt;p&gt;This is made all the more strange by the fact that when you run the PowerShell ISE it is as if the ISE was itself dot sourced. By that I mean when you step through a script in ISE you WILL get different results to just running the script WITHOUT dot sourcing it on the command line.&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=16016" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author></entry><entry><title>Will Amazon AWS be able to continue to compete?</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/07/15/will-amazon-aws-be-able-to-continue-to-compete.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/07/15/will-amazon-aws-be-able-to-continue-to-compete.aspx</id><published>2009-07-15T10:02:01Z</published><updated>2009-07-15T10:02:01Z</updated><content type="html">&lt;p&gt;Early indications of &lt;a href="http://www.microsoft.com/azure/pricing.mspx"&gt;Microsoft’s Azure pricing&lt;/a&gt; are out. As &lt;a href="http://blogs.conchango.com/simonmunro/archive/2009/07/14/azure-announces-unimaginative-pricing-model.aspx"&gt;Simon Munro&lt;/a&gt; pointed out they seem an awful lot like &lt;a href="http://aws.amazon.com/"&gt;Amazon’s AWS&lt;/a&gt; pricing and to some degree &lt;a href="http://googleappengine.blogspot.com/2009/02/new-grow-your-app-beyond-free-quotas.html"&gt;Google’s pricing&lt;/a&gt;. Perhaps people are already building Excel spreadsheets and AJAX apps to help model your solution like on &lt;a href="http://calculator.s3.amazonaws.com/calc5.html"&gt;Amazon’s Simple Monthly Calculator&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Microsoft have to move into this space to defend many of their franchises that would otherwise be eroded or sunk by the likes of Google and Amazon AWS. With MSFT on the scene running the most advanced&lt;sup&gt;(1)&lt;/sup&gt; mega data centres, owning the entire technology stack as well as having experience of operating several of the biggest web properties on the planet&lt;sup&gt;(2)&lt;/sup&gt;, will Amazon AWS be able to compete with that as well as Google? They will also have to compete with the likes of GoGrid and any other Managed Service company that wish to restructure around a Cloud business model. After all, their core business is the world famous ecommerce site and not Cloud Computing. What started as selling off excess capacity has evolved a great deal, matured and established a growing ecosystem with many big names putting their business on it. But is that enough to compete with pure technology giants who have set out to build this from the ground up to specifically address this need? Is there enough desire and a good enough business case within Amazon to do this? Will AWS need to become a fully separate business with Amazon as one of its biggest clients? However they justify it I hope they do because we need the choice and innovation they all offer.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;(1) I expect – I don’t know.&lt;/em&gt;    &lt;br /&gt;&lt;em&gt;(2) 2B Bings(!!) per month, 10B MSN page views per month, 30B Live ID authentications per month, 240B Messenger messages per month. These numbers have probably grown somewhat given Bing is boasting a 8% boost last month.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15856" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author><category term="Cloud Computing" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Cloud+Computing/default.aspx" /></entry><entry><title>Megastructure Datacentres</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/07/01/megastructure-datacentres.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/07/01/megastructure-datacentres.aspx</id><published>2009-07-01T20:31:10Z</published><updated>2009-07-01T20:31:10Z</updated><content type="html">&lt;p&gt;I &lt;a href="http://blogs.conchango.com/jamessaull/archive/2008/09/01/megastructure-data-centres.aspx"&gt;suggested last year&lt;/a&gt; that National Geographic would probably not include Cloud Datacentres in their &lt;a href="http://channel.nationalgeographic.com/series/man-made/all/Overview"&gt;megastructures&lt;/a&gt; series. I am in Dublin just as MSFT launch their “&lt;a href="http://news.zdnet.co.uk/hardware/0,1000000091,39669283,00.htm"&gt;mega datacentre&lt;/a&gt;”. Perhaps they should!&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15654" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author></entry><entry><title>How cloud operating systems aren’t quite there yet</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/07/01/how-cloud-operating-systems-aren-t-quite-there-yet.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/07/01/how-cloud-operating-systems-aren-t-quite-there-yet.aspx</id><published>2009-07-01T19:25:00Z</published><updated>2009-07-01T19:25:00Z</updated><content type="html">&lt;P&gt;Shrink yourself to the size of an ant and think of a classic server as a mini data centre. Banks upon banks of memory, multiple disks, many CPU cores and even network interfaces. The OS manages all of the many processes and threads, sharing the resources amongst them and when they demand more resource it makes it available to them – on demand and apparently instantly. Importantly all the resources in my mini data centre genuinely appear as one enormous pool available to all my applications at once. My application runs in a process and doesn’t care whether it consumes one core or 8. So what is a cloud OS?&lt;/P&gt;
&lt;P&gt;Cloud OSes do appear to be quite different because somehow I need to play a part traditionally played by the OS. When my application demands more resources I get involved. Typically I need to allocate more virtual machines or storage and quite likely I need to tell my application to extend itself into this new resource (i.e. install my application components and bring it into the pool/farm/cluster/you-name-it). Then when that demand passes I need to consider releasing those resources.&lt;/P&gt;
&lt;P&gt;Consider for a moment too the utility model, or to use a common analogy: “cloud computing is like the power grid – on demand, just in time, scale up and down”. When I need to consume more power, the statistically multiplexed grid allows me to draw as much as I want. There are even special burst providers like pumped storage schemes to handle the gigantic surge of kettles going on after a football game. If I need a milliamp for a second or 10 amps for an hour it makes no odds to me(!).&lt;/P&gt;
&lt;P&gt;Again the cloud seems to break this analogy. My application will consume up to the limit of pre-allocated resources and stop. The data centre might have a potential for a billion petaflops but the cloud OS can’t just grant them to my app. It is a bit like knowing that I am about to plug in my electric car and ringing the grid to provision me more current.&lt;/P&gt;
&lt;P&gt;Once upon a time the server OS used to be quite crude but they evolved and we take their sophistication for granted now. Most people struggle to even describe what an OS does. At the moment I need to resort to special software like &lt;A href="http://www.appistry.com/"&gt;Appistry&lt;/A&gt; to help me virtualise my application so that when I &lt;A href="http://aws.amazon.com/autoscaling/"&gt;auto scale&lt;/A&gt; up/down my Amazon machine images the application can do so too. How long before these capabilities are part of the cloud OS allowing applications to genuinely scale up and down very discretely? Will all the CPUs in the cloud data centre eventually present themselves as a single virtual resource with the cloud OS presenting abstractions, much like a regular process, as execution containers or in the cloud OS will the virtual machine always get in the way?&lt;/P&gt;
&lt;P&gt;It feels as if the virtual machine is a convenient way of *currently* spanning large amounts of hardware, but is it a stop gap? Will a genuine cloud OS come along that behaves like a regular server OS atop a giant data centre? It will be happy to present 24TB of apparently contiguous RAM and 1000 cores to a single “process”. It will be like NUMA and move application data across the server farm to the CPU that has been scheduled to work on it. Do we need it? Are we content for the next few decades to worry about how to span virtual machines and make them collaborate and auto-scale? Is the VM the new Process?&lt;/P&gt;
&lt;P&gt;P.S. I appreciate that in many clouds, storage capacity seems to have been the first to become a truly virtualised and discrete resource, although storage performance hasn’t (i.e. most solutions are too blunt to configure for different performance characteristics etc.)&lt;/P&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15651" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author><category term="Architecture" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Architecture/default.aspx" /><category term="Virtualisation" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Virtualisation/default.aspx" /><category term="Cloud Computing" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/Cloud+Computing/default.aspx" /></entry><entry><title>Dilbert’s Scott Adams is on the trail of Device 0</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2009/05/19/dilbert-s-scott-adams-is-on-the-trail-of-device-0.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2009/05/19/dilbert-s-scott-adams-is-on-the-trail-of-device-0.aspx</id><published>2009-05-19T18:30:04Z</published><updated>2009-05-19T18:30:04Z</updated><content type="html">&lt;p&gt;I read this post on Scott Adams’ blog today: &lt;a href="http://dilbert.com/blog/entry/your_phone/"&gt;http://dilbert.com/blog/entry/your_phone/&lt;/a&gt; It echoed my sentiments about the evolution of the mobile phone that I posted last year here: &lt;a title="http://blogs.conchango.com/jamessaull/archive/2008/09/22/windows-mobile-and-cloud-computing-will-it-erode-laptop-and-books.aspx" href="http://blogs.conchango.com/jamessaull/archive/2008/09/22/windows-mobile-and-cloud-computing-will-it-erode-laptop-and-books.aspx"&gt;http://blogs.conchango.com/jamessaull/archive/2008/09/22/windows-mobile-and-cloud-computing-will-it-erode-laptop-and-books.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Perhaps, with his considerable readership, he’ll provoke Steve Jobs into action. However, Microsoft have a much broader technology portfolio to actually materialise this. Like Veruca Salt I want this right now!&lt;/p&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=15229" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author></entry><entry><title>Making sure each web server in the farm is serving the same content.</title><link rel="alternate" type="text/html" href="http://consultingblogs.emc.com/jamessaull/archive/2008/12/15/making-sure-each-web-server-in-the-farm-is-serving-the-same-content.aspx" /><id>http://consultingblogs.emc.com/jamessaull/archive/2008/12/15/making-sure-each-web-server-in-the-farm-is-serving-the-same-content.aspx</id><published>2008-12-15T20:37:40Z</published><updated>2008-12-15T20:37:40Z</updated><content type="html">&lt;p&gt;When you have a web farm, monitoring can become a little bit more tricky. When you deploy a monitor&amp;#160; it is only monitoring the behaviour of the server chosen by the load balancer to respond. You need to create a monitor that is engaging each server directly, bypassing the load-balancer. Obvious, yes. Hard, no.&lt;/p&gt;  &lt;p&gt;When you have a web farm to serve your web site you want to make sure that they are all serving the same content. Maybe post-deployment, or just on a regular interval you want to check that one server hasn’t failed to pick up a configuration change or been accidentally interfered with. Or perhaps, when another monitor detects a failure you want to see if the wrong content is displaying across all web servers or just one.&lt;/p&gt;  &lt;p&gt;One thing you can do is to create a web page that includes an iFrame of each web server (bypassing the load balancer obviously). This is great for a quick eye-balling and may give the answer you need straight away. Sometimes the difference in a web page is not visual, or too subtle to spot in a hurry…&lt;/p&gt;  &lt;p&gt;I feed my habit by coding on the train home and I knocked this PowerShell script together to line by line compare the output of a page across a farm. It is a start and has proved handy a couple of times to spot a problem. It can be vastly improved of course. For example: by repeating the script and passing different HTTP headers (emulating a different browser type) it can see whether Web Server A is serving different content to IE8 to Web Server D. That’d be hard to spot. Anyway, here it is:&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green;"&gt;&lt;/span&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:purple;"&gt;$inputDocuments &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;http://192.168.0.10/default.aspx&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;http://192.168.0.11/default.aspx&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;http://192.168.0.12/default.aspx&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;http://192.168.0.20/default.aspx&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;http://192.168.0.21/default.aspx&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;# Use this line if you would prefer the script actually ignored known patterns that different in each file     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:purple;"&gt;$patternList &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;^\s*&amp;lt;input\s+type=&amp;quot;&amp;quot;hiden&amp;quot;&amp;quot;\s+value=&amp;quot;&amp;quot;[^&amp;quot;&amp;quot;]+&amp;quot;&amp;quot;\s+/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;,&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;^[\s]*$&amp;quot;     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;MatchesKnownPattern &lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputLine&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;ForEach &lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$pattern&lt;/span&gt;&lt;span style="color:blue;"&gt;in&lt;/span&gt;&lt;span style="color:purple;"&gt;$patternList&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:purple;"&gt;$pat&lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:teal;"&gt;regex&lt;/span&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:purple;"&gt;$pattern     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$pat&lt;/span&gt;&lt;span style="color:black;"&gt;.match(&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputLine&lt;/span&gt;&lt;span style="color:black;"&gt;).Success)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;return $TRUE     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;return $FALSE     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;# For each document create a hash table of line number and the actual line. Exclude all lines that match a pattern known to be different in each document.     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;@()     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;ForEach &lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocument &lt;/span&gt;&lt;span style="color:blue;"&gt;in&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;/span&gt;&lt;span style="color:teal;"&gt;regex&lt;/span&gt;&lt;span style="color:black;"&gt;]::&lt;/span&gt;&lt;span style="color:#8b4513;"&gt;Split&lt;/span&gt;&lt;span style="color:black;"&gt;((&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;New-Object&lt;/span&gt;&lt;span style="color:maroon;"&gt;net.webclient&lt;/span&gt;&lt;span style="color:black;"&gt;).DownloadString(&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocument&lt;/span&gt;&lt;span style="color:black;"&gt;),&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;) |&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;ForEach-Object -begin&lt;/span&gt;&lt;span style="color:black;"&gt;{&lt;/span&gt;&lt;span style="color:purple;"&gt;$count&lt;/span&gt;&lt;span style="color:black;"&gt;=0;&lt;/span&gt;&lt;span style="color:purple;"&gt;$webLines&lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;@{}}&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;-Process&lt;/span&gt;&lt;span style="color:black;"&gt;{&lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;MatchesKnownPattern&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:navy;"&gt;$_&lt;/span&gt;&lt;span style="color:black;"&gt;)){&lt;/span&gt;&lt;span style="color:purple;"&gt;$webLines&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$count&lt;/span&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;KNOWN DIFFERENCE&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;;&lt;/span&gt;&lt;span style="color:purple;"&gt;$count&lt;/span&gt;&lt;span style="color:red;"&gt;++&lt;/span&gt;&lt;span style="color:black;"&gt;;}&lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;span style="color:black;"&gt;{&lt;/span&gt;&lt;span style="color:purple;"&gt;$webLines&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$count&lt;/span&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:navy;"&gt;$_&lt;/span&gt;&lt;span style="color:black;"&gt;;&lt;/span&gt;&lt;span style="color:purple;"&gt;$count&lt;/span&gt;&lt;span style="color:red;"&gt;++&lt;/span&gt;&lt;span style="color:black;"&gt;;}}&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;-End&lt;/span&gt;&lt;span style="color:black;"&gt;{&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments &lt;/span&gt;&lt;span style="color:red;"&gt;+=&lt;/span&gt;&lt;span style="color:purple;"&gt;$webLines&lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;# Look at each document and see if after all known different patterns are excluded if they have the same line count:     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:purple;"&gt;$lineCounts &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;@{}     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;ForEach &lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocument &lt;/span&gt;&lt;span style="color:blue;"&gt;in&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:purple;"&gt;$lineCounts&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocument&lt;/span&gt;&lt;span style="color:black;"&gt;.psbase.keys.count]&lt;/span&gt;&lt;span style="color:red;"&gt;++     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$lineCounts&lt;/span&gt;&lt;span style="color:black;"&gt;.Count&lt;/span&gt;&lt;span style="color:red;"&gt;-gt &lt;/span&gt;&lt;span style="color:black;"&gt;1)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;Write-Host&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;Line counts are different&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:purple;"&gt;$documentCount &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;0;     &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;ForEach &lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocument &lt;/span&gt;&lt;span style="color:blue;"&gt;in&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;Write-Host&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;Document [&amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocument &lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;] has a count of: &amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$documentCount&lt;/span&gt;&lt;span style="color:black;"&gt;].Count     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:purple;"&gt;$documentCount&lt;/span&gt;&lt;span style="color:red;"&gt;++     &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;}      &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:green;"&gt;# Having agreed that they all have the same line count then go through each line     &lt;br /&gt;# and then compare:      &lt;br /&gt;# file 1 line 1 with file 2 line 1      &lt;br /&gt;# file 2 line 1 with file 3 line 1      &lt;br /&gt;# file 3 line 1 with file 4 line 1      &lt;br /&gt;# file 4 line 1 with file 5 line 1      &lt;br /&gt;# file 1 line 2 with file 2 line 2      &lt;br /&gt;# ....      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:purple;"&gt;$agreedLineCount &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[0].Count     &lt;br /&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;0;&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:red;"&gt;-lt &lt;/span&gt;&lt;span style="color:purple;"&gt;$agreedLineCount&lt;/span&gt;&lt;span style="color:black;"&gt;;&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:red;"&gt;++&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex &lt;/span&gt;&lt;span style="color:red;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;0;&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex &lt;/span&gt;&lt;span style="color:red;"&gt;-lt &lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;.Length&lt;/span&gt;&lt;span style="color:red;"&gt;-&lt;/span&gt;&lt;span style="color:black;"&gt;1;&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex&lt;/span&gt;&lt;span style="color:red;"&gt;++&lt;/span&gt;&lt;span style="color:black;"&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex&lt;/span&gt;&lt;span style="color:black;"&gt;][&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:red;"&gt;-cne &lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex &lt;/span&gt;&lt;span style="color:red;"&gt;+&lt;/span&gt;&lt;span style="color:black;"&gt;1][&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;])     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;Write-Host&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;Compared Document [&amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex&lt;/span&gt;&lt;span style="color:black;"&gt;]&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;] Line Number [&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;+1)&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;]:&amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex&lt;/span&gt;&lt;span style="color:black;"&gt;][&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;Write-Host&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;To Document&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$inputDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex &lt;/span&gt;&lt;span style="color:red;"&gt;+&lt;/span&gt;&lt;span style="color:black;"&gt;1]&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;] Line Number [&amp;quot;&lt;/span&gt;&lt;span style="color:black;"&gt;(&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;+1)&lt;/span&gt;&lt;span style="color:maroon;"&gt;&amp;quot;]:&amp;quot;&lt;/span&gt;&lt;span style="color:purple;"&gt;$parsedDocuments&lt;/span&gt;&lt;span style="color:black;"&gt;[&lt;/span&gt;&lt;span style="color:purple;"&gt;$innerIndex &lt;/span&gt;&lt;span style="color:red;"&gt;+&lt;/span&gt;&lt;span style="color:black;"&gt;1][&lt;/span&gt;&lt;span style="color:purple;"&gt;$index&lt;/span&gt;&lt;span style="color:black;"&gt;]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:green;"&gt;# If the files are horrendously different (i.e. out of step by one line) then you may just want the script exit on first error     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #Exit      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:black;"&gt;}     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;}      &lt;br /&gt;&lt;/span&gt;&lt;span style="color:#5f9ea0;"&gt;Write-Host &lt;/span&gt;&lt;span style="color:maroon;"&gt;Done&lt;/span&gt;&lt;/p&gt; &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://consultingblogs.emc.com/aggbug.aspx?PostID=13683" width="1" height="1"&gt;</content><author><name>James.Saull</name><uri>http://consultingblogs.emc.com/members/James.Saull.aspx</uri></author><category term="PowerShell" scheme="http://consultingblogs.emc.com/jamessaull/archive/tags/PowerShell/default.aspx" /></entry></feed>
