<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">James O&amp;#39;Neill&amp;#39;s blog </title><subtitle type="html">Windows Platform, Virtualization and PowerShell with a little Photography for good measure.</subtitle><id>http://blogs.technet.com/b/jamesone/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/" /><link rel="self" type="application/atom+xml" href="http://blogs.technet.com/b/jamesone/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2010-03-18T17:23:22Z</updated><entry><title>So long, farewell Auf Wiedersehen, good bye</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/11/16/so-long-farewell-auf-wiedersehen-good-bye.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/11/16/so-long-farewell-auf-wiedersehen-good-bye.aspx</id><published>2010-11-16T15:37:00Z</published><updated>2010-11-16T15:37:00Z</updated><content type="html">&lt;p&gt;Today is my last day at Microsoft after 10 years, it&amp;rsquo;s sad to be going, but&amp;nbsp; as someone said once &amp;ldquo;Regrets. I&amp;rsquo;ve had a few, but then again too few to mention.&amp;rdquo; I&amp;rsquo;ve met some great people while I&amp;rsquo;ve been here and&amp;nbsp; I look back on my time here with more pleasure than regret. &lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the end for this blog. My new blogs is at &lt;a href="http://jamesOne111.wordpress.com"&gt;http://jamesOne111.wordpress.com&lt;/a&gt;. If you&amp;rsquo;ve found what I had to say interesting, update your bookmarks. &lt;/p&gt;
&lt;p&gt;James.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3368927" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Thinking about the cloud - part 2, Office 365</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/11/01/thinking-about-the-cloud-part-2-office-365.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/11/01/thinking-about-the-cloud-part-2-office-365.aspx</id><published>2010-11-01T15:03:12Z</published><updated>2010-11-01T15:03:12Z</updated><content type="html">&lt;p&gt;In my &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/10/19/thinking-about-the-cloud-part-1.aspx"&gt;previous post&lt;/a&gt; I was talking in general terms about why BPOS was a sound idea. The recent &lt;a href="http://www.microsoft.com/presspass/press/2010/oct10/10-18steveb-mail.mspx"&gt;announcement of Ray Ozzie’s retirement&lt;/a&gt; set people quoting his mantra &lt;strong&gt;“Three screens and a cloud”&lt;/strong&gt; – the three screens being Computer, Mobile device, and TV.&amp;#160; The unwritten part of “&lt;strong&gt;Three &lt;/strong&gt;screens” is recognising their diversity: people should interact with the best possible client – which means &lt;em&gt;adapting to the specifics&lt;/em&gt; of each “screen”; it’s &lt;strong&gt;not “any browser and a cloud”&lt;/strong&gt;: many phone apps do something which PCs do in the browser, they only exist because of the need to give a different experience on a different kind of screen. Instead of seeing a monolithic website (which in reality probably wasn’t monolithic) we see an app which consumes a service (probably the same service which was behind the web site).&amp;#160; &lt;/p&gt;  &lt;p&gt;But there was more than publishing &lt;em&gt;stuff &lt;/em&gt;using services instead of HTML pages; more even than the likes of Groove or Live Meeting which used the cloud to enable new things.&amp;#160; From &lt;a href="http://ozzie.net/docs/the-internet-services-disruption/"&gt;Ozzie’s vision, famously expressed in 2005,&lt;/a&gt; came a realization that services &lt;u&gt;already used&lt;/u&gt; by business PCs and devices would &lt;strong&gt;increasingly be in the cloud, instead of on an organizations own servers.&lt;/strong&gt; That was the cue to provide Exchange as a service, SharePoint as a service and so on. We’ve tried to make a distinction between “&lt;em&gt;Software as a Service”&lt;/em&gt; – which in some people’s minds is “Any browser and a cloud” and &lt;em&gt;“Software PLUS Services”&lt;/em&gt; – which covers a plethora of client software: from multi-player games on Xbox to iTunes to Outlook talking to an Exchange server. But when Office Outlook on a PC accesses &lt;em&gt;Exchange-Online&lt;/em&gt; , Exchange is &lt;em&gt;software&lt;/em&gt; and it is provided &lt;em&gt;as a service&lt;/em&gt; –it just isn’t accessed using a browser: I haven’t yet seen a successful way to make the distinction between the two kinds of “Software as a service” just understand it has different meanings depending on who is speaking.&lt;/p&gt;  &lt;p&gt;I don’t know if it was planned but it seemed fitting that we should &lt;a href="http://www.microsoft.com/Presspass/press/2010/oct10/10-19Office365.mspx"&gt;announce the next generation of BPOS&lt;/a&gt; on the day after Ray’s announcement.&amp;#160; I prefer the new name &lt;strong&gt;Office 365.&lt;/strong&gt;&amp;#160; Mary Jo Foley posted something headed “&lt;a href="http://www.zdnet.com/blog/microsoft/office-365-sorry-folks-this-is-not-office-in-the-cloud/7743"&gt;This is not Office in the cloud&lt;/a&gt;” – in which she says “&lt;em&gt;this was not some out-of-the-blue change in Microsoft’s business model. Microsoft is still pushing Office first and foremost as a PC-based software package.&lt;/em&gt;” Which is spot on: if you need office in a browser, Office Web App is there but it is &lt;u&gt;not a replacement&lt;/u&gt;. I wrote in the previous post about the challenges of providing SharePoint, Exchange and so on, it is &lt;strong&gt;not Office but &lt;u&gt;the services behind Office &lt;/u&gt;which are in the cloud. &lt;/strong&gt;The key points of Office 365 are these:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;At it’s core are the&lt;strong&gt; latest versions&lt;/strong&gt; of the Server Software (Lync replaces Office Communications Server and provides Live Meeting functionality, and both Exchange and SharePoint are updated).&amp;#160; The &lt;a href="http://office365.microsoft.com/en-US/faq.aspx"&gt;FAQ page&lt;/a&gt; has a link to explain what happens to existing BPOS customers (and there are plenty of them – sending 167 million e-mails a day). &lt;/li&gt;    &lt;li&gt;The ability to create a &lt;strong&gt;Public website &lt;/strong&gt;(previously part of &lt;strong&gt;Office Live Small Business&lt;/strong&gt;) has moved into Office 365 (Again the &lt;a href="http://office365.microsoft.com/en-US/faq.aspx"&gt;FAQ page&lt;/a&gt; explains what will happen to Office Live Small Business) &lt;/li&gt;    &lt;li&gt;The update to SharePoint 2010 enables us to offer &lt;strong&gt;Office Web Apps&lt;/strong&gt; – so documents can be viewed in high fidelity and edited from the browser. &lt;/li&gt;    &lt;li&gt;Despite the the presence of Office Web Apps the main client will be &lt;strong&gt;Office on Desktop&lt;/strong&gt; &lt;strong&gt;computers &lt;/strong&gt;: Office Professional Plus for the desktop is now available as a part of the package&lt;strong&gt; on the same monthly subscription basis&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;There is &lt;strong&gt;a-la-carte pricing &lt;/strong&gt;for individual parts of the suite and bundles known as &lt;em&gt;plans&lt;/em&gt; targeted at different market segments. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I think the a-la-carte pricing option is a good thing – though some are bound to say “Microsoft are offering too many options”. The plans are just the combinations of cloud services we think will be popular; services can be added to a plan or bought standalone – for example “Kiosk” workers can get on the company e-mail system with Outlook web access from $2.&amp;#160; We’ve announced that the plans will cost between $4 to $27 per month,&amp;#160; that one of the enterprise plans closely mirrors the current BPOS at the same $10/user/month, and that there will be $6 plan with the features we think small business will need. In the run up to the launch I did see some details of different plans and options but I haven’t seen all of these in the announcements and it is not impossible that they will be fine tuned before the system goes fully live.&amp;#160; When will that be? The launch has a beta programme (sign-up is at &lt;a title="http://office365.microsoft.com" href="http://office365.microsoft.com"&gt;http://office365.microsoft.com&lt;/a&gt;) , &lt;a href="http://www.zdnet.com/blog/microsoft/ten-more-tidbits-on-microsofts-new-office-365-cloud-play/7725"&gt;Mary-Jo said back in July&lt;/a&gt; that the plan was for full launch was early 2011 which sounds about right – it’s also necessarily vague, because a beta might reveal a lot of unexpected work to be done: if you want a more precise date I always say in these cases those who know won’t talk, and those who talk don’t know.&amp;#160; &lt;/p&gt;  &lt;p&gt;We’ve &lt;a href="http://www.microsoft.com/presspass/features/2010/oct10/10-19Office365.mspx"&gt;positioned Office 365 as helping small businesses to think big and big business to act fast&lt;/a&gt;&amp;#160; – the link gives examples which range from the Starwood hotel chain to a single independent restaurant – it’s worth taking time to work out what it might mean to the organization(s) you work in/with: the cloud might be right for you, it might not - but if it isn’t I’d want to be able to explain why not and not have people think an opportunity was being missed through inertia. &lt;/p&gt;  &lt;p&gt;This post now appears on my new blog (&lt;a href="http://jamesone111.wordpress.com"&gt;http://jamesone111.wordpress.com&lt;/a&gt; )&amp;#160; -&amp;#160; &lt;a href="http://jamesone111.wordpress.com/2010/11/01/thinking-about-the-cloud-part-2-office-365/"&gt;James O’Neill’s blog Thinking about the cloud Part 2 office 365&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3365246" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Thinking about the cloud (part 1).</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/10/19/thinking-about-the-cloud-part-1.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/10/19/thinking-about-the-cloud-part-1.aspx</id><published>2010-10-19T16:49:19Z</published><updated>2010-10-19T16:49:19Z</updated><content type="html">&lt;p&gt;I was telling someone recently that before I joined Microsoft I spent the late 1990s running a small training company. The number of employees varied, averaging out at a dozen or so. I delivered training, did the business management, helped the win over customers and I looked after the IT. It was like doing two or three jobs.&lt;/p&gt;  &lt;p&gt;I’ve been quite reticent about our&amp;#160; “&lt;a href="http://www.microsoft.com/online/business-productivity.aspx"&gt;&lt;strong&gt;Business Productivity Online Service&lt;/strong&gt;&lt;/a&gt;&amp;quot;partly because it takes a long and closely argued post to cover why, from an IT professional’s point of view, getting rid of your servers isn’t abdicating. (This is not going to be that post). But as chance would have it I was looking at &lt;strong&gt;BPOS&lt;/strong&gt; again with my old job in my thoughts.&amp;#160; B-POS sounds like it should be something… ”points of sale”, but it is Exchange&lt;strong&gt;,&lt;/strong&gt;Communications server&lt;strong&gt;&amp;#160;&lt;/strong&gt;and Sharepoint provided as Pay-monthly “&lt;em&gt;Cloud &lt;/em&gt;services” &lt;/p&gt;  &lt;p&gt;In the training company we ran all our own IT services, but there’s no way I’d host my own web-server today: the sense of using a hosting company was clear before I left for Microsoft.&amp;#160; The launch of BPOS gave businesses a way to get hosted Mail (Exchange), Presence &amp;amp; IM (OCS) and Collaboration &amp;amp; Document management (Sharepoint) for $10 US per month – or in round numbers £80 annually - per user. Comparing that with the cost of server hardware and software and especially the time that in-house systems took up, if I were running that business today, my &lt;em&gt;head&lt;/em&gt; would say &lt;em&gt;get rid of the servers&lt;/em&gt;.&amp;#160; You can mix in-house and in-cloud servers; users keep the same desktop software which is crucial: you don’t give up Outlook to move your mailboxes to the cloud.&lt;/p&gt;  &lt;p&gt;It needs a change of attitude to give up the server. If my &lt;em&gt;head&lt;/em&gt; argued costs and figures,&amp;#160; my &lt;em&gt;heart&lt;/em&gt; might have come back with benefits like “You are master of your own destiny with the servers in-house”. But are you ? Back then we couldn’t justify clustering our servers, so if hardware failed – work would stop until it was repaired. Paying for a service in a Microsoft datacentre means it runs on clustered hardware, which someone else maintains. Microsoft’s datacentre is a bigger target for attack, but the sheer scale of the operation allows investment in tiers of defence. Small businesses tend not to worry about these things until something goes wrong, and you can always tell yourself that the risk is OK if you’re getting a better service in-house. But the truth is you’re probably &lt;u&gt;not&lt;/u&gt; getting&amp;#160; better service.&amp;#160; As a Microsoft employee I’m used to having access to my mail and calendar from anything that connect to the internet – laptop at home, or on the move, any PC with web access, or Sync’d to a phone. I doubt if I would have set that up for the training company but it’s part of BPOS – even to the extent of supporting iPhones and Blackberries.&amp;#160;&amp;#160; Getting rid of servers could not only save money but give users a better set of tools to use in their jobs – an easier thing to accept now that I don’t run servers for a business. &lt;/p&gt;  &lt;p&gt;Now if you’ve come across the idea of the HypeCycle (see &lt;a href="http://en.wikipedia.org/wiki/Hype_cycle"&gt;Wikipedia&lt;/a&gt; if not) – I agree &lt;a href="http://www.gartner.com/it/page.jsp?id=1447613"&gt;with Gartner&lt;/a&gt; that cloud technologies somewhere near “peak of inflated expectations”&amp;#160; - in other words people are talking up “the cloud” beyond it’s true capabilities, and if things follow a normal course there will be a “trough of disillusionment” before things find their true level. I don’t buy into the idea that in the future scarcely any business will bother with keeping their own server, any more than they would generate their own electricity.&amp;#160; Nor do I buy into the polar opposite - that very few organisations, and none with any sense, will keep critical services in the cloud – that idea seems just as implausible to me. So the truth must lie in between: the method of delivering services to users won’t change from one foregone conclusion (the in-house server) to another foregone conclusion (the service in the cloud), like so many things it will be a question of businesses asking “does it make sense to do this in-house”, and I think IT professionals will want to avoid depending on that question being answered one way. &lt;/p&gt;  &lt;p&gt;This post appears on my new blog (&lt;a title="http://jamesone111.wordpress.com/2010/11/01/thinking-about-the-cloud-part-2-office-365/" href="http://jamesone111.wordpress.com/2010/11/01/thinking-about-the-cloud-part-2-office-365/"&gt;http://jamesone111.wordpress.com&lt;/a&gt; )- &lt;a title="http://jamesone111.wordpress.com/2010/10/19/thinking-about-the-cloud-part-1/" href="http://jamesone111.wordpress.com/2010/10/19/thinking-about-the-cloud-part-1/"&gt;James O'Neill's blog Thinking about the cloud (part 1).&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3362880" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Exchange" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Exchange/" /><category term="Real Time Collaboration" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Real+Time+Collaboration/" /><category term="Office" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Office/" /></entry><entry><title>An unexpected call from a help desk? Hang up.</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/10/18/an-unexpected-call-from-a-help-desk-hang-up.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/10/18/an-unexpected-call-from-a-help-desk-hang-up.aspx</id><published>2010-10-18T13:04:51Z</published><updated>2010-10-18T13:04:51Z</updated><content type="html">&lt;p&gt;My phone rang: it was my dad. Father/son combinations don’t ring to chat like mother/daughter ones do, and Dad had been having computer problems. Specifically, Excel had been crashing but managing to recover his work. Each time it had offered to send data to Microsoft and each time he had declined. Then his phone had rung and the caller said it was about the problems he was having problems with his computer. &lt;/p&gt;  &lt;p&gt;To me this was immediately suspicious, there is &lt;u&gt;nothing in the Microsoft reporting process which sends personal information like phone-numbers&lt;/u&gt;. In fact when you register Windows you don’t put a phone number in, and it is not stored anywhere in the configuration of the machine.&amp;#160; Dad doesn’t have a support contract with anyone so even if personal information &lt;em&gt;were&lt;/em&gt; being sent I wouldn’t expect a phone call.&amp;#160; It would need quite some call centre to manage a courtesy call every time an app crashed. The&amp;#160; only way the caller could know that there was a problem and have his details was if something malign on the machine was telling them.     &lt;br /&gt;Dad assumed the caller was legitimate:&amp;#160; he assumed they’d been given his details by Microsoft, &lt;u&gt;we only give your personal information to a 3rd party if you have requested a specific service which needs us to do that&lt;/u&gt;, or said you were happy to be called about something specific by a partner (which is Opt-in, not opt-out).&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;They had his confidence and things now went from bad to worse, the caller got Dad to give him remote access to the PC for 50 minutes. There’s no telling what went on in that time, but at this stage I had to assume his machine could be doing anything and &lt;em&gt;everything&lt;/em&gt; on it machine was potentially compromised. Changing passwords would do no good if a key-logger had been installed.     &lt;br /&gt;After 50 minutes they called back and told Dad they’d removed 300 viruses from his machine (A bit of a dent for the Anti-virus software he &lt;em&gt;was&lt;/em&gt; using, and almost certainly untrue) and signed him up for a £180 support contract which he paid by credit card. When he went to use the card… as if you couldn’t guess, it bounced.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;I told him to turn everything off and quarantine the PC. Having realised he’d been taken in, he took steps to get his credit card re-issued, and he set about changing all the passwords which might have been exposed on this machine -using a different one. He’d heard about someone whose stock portfolio had been compromised: the crook had changed address and bank details and it was only when they tried to sell &lt;em&gt;everything, &lt;/em&gt;that the broker’s system spotted something might be wrong. I had to visit, and&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Remove the hard disk and connect it to another machine. &lt;/li&gt;    &lt;li&gt;Copy all the data off, for safety, &lt;/li&gt;    &lt;li&gt;Scan for Malware (nothing found) &lt;/li&gt;    &lt;li&gt;Roll windows back to a checkpoint before all this occurred. &lt;/li&gt;    &lt;li&gt;Re-apply updates from Windows updates since that check point &lt;/li&gt;    &lt;li&gt;Replace the anti-virus he was using with &lt;a href="http://www.microsoft.com/security_essentials"&gt;Microsoft Security essentials&lt;/a&gt; and let it scan the machine (nothing found). &lt;/li&gt;    &lt;li&gt;Re-run the Malicious Software Removal tool (MRT.EXE) – again nothing was found. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;My father was a smart man – smarter than me if I’m honest – and although he has been retired for nearly 20 years I don’t think he has lost his wits. I spent the afternoon of that phone call moving between rage and incomprehension – how could he be so &lt;em&gt;stupid. &lt;/em&gt;(Many readers will know the famous “Word Perfect support call ” story – put that into Bing or Google if you don’t: it ends with&amp;#160; &lt;em&gt;&amp;quot;unplug your system and pack it up just like it was when you got it. Then take it back to the store you bought it from.&amp;quot;&lt;/em&gt;&amp;#160; “What do I tell them?&amp;quot; &lt;em&gt;&amp;quot;Tell them you're too stupid to own a computer.&amp;quot; &lt;/em&gt;) . The problem is – of course – that &lt;u&gt;confidence tricksters are plausible&lt;/u&gt;, and anyone can fall for social engineering if it is well enough done.&amp;#160; &lt;/p&gt;  &lt;p&gt;It turns out that this is a scam being used by a couple of firms in India – they don’t get malware onto the machine and then call to fix it; they randomly call people and tell them they have a problem. It was a company using the name of &lt;strong&gt;OnlinePcCare.com who scammed my Dad&lt;/strong&gt; . One interesting thing was they put the credit card transaction through a third party G2S.com, and it may be that which triggered a fraud alert, the credit card company wouldn’t say. A &lt;a href="http://www.bing.com/search?q=onlinepccare+%2Bscam"&gt;search on Bing for “onlinePcCare +scam”&lt;/a&gt; finds plenty of other victims or near misses. &lt;a href="http://www.homehelptech.ie/blog/phone-pc-repair-scam/"&gt;This one from Ireland&lt;/a&gt; was immediately familiar “can you start event viewer…&amp;#160; are there any errors in the application log ?”.&amp;#160; If the event log is &lt;em&gt;empty&lt;/em&gt;, logging itself is broken. Some people recorded the scammers and have posted the call to you-tube – these come near the top in a search and &lt;a href="http://www.digitaltoast.co.uk/supportonclick-systemrecure-scam"&gt;Digital toast has a selection&lt;/a&gt; – together with a list of other names used by these people.&lt;/p&gt;  &lt;p&gt;Charles Arthur at The Guardian has been covering this story for a little while, see &lt;a href="http://www.guardian.co.uk/technology/2010/jul/19/police-crackdown-phone-scam-computer"&gt;Police crack down on computer support phone scam&lt;/a&gt;, and &lt;a href="http://www.guardian.co.uk/world/2010/jul/18/phone-scam-india-call-centres"&gt;Virus phone scam being run from call centres in India&lt;/a&gt;. His blog post &lt;a href="http://www.guardian.co.uk/technology/blog/2010/jul/20/phone-calls-india-scams"&gt;Those 'PC virus' phone call scams: the unanswered questions&lt;/a&gt; is a worth reading too; it confirms my finding that no malware seems to get installed, and shares my opinion that this fits the definition of obtaining money by deception. (Dad’s call to the police got a response of “here’s a crime number – we’ve got a big file on this and we’ll add you to it”)&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;If you act as family tech support&lt;/strong&gt;, do yourselves a favour.&amp;#160; As well as pointing out that none of those nice men in Nigeria will &lt;em&gt;really &lt;/em&gt;have a fortune which they will share, and that it is statistically nearly impossible to have a large lottery win and &lt;u&gt;at the same time&lt;/u&gt; be unaware of entering the draw, now you need to add&amp;#160; “no one really knows if you have a problem with your computer and calls to fix it” (you may be yelling at the computer but in cyberspace no-one can hear you scream.)&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;You might add “If you don’t &lt;em&gt;like&lt;/em&gt; unsolicited calls register with the &lt;a href="http://www.tpsonline.org.uk/ctps/number_type.html"&gt;telephone preference service&lt;/a&gt;,&amp;#160; no reputable company will call you once you’ve registered and any company which does call you is, by definition, not reputable&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Postscript&lt;/em&gt;. While I was working on this post I got a call from OnlinePcCare. It may be one of those random things or they may be stepping up their activities. &lt;/p&gt;  &lt;p&gt;This post appears on my new blog ( &lt;a href="http://jamesone111.wordpress.com/"&gt;http://jamesone111.wordpress.com/&lt;/a&gt;&amp;#160;&amp;#160; ) - &lt;a title="http://jamesone111.wordpress.com/2010/10/18/an-unexpected-call-from-a-help-desk-hang-up/" href="http://jamesone111.wordpress.com/2010/10/18/an-unexpected-call-from-a-help-desk-hang-up/"&gt;James O'Neill's blog An unexpected call from a help desk? Hang up.&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3362598" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Security and Malware" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Security+and+Malware/" /><category term="Privacy" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Privacy/" /></entry><entry><title>Working with the image module for PowerShell; part 3, GPS and other data</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/07/07/working-with-the-image-module-for-powershell-part-3-gps-and-other-data.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/07/07/working-with-the-image-module-for-powershell-part-3-gps-and-other-data.aspx</id><published>2010-07-07T06:59:00Z</published><updated>2010-07-07T06:59:00Z</updated><content type="html">&lt;p&gt;In &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx"&gt;Part one&lt;/a&gt; I showed how my &lt;a href="http://code.msdn.microsoft.com/PSImage/"&gt;downloadable PowerShell module&lt;/a&gt; can tag photos using related data – like GPS position – which was logged as they were being taken, and in &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/05/exploring-the-image-powershell-module.aspx"&gt;part two&lt;/a&gt; I showed how I’d extended the module in &lt;a href="http://code.msdn.microsoft.com/PowerShellPack"&gt;James Brundage’s&amp;#160; PowerPack&lt;/a&gt;&lt;b&gt; &lt;/b&gt;for Windows 7. Now I want to explain the extensions which automate the processes of: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Getting the data logged by GPS units and similar devices &lt;/li&gt;    &lt;li&gt;Reading each image file from the memory card and matching it to an entry in the log made at around the same time &lt;/li&gt;    &lt;li&gt;Building up the set of EXIF filters filters based on the log entry. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The data and pictures are &lt;strong&gt;connected by the time stamp on each,&lt;/strong&gt; but to connect properly the scripts must cope with any &lt;b&gt;time difference&lt;/b&gt; between the camera’s clock and time on the logging device – whether that’s a GPS unit or my wrist mounted scuba computer. A few seconds won’t introduce much error, but the devices might be in different time zones –for example GPS works on Universal time (GMT) - so the offset is often hours, not seconds. My quick and dirty way of making a note of the difference is to &lt;b&gt;photograph whatever is doing the logging&lt;/b&gt; (assuming it can display its time). The camera will record the time its own clock was set to in the EXIF “Date and time taken” field and subtracting that from the time displayed on the logger in the picture gives an offset to apply to all data points. The following is the core of a function named &lt;code&gt;Set-Offset&lt;/code&gt; which could be seen in part one;&lt;/p&gt; &lt;code&gt;   &lt;p&gt;$RefDate = ([datetime]( Read-Host (&amp;quot;Please enter the Date &amp;amp; time &amp;quot; +      &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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;in the reference picture, formatted as&amp;quot; + [char]13 +       &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [Char]10 + &amp;quot;Either MM/DD/yyyy HH:MM:SS ±Z or &amp;quot; +       &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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;dd MMMM yyyy HH:mm:ss ±Z&amp;quot;))&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;&amp;#160; ).touniversalTime()&lt;/p&gt;    &lt;p&gt;$ReferenceImagePath = Read-Host &amp;quot;Please enter the path to the picture&amp;quot;      &lt;br /&gt;if ($ReferenceImagePath -and (test-path $ReferenceImagePath) -and $RefDate) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $picTime = (get-exif -image $ReferenceImagePath).dateTaken&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $Global:offset = ($picTime - $refdate).totalSeconds       &lt;br /&gt;}&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;The real &lt;code&gt;Set-Offset&lt;/code&gt; can take &lt;code&gt;–refDate&lt;/code&gt; and &lt;code&gt;–ReferenceImagePath&lt;/code&gt; parameters so the user doesn’t need to be prompted for them.&amp;#160; Most of code you can see is concerned with getting the user to enter the time (in a format that PowerShell can use) and the path to the file. The only part which uses the image module is     &lt;br /&gt;&lt;code&gt;(get-exif -image $ReferenceImagePath).dateTaken      &lt;br /&gt;&lt;/code&gt;&lt;code&gt;Get-Exif &lt;/code&gt;is a command I added, and it returns an object which contains all the interesting EXIF data from the image file. Only the value in the &lt;code&gt;DateTaken&lt;/code&gt; property is of interest here; it is used to calculate the number of seconds between the &lt;em&gt;camera&lt;/em&gt; time and &lt;em&gt;logger&lt;/em&gt; time and the result is stored in a global variable named &lt;code&gt;$offset&lt;/code&gt;. &lt;/p&gt;  &lt;p&gt;The next step is to read the data and applying the offset to it; depending on the how it was logged the next step will be either:    &lt;br /&gt;&lt;code&gt;&amp;#160; $Points = Get-NMEAData&amp;#160;&amp;#160; -Path $Logpath -offset $offset      &lt;br /&gt;Or       &lt;br /&gt;&lt;code&gt;&amp;#160; $Points = Get-GPXData&amp;#160;&amp;#160;&amp;#160; -Path $Logpath -offset $offset        &lt;br /&gt;&lt;/code&gt;Or&amp;#160; &lt;br /&gt;&amp;#160;&lt;code&gt; $Points = Get-CSVGPSData -Path $Logpath -offset $offset        &lt;br /&gt;&lt;/code&gt;Or       &lt;br /&gt;&lt;code&gt;&amp;#160; $Points = Get-SuuntoData -Path $Logpath -offset $offset&lt;/code&gt;&lt;/code&gt; &lt;/p&gt;  &lt;p&gt;The last one handles the comma separated data exported from the &lt;em&gt;Suunto Dive Manager&lt;/em&gt; program which downloads the data from my dive watch. The other 3 deal with different formats of GPS data, it may be in the form of NMEA sentences (comma separated again) or the CSV format used by &lt;a href="http://www.efficasoft.com/gpsutilities/index_wm_ppc.html"&gt;Efficasoft GPS utilities&lt;/a&gt; on my phone or the XML-based &lt;em&gt;GPX&lt;/em&gt; format. (GPS data formats are worth another post of their own). &lt;b&gt;You may need to make slight alterations to these functions&lt;/b&gt; to work with your own logger, but they are easy to change.&amp;#160; All of them except &lt;code&gt;Get-GPXdata&lt;/code&gt; import from a CSV file – and use a feature which is new in PowerShell V2 to specify the CSV column headings when using the &lt;code&gt;import-csv&lt;/code&gt; command.&amp;#160; &lt;code&gt;Get-GPXData&lt;/code&gt; uses XML documents looking for a hierarchy which goes &lt;code&gt;&amp;lt;gpx&amp;gt; &amp;lt;trk&amp;gt; &amp;lt;trkseg&amp;gt;&amp;lt;trkpt&amp;gt;&amp;lt;trkpt&amp;gt;&amp;lt;trkpt&amp;gt;&amp;lt;trkpt&amp;gt;… &lt;/code&gt;All the functions use &lt;code&gt;select-object&lt;/code&gt; to remove fields which aren’t needed and insert calculated data (for example converting the native speed in knots from GPS to MPH and KM/H )&lt;/p&gt;  &lt;p&gt;After running one of these commands there will be &lt;b&gt;a collection of data points&lt;/b&gt; stored in the variable &lt;code&gt;$points&lt;/code&gt;. &lt;b&gt;Each data point has a time&lt;/b&gt; – adjusted by the offset value, so it is time &lt;b&gt;as the camera would have seen it&lt;/b&gt;. The Suunto dive computer points have a Description (the name of the dive site and water temperature) and depth, while the GPS points have Speed (GPS works in knots and the script calculates Miles per Hour and Kilometres per hour); bearing, latitude as Degrees, Minutes, Seconds, North or South, Longitude as Degrees, Minutes, Seconds East or West, Latitude &amp;amp; Longitude in their original form from the logger and Altitude in both meters and Feet (NMEA data needs extra processing to get the attitude data and &lt;code&gt;Get-NMEAdata&lt;/code&gt; has a &lt;code&gt;–NoAltitude&lt;/code&gt; switch to allow processing to be speeded up if it only Latitude and Longitude are needed ) &lt;/p&gt;  &lt;p&gt;Armed with a collection of points the next step find the one nearest to the time the picture was taken; a function named &lt;code&gt;Get-NearestPoint&lt;/code&gt; does this. Given &lt;b&gt;the time stamped on the photo&lt;/b&gt; the function returns the &lt;b&gt;data point logged closest to that time&lt;/b&gt;. It isn’t very sophisticated, taking 3 parameters: a time, a time-sorted array of points and the name of field on the data points to check for the time, and working through the points until the point being looked at is further away from the target time than the previous point; the core of the function looks like this: &lt;/p&gt; &lt;code&gt;   &lt;p&gt;&amp;#160;&amp;#160; $variance = [math]::Abs(($dataPoints[0].$columnName - $MatchingTime).totalseconds)      &lt;br /&gt;&amp;#160;&amp;#160; $i = 1       &lt;br /&gt;&amp;#160;&amp;#160; do {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $v = [math]::Abs(($dataPoints[$i].$columnName - $MatchingTime).totalseconds)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ($v -le $variance) {$i ++ ; $variance = $v }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } while (($v -eq $variance) -and ($i -lt $datapoints.count))       &lt;br /&gt;&amp;#160;&amp;#160; $datapoints[($i -1)]&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;In use it looks something like this.&lt;/p&gt; &lt;code&gt;   &lt;p&gt;$image = Get-Image&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; –Path &amp;quot;MyPicture.Jpg&amp;quot;      &lt;br /&gt;$dt&amp;#160;&amp;#160;&amp;#160; = Get-ExifItem&amp;#160;&amp;#160;&amp;#160;&amp;#160; -image $image&amp;#160; -ExifID $ExifIDDateTimeTaken       &lt;br /&gt;$point = Get-nearestPoint –Data&amp;#160; $points -Column &amp;quot;DateTime&amp;quot; -MatchingTime $dt&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;&lt;code&gt;$point&lt;/code&gt; contains the &lt;b&gt;data used to set the EXIF properties &lt;/b&gt;of the picture, a process which requires a &lt;strong&gt;series of &lt;/strong&gt;&lt;em&gt;&lt;strong&gt;Exif filters&lt;/strong&gt;&amp;#160;&lt;/em&gt;to be created – and I explained EXIF Filters in &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/05/exploring-the-image-powershell-module.aspx"&gt;Part 2.&lt;/a&gt;&amp;#160; As well as data retrieved from a log, there are times when I want to tag a picture manually. For example&amp;#160; I took some photos in London’s Trafalgar Square &lt;em&gt;without&lt;/em&gt; a GPS logger that I want to tag with &lt;em&gt;51°30’30” N, 0° 7’40” W&amp;#160; . &lt;/em&gt;To make this easier I created a function named &lt;code&gt;Convert-GPStoEXIFFilter&lt;/code&gt; which can be invoked like this:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;$filter = Convert-GPStoEXIFFilter 51,30,30 &amp;quot;N&amp;quot; 0,7,40 &amp;quot;W&amp;quot;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;If you’re not used to PowerShell I should say that in some places 51,30,30 would be the way to write 3 parameters.&amp;#160; In PowerShell&amp;#160; it is one array parameter with 3 members. (Even old hands at Powershell occasionally get confused and put in a comma which turns two parameters into a single array parameter)&amp;#160; I could have explicitly named the parameters and made it clear that these 3 were an array by writing    &lt;br /&gt;&amp;#160;&lt;code&gt;-LatDMS @(51,30,30) -NS &amp;quot;N&amp;quot;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;Convert-GPStoEXIFFilter &lt;/code&gt;returns a chain of up to 7 EXIF Filters for&lt;em&gt; GPS version, Latitude reference&lt;/em&gt; (North or South) &lt;em&gt;Longitude reference &lt;/em&gt;(East or West),&lt;em&gt; Altitude reference&lt;/em&gt; (above or below Sea Level), the &lt;em&gt;Latitude &lt;/em&gt;&amp;amp; &lt;em&gt;Longitude &lt;/em&gt;(as degrees, Minutes, Second and Decimals) and &lt;em&gt;Altitude &lt;/em&gt;in meters (altitude is optional). If &lt;code&gt;$point&lt;/code&gt; holds the data logged at the time the picture was taken &lt;code&gt;Convert-GPStoEXIFFilter&lt;/code&gt; can be invoked like this:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;$filter = Convert-GPStoEXIFFilter -LatDMS $point.Latdms -NS $point.NS `      &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -LONDMS $point.londms -EW $point.ew -AltM $point.altM &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;At the end of &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/05/exploring-the-image-powershell-module.aspx"&gt;part 2&lt;/a&gt; I showed the &lt;code&gt;&lt;strong&gt;Copy-Image&lt;/strong&gt;&lt;/code&gt; command that handles &lt;em&gt;renaming&lt;/em&gt;, &lt;em&gt;rotating&lt;/em&gt;, and setting &lt;em&gt;keywords&lt;/em&gt; &amp;amp; &lt;em&gt;title&lt;/em&gt; EXIF fields and mentioned it could be handed a set of filters. All the parameters that &lt;code&gt;Copy-image&lt;/code&gt; uses are available to &lt;code&gt;&lt;strong&gt;Copy-GPSImage&lt;/strong&gt;,&lt;/code&gt; which takes the the set of points as well . Internally it performs the &lt;code&gt;$image=&lt;/code&gt; , &lt;code&gt;$dt=&lt;/code&gt; , &lt;code&gt;$point=&lt;/code&gt; and &lt;code&gt;$filter=&lt;/code&gt; commands seen above before calling &lt;code&gt;Copy-image&lt;/code&gt; with the image, the filter chain and the other parameters it was passed. The full set of parameters for &lt;code&gt;Copy-GPSImage&lt;/code&gt; is as follows &lt;/p&gt;  &lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="100%"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Image&lt;/td&gt;          &lt;td valign="top"&gt;The image to work on – this can be an image object, a file object or a file name can come from the Pipeline.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Points&lt;/td&gt;          &lt;td valign="top"&gt;The array of GPS data points from Get-NMEAdata, get-GPXData or Get-CSVGPSData&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Keywords&lt;/td&gt;          &lt;td valign="top"&gt;Keywords to go into the EXIF Keyword Tags field &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Title&lt;/td&gt;          &lt;td valign="top"&gt;Text to go into the EXIF Title field&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Rotate&lt;/td&gt;          &lt;td valign="top"&gt;If specified, adds whatever rotate filter is indicated by the EXIF Orientation field&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;NoClobber&lt;/td&gt;          &lt;td valign="top"&gt;The conventional PowerShell switch to say “Don’t overwrite the file if it already exists”&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Destination &lt;/td&gt;          &lt;td valign="top"&gt;The FOLDER to which the file should be saved.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;Replace&lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;Two values separated by a comma specifying a replacement in the file NAME&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;ReturnInfo&lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;If specified returns the point(s) matched with the pictures&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;So now it is possible to use three commands to geotag the images, the first two get time offset , and get the data points, applying that offset in the process.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;set-offset &amp;quot;D:\dcim \100Pentx\IMG43272.JPG&amp;quot; –Verbose      &lt;br /&gt;$points= Get-CSVGPSData 'F:\My Documents\My GPS\Track Log\20100425115503.log' ‑offset $offset&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;and the third gets the files on a memory card and push them into Copy-GPSImage &lt;/p&gt;  &lt;p&gt;&lt;code&gt;$photoPoints = Dir E:\dcim –include *.jpg –recurse |&amp;#160; Copy-GpsImage -Points $Points `&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -verbose&amp;#160; -DestPath &amp;quot;C:\users\jamesone\pictures\oxford&amp;quot;&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; -Keywords &amp;quot;Oxfordshire&amp;quot;&amp;#160; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;&amp;#160; -returnInfo &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;This is much as it appeared in &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx"&gt;Part 1&lt;/a&gt; although third command has changed slightly.&lt;code&gt;Copy-GPSImage&lt;/code&gt; now has a &lt;code&gt;–returnInfo&lt;/code&gt; switch which returns the points where a photo was taken; to link the point to the image file(s) which patched it an extra property &lt;em&gt;Paths&lt;/em&gt; is added to the points. &lt;/p&gt;  &lt;p&gt;I mention this because I wanted to show the functions I put added almost for fun at the end. &lt;code&gt;Out-MapPoint&lt;/code&gt; and &lt;code&gt;ConvertTo-GPX&lt;/code&gt; got brief mentions in part 1: with the data in &lt;code&gt;$photopoints&lt;/code&gt; I can push camera symbols through to a map like this : (note the sort –unique to remove duplicate points, 79 is the camera symbol)     &lt;br /&gt;&lt;code&gt;&amp;#160; $photopoints | sort dateTime -Unique | Out-MapPoint -symbol {79}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;/code&gt;Alternatively I can create a GPX file which can be imported into MapPoint, Google Earth and lots of other tools. GPX files need to be UTF8 text, PowerShell wants to write output files as Unicode – thwarting it isn’t hard but is ugly.&amp;#160; &lt;br /&gt;&lt;code&gt;&amp;#160; $photopoints | sort dateTime -Unique | convertto-gpx | out-file photoPoints.gpx -Encoding utf8&lt;/code&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;With the photo points logged it would be nice to show the path I walked but that will have too many points so I wrote Merge-GPSPoint which combines all the points for each minute so I can do&amp;#160; &lt;br /&gt;&lt;code&gt;&amp;#160; Merge-GPSPoints $points | Out-MapPoint      &lt;br /&gt;&lt;/code&gt;or&amp;#160; &lt;br /&gt;&lt;code&gt;&amp;#160; Merge-GPSPoints $points | convertto-gpx | out-file WalkPoints.gpx -Encoding utf8 &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;One thing I should point out here is that the GPX format which I convert to is a series of Waypoints (i.e places that will be navigated to in future), not track points (places which have been visited in the past). The import routine processes the latter. &lt;/p&gt;  &lt;p&gt;The last detail of the module for now is that I also gave it a function to find out where an image was taken, like this&lt;/p&gt;  &lt;p&gt;&lt;code&gt;PS&amp;#160; &amp;gt; resolve-imageplace 'C:\users\Jamesone\Pictures\Oxford\OX-43624.JPG'      &lt;br /&gt;Summertown, Oxford, Oxford, Oxfordshire, England, United Kingdom, Europe, Earth&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;That’s not a data error when it says Oxford, Oxford. The Geoplaces web service I use returns &lt;/p&gt;  &lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="868"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="200"&gt;&lt;strong&gt;ToponymName&lt;/strong&gt; :&lt;/td&gt;          &lt;td valign="top" width="102"&gt;&lt;strong&gt;name&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/td&gt;          &lt;td valign="top" width="73"&gt;&lt;strong&gt;fcode&lt;/strong&gt;&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;strong&gt;Desctiption for fcode&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;Earth&lt;/td&gt;          &lt;td valign="top" width="104"&gt;Earth&lt;/td&gt;          &lt;td valign="top" width="73"&gt;AREA&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;a tract of land without homogeneous character or boundaries&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;Europe&lt;/td&gt;          &lt;td valign="top" width="105"&gt;Europe&lt;/td&gt;          &lt;td valign="top" width="73"&gt;CONT&lt;/td&gt;          &lt;td valign="top" width="491"&gt;           &lt;p&gt;&lt;em&gt;Continent&lt;/em&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;United Kingdom of Great Britain and Northern Ireland&lt;/td&gt;          &lt;td valign="top" width="106"&gt;United Kingdom&lt;/td&gt;          &lt;td valign="top" width="73"&gt;PCLI&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;Independent political entity&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;England&lt;/td&gt;          &lt;td valign="top" width="106"&gt;England&lt;/td&gt;          &lt;td valign="top" width="73"&gt;ADM1&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;First-order administrative division (US States, England, Scotland etc)&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;County of Oxfordshire&lt;/td&gt;          &lt;td valign="top" width="106"&gt;Oxfordshire&lt;/td&gt;          &lt;td valign="top" width="73"&gt;ADM2&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;A sub-division of an ADM1 (Counties in the UK)&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;Oxford District&lt;/td&gt;          &lt;td valign="top" width="106"&gt;Oxford&lt;/td&gt;          &lt;td valign="top" width="73"&gt;ADM3&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;A sub-division of an ADM2 (District level councils in the UK)&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;Oxford&lt;/td&gt;          &lt;td valign="top" width="106"&gt;Oxford&lt;/td&gt;          &lt;td valign="top" width="73"&gt;PPL&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;Populated Place&amp;#160; (Cities, Towns, Villages)&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="199"&gt;Summertown&lt;/td&gt;          &lt;td valign="top" width="107"&gt;Summertown&lt;/td&gt;          &lt;td valign="top" width="73"&gt;PPLX&lt;/td&gt;          &lt;td valign="top" width="491"&gt;&lt;em&gt;Section of populated place&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p&gt;I haven’t done much to introduce intelligence into processing this. I used Trafalagar square in one part 2 and this returns&amp;#160; &lt;em&gt;Charing Cross, London, City of Westminster, Greater London, England, United Kingdom, Europe, Earth &lt;/em&gt;which is correct but difficult to allow for. To make matters worse all sorts of strange geo-political questions come up as well if you say UK is the country, and England is the topmost Administrative division: English people might well think counties are the tier below parliament adminstratively but since the Scottish parliament and Welsh assembly opened, you might find a different view if you step over the border. Software which works to the American model of displaying the Populated place and First admin Division – for example Seattle, Washington; is easily thrown giving Reading, Berkshire it gives Reading, England.&amp;#160; Those are questions to look at another time&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3342355" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Photography" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Photography/" /><category term="Powershell" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Powershell/" /></entry><entry><title>Exploring the IMAGE PowerShell Module</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/07/05/exploring-the-image-powershell-module.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/07/05/exploring-the-image-powershell-module.aspx</id><published>2010-07-05T11:57:44Z</published><updated>2010-07-05T11:57:44Z</updated><content type="html">&lt;p&gt;In &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx"&gt;part one of this series&lt;/a&gt; I showed the finished version of photo-tagging script I’ve been using. I based my work (which is &lt;a href="http://code.msdn.microsoft.com/PSImage/"&gt;available for download&lt;/a&gt;) on James Brundage’s PSImageTools module for PowerShell which is part of the PowerPack included with the Windows 7 Resource kit (and &lt;a href="http://code.msdn.microsoft.com/PowerShellPack"&gt;downloadable independently&lt;/a&gt;). In this post I want to show the building blocks that were in the original library provide and the ones I added.     &lt;br /&gt;Producing a modified image using this module usually means working to the following pattern: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Read an image &lt;/li&gt;    &lt;li&gt;Create a set of &lt;i&gt;filters&lt;/i&gt; &lt;/li&gt;    &lt;li&gt;Apply the filters to the image &lt;/li&gt;    &lt;li&gt;Save the modified image &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you are wondering what a filter &lt;em&gt;is&lt;/em&gt;, that will become clear in a moment. James B’s original module had these commands. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="100%"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Get-Image&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Loads an image from a file&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Add-CropFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Creates a filter to crop the image to a given size &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Add-OverlayFilter &lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Creates a filter to an overlay such as a watermark or copyright notice&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Add-RotateFlipFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Creates a filter to rotate the image in multiples of 90 degrees or to mirror it vertically or horizontally&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Add-ScaleFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Creates a filter to resize the image&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Set-ImageFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Applies a set of filters to one or more images&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Get-ImageProperty &lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Gets Items of EXIF data from an image&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;ConvertTo-Bitmap&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Loads a file, applies a conversion filter to it, and saves it as a BMP&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;ConvertTo-Jpeg&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Loads a file, applies a conversion filter to it, and saves it as a JPG &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="321"&gt;&lt;code&gt;Copy-ImageIntoOrganizedFolder&lt;/code&gt;&lt;/td&gt;        &lt;td width="1366"&gt;Organizes pictures into folders based on EXIF data &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;You can see there are &lt;strong&gt;4 kinds of filter&lt;/strong&gt; with their own commands in the list and each one makes some modification to the image: &lt;strong&gt;cropping&lt;/strong&gt;, &lt;strong&gt;scaling&lt;/strong&gt;, &lt;strong&gt;rotating&lt;/strong&gt;, or adding an &lt;strong&gt;overlay&lt;/strong&gt;. Inside the two ConvertTo commands, a 5th kind of filter, &lt;strong&gt;conversion&lt;/strong&gt;,&lt;strong&gt; &lt;/strong&gt;is used and I added a function to create filters to do that. I made some changes to the existing functions to give better flexibility with how they can be called, and added some further functions, mostly to work with EXIF data embedded in the image file. The full list of functions I added is as follows:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="100%"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Save-Image&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Not strictly required but it is a logical command to have at the end of a pipe line, instead of calling a method of the image object&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;New-ImageFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Not strictly required either but it makes the syntax of &lt;em&gt;adding &lt;/em&gt;filters more logical&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;New-Overlay&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Takes text and font information and creates a bitmap with the text in that font&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Add-ConversionFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Creates a conversion filter for JPG, GIF, TIF, BMP or PNG format (as used in ConvertTo-Jpeg / Bitmap without applying it to an image or saving it)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Add-ExifFilter&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Adds a filter to set EXIF data&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Copy-Image&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Copies one or more images, renaming, rotating and setting title keyword tags in the process.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Get-EXIF&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Returns an object representing the EXIF data of the image&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Get-EXIFItem&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Returns a single item of EXIF data using its EXIF ID (the common IDs are defined as constants&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Get-PentaxMakerNoteProperty&lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Decodes information from the Maker-Note Exif field, I have only implemented this for Pentax data&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="323"&gt;&lt;code&gt;Get-PentaxExif &lt;/code&gt;&lt;/td&gt;        &lt;td width="1374"&gt;Similar to Get-Exif but with Maker-Note fields for Pentax &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;The image below was resized and labelled using these commands.&amp;#160; The first step is to &lt;strong&gt;create an image to act as an overlay&lt;/strong&gt;:&amp;#160; I’m going to a copyright notice in Red red text, in 32 point Arial&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;code&gt;PS&amp;gt; $Overlay = New-overlay -text &amp;quot;© James O'Neill 2008&amp;quot; -size 32 -TypeFace &amp;quot;Arial&amp;quot;&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;&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;&amp;#160;&amp;#160;&amp;#160; -color &amp;quot;red&amp;quot; -filename &amp;quot;$Pwd\overLay.jpg&amp;quot;&amp;#160; &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;I’m using a &lt;img style="display: inline" class="wlDisabledImage" title="Click for the 800 pixel high version" alt="Click for the 800 pixel high version" align="right" src="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/7433.DIVE_5F00_1799_2B002D00_small_5F00_thumb_5F00_1.jpg" width="200" height="150" /&gt;picture I took in 2008: and I could have used a more complex command to build the text from the &lt;em&gt;date taken&lt;/em&gt; field in the EXIF data.&amp;#160; Next I’m going to &lt;strong&gt;create a chain of filters&lt;/strong&gt; to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Resize&lt;/strong&gt; my image to be 800 pixels high (the aspect ratio is preserved by default), &lt;/li&gt;    &lt;li&gt;Add my &lt;strong&gt;overlay&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Set the &lt;strong&gt;EXIF fields&lt;/strong&gt; for the keyword-tags, title and Copyright information &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Save&lt;/strong&gt; the image as a JPEG with a &lt;strong&gt;70/100 quality rating&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Despite the multi-line formatting here, this is a single PowerShell command:&amp;#160; &lt;code&gt;$filter = new-Filter | add | add | add...&lt;/code&gt; &lt;/p&gt;  &lt;p&gt;&lt;code&gt;PS&amp;gt; $filter = new-Imagefilter |&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-ScaleFilter&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -passThru -height 800 -width 65535&amp;#160; |       &lt;br /&gt;&lt;/code&gt;&lt;code&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-OverlayFilter&amp;#160;&amp;#160;&amp;#160; -passThru –top&amp;#160;&amp;#160;&amp;#160; 75&lt;/code&gt;&lt;code&gt;0 –left&amp;#160; 0&amp;#160;&amp;#160;&amp;#160;&amp;#160; –&lt;/code&gt;&lt;code&gt;image&amp;#160;&amp;#160;&amp;#160; $Overlay |      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-ExifFilter&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -passThru -ExifID $ExifIDKeywords&amp;#160; -typeName &amp;quot;vectorofbyte&amp;quot; -string &amp;quot;Ocean&amp;quot; |       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-ExifFilter&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -passThru -ExifID $ExifIDTitle&amp;#160;&amp;#160;&amp;#160;&amp;#160; -typeName &amp;quot;vectorofbyte&amp;quot; -string &amp;quot;StingRay&amp;quot;&amp;#160; |       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-ExifFilter&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -passThru -ExifID $ExifidCopyright &lt;/code&gt;&lt;code&gt;-typeName &amp;quot;String&amp;quot; -value &amp;quot;© James O'Neill 2008&amp;quot; |      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-ConversionFilter -passThru –typeName jpg -quality 70&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Given a set of filters, a script can &lt;strong&gt;get an image,&amp;#160; apply the filters to it and save it.&lt;/strong&gt; Originally these 3 steps needed 3 commands to be piped together like this     &lt;br /&gt;&lt;code&gt;PS&amp;gt; Get-Image&amp;#160;&amp;#160; C:\Users\Jamesone\Pictures\IMG_3333.JPG&amp;#160; |      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Set-ImageFilter -filter $filter |       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Save-image -fileName {$_.FullName -replace &amp;quot;.jpg$&amp;quot;,&amp;quot;-small.jpg&amp;quot;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;I streamlined this first by changing James B’s&amp;#160; &lt;code&gt;Set-ImageFilter&lt;/code&gt; so that if it is given something other than an &lt;em&gt;image object&lt;/em&gt;, it hands it to &lt;code&gt;Get-Image&lt;/code&gt;.&amp;#160; In other words &lt;code&gt;Get-Image &lt;em&gt;X&lt;/em&gt; | Set-Image&lt;/code&gt; is reduced to &lt;code&gt;Set-Image &lt;em&gt;X&lt;/em&gt;&lt;/code&gt; (and I made sure X could be path, including one with wild cards or one or more file objects) . After processing I added a &lt;code&gt;-savepath&lt;/code&gt; parameter so that &lt;code&gt;set-image –SavePath &lt;em&gt;P&lt;/em&gt;&lt;/code&gt; is the same as &lt;code&gt;Set-Image | Save-Image &lt;em&gt;P&lt;/em&gt;&lt;/code&gt; . &lt;em&gt;P&lt;/em&gt; can be a path, or script block which becomes a path, or empty to over-write the image. &lt;strong&gt;Get an image,&amp;#160; apply the filters to it and save it &lt;/strong&gt;becomes a &lt;strong&gt;singe command.      &lt;br /&gt;&lt;/strong&gt;&lt;code&gt;PS&amp;gt; Set-ImageFilter –Image &amp;quot;.\IMG_3333.JPG&amp;quot; -filter $filter `      &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; –SaveName {$_.FullName -replace &amp;quot;.jpg$&amp;quot;,&amp;quot;-small.jpg&amp;quot;}&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;The workflow for my photos typically begins with &lt;em&gt;copying files&lt;/em&gt; from a memory card, &lt;em&gt;replacing the start of the filename&lt;/em&gt; - like the “IMG_” in the example above - with text like “DIVE” (I try to keep the sequential numbers the camera stamps on the pictures as a basis for a unique ID). Next, I &lt;em&gt;rotate&lt;/em&gt; any which were shot in portrait format so they display correctly and finally I add descriptive information to the EXIF data: keyword tags like “Ocean” and titles like “Stingray”. So it made sense to create a &lt;code&gt;&lt;strong&gt;copy-image&lt;/strong&gt;&lt;/code&gt; function which would handle all of that in one command. The only part of this which hasn’t already appeared is rotation. The Orientation EXIF field contains 8 to show the image has been rotated 90 degrees, 6 indicates 270 degrees of rotation, and 1 to show the image is correctly rotated, so it is a question of read the data, and depending on what we find add filters to rotate and reset the orientation data.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;$orient = Get-ExifItem -image $image -ExifID $ExifIDOrientation&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;if ($orient -eq 8) {Add-RotateFlipFilter -filter $filter -angle 270       &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Add-exifFilter&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -filter $filter -ExifID $ExifIDOrientation`       &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;&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;&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;&amp;#160;&amp;#160;&amp;#160; -value&amp;#160; 1&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -typeid $ExifUnsignedInteger }&amp;#160;&amp;#160;&amp;#160; &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;There is similar code to deal with rotation in the opposite direction, and rotation is just another filter like adding the EXIF data for keywords or title, all job of &lt;code&gt;Copy-Image&lt;/code&gt; does is to build a chain of filters to add Title and Keyword tags and rotate the image, determine the full path the new copy should be saved to and invoke &lt;code&gt;Set-ImageFilter. &lt;/code&gt;To make it more flexible,&amp;#160; gave &lt;code&gt;Copy-Image&lt;/code&gt; the ability to add filters to an existing filter chain: in the &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx"&gt;part one&lt;/a&gt; you could see &lt;code&gt;Copy-GPSImage&lt;/code&gt;&amp;#160; which finds the GPS data to apply to a picture and produces a series of filters from it: these filters are passed on to &lt;code&gt;Copy-Image&lt;/code&gt; which does the rest.&amp;#160; &lt;/p&gt;  &lt;p&gt;The last aspect of &lt;code&gt;Copy-Image&lt;/code&gt; to look at is renaming:&amp;#160; &lt;code&gt;-Replace&lt;/code&gt; has become one of my favourite PowerShell operators. It takes a regular expression and a block of text, and replaces all instances of expression found in a string with the text. Regular expressions can be complex but &lt;code&gt;“IMG”&lt;/code&gt; is perfectly valid so if I have a lot of pictures to name as “OX-” for “Oxford”&amp;#160; I can call the function with a &lt;code&gt;replace &lt;/code&gt;parameter of &lt;code&gt;&amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;&lt;/code&gt; . Inside &lt;code&gt;Copy-Image&lt;/code&gt;, the parameter &lt;code&gt;$replace &lt;/code&gt;is used with the &lt;code&gt;-replace &lt;/code&gt;operator (using PowerShell’s ability&amp;#160; to treat “img”,”ox” as one parameter in two parts).&amp;#160;&amp;#160; &lt;code&gt;$savePath&lt;/code&gt; is worked out as follows:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;if ($replace)&amp;#160;&amp;#160; {$SavePath= join-path -Path $Destination `      &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -ChildPath ((Split-Path $image.FullName -Leaf) -Replace $replace)}       &lt;br /&gt;else&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {$SavePath= join-path -Path $Destination `       &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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -ChildPath&amp;#160; (Split-Path $image.FullName -Leaf)&amp;#160; }&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;As mentioned above I went to some trouble to make sure the functions &lt;code&gt;can&lt;/code&gt; accept image objects &lt;em&gt;or&lt;/em&gt; names of image files &lt;em&gt;or&lt;/em&gt; file objects – because at different times, different ones will suit me. So all of the following are valid ways to copy multiple files from my memory card to the current directory (&lt;code&gt;$pwd&lt;/code&gt;), renaming, rotating and applying the keyword tag “oxfordshire”&lt;/p&gt;  &lt;p&gt;&lt;code&gt;PS[1]&amp;gt; Copy-Image E:\DCIM\100PENTX\img4422*.jpg -Destination $pwd `      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -Rotate -keywords &amp;quot;oxfordshire&amp;quot; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;       &lt;br /&gt;PS[2]&amp;gt; dir&amp;#160; E:\DCIM\100PENTX\img4422*.jpg | Copy-Image -Destination $pwd `       &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; -Rotate -keywords &amp;quot;oxfordshire&amp;quot; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;       &lt;br /&gt;PS[3]&amp;gt; get-image&amp;#160; E:\DCIM\100PENTX\img4422*.jpg | Copy-Image -Destination $pwd `       &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; -Rotate -keywords &amp;quot;oxfordshire&amp;quot;&amp;#160;&amp;#160; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;       &lt;br /&gt;PS[4]&amp;gt; $i = get-image&amp;#160; E:\DCIM\100PENTX\img4422*.jpg; Copy-Image $i -Destination $pwd `       &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; -Rotate -keywords &amp;quot;oxfordshire&amp;quot; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;       &lt;br /&gt;PS[5]&amp;gt; dir&amp;#160; E:\DCIM\100PENTX\img4422*.jpg | get-image |&amp;#160; Copy-Image -Destination $pwd `       &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; -Rotate -keywords &amp;quot;oxfordshire&amp;quot;&amp;#160; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot;&lt;/code&gt; &lt;/p&gt;  &lt;p&gt;Of course if I have the GPS data from taking the logger with me on a walk I can use Copy-GPSImage to geotag the files as they are copied, and in the next part I’ll look at how the GPS data is processed.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3342068" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="How to" scheme="http://blogs.technet.com/b/jamesone/archive/tags/How+to/" /><category term="Photography" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Photography/" /><category term="Powershell" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Powershell/" /></entry><entry><title>GPS, and other kinds of Picture tagging with PowerShell</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/07/01/gps-and-other-kinds-of-picture-tagging-with-powershell.aspx</id><published>2010-07-01T15:38:27Z</published><updated>2010-07-01T15:38:27Z</updated><content type="html">&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/4011.image_5F00_4.png"&gt;&lt;img style="display: inline" class="wlDisabledImage" title="image" alt="image" align="right" src="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/5100.image_5F00_thumb_5F00_1.png" width="128" height="185" /&gt;&lt;/a&gt;Well… I have been off for a bit and you can have a read of &lt;a href="http://blogs.technet.com/b/jamesone/archive/2010/05/02/i-aten-t-dead.aspx"&gt;the previous post&lt;/a&gt; for some background on that. During that time I’ve done a lot of walking, taking photos as I go.&amp;#160; Having raved about my HTC Touch pro 2 and its GPS I’ve been using it to GeoTag those photos. Naturally (for me) PowerShell figures in here somewhere. I’ve added to the image module in the &lt;a href="http://code.msdn.microsoft.com/PowerShellPack"&gt;Windows Powerpack&lt;/a&gt; that James Brundage wrote.&lt;strong&gt; It now takes data from a log and applies it to pictures.&lt;/strong&gt; It supports several log formats and incidental things I found I wanted to do with GPS data. And it is &lt;a href="http://code.msdn.microsoft.com/PSImage/"&gt;available for download&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I log my walks using &lt;a href="http://www.efficasoft.com/gpsutilities/index_wm_ppc.html"&gt;Efficasoft’s GPS&amp;#160; utilities&lt;/a&gt; (on the right). I have a picture of the logger to help with the first of the three PowerShell commands I need to use &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;u&gt;&lt;code&gt;Set-Offset&lt;/code&gt;&lt;/u&gt; works out the time difference between the time on the logger and time on the camera and stores it in &lt;code&gt;$offset&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;&lt;u&gt;&lt;code&gt;Get-CSVGPSData&lt;/code&gt;&lt;/u&gt; reads the GPS log from a CSV file, using &lt;code&gt;$offset&lt;/code&gt; to adjust the time so it matches the camera. I store the result in &lt;code&gt;$points&lt;/code&gt; and a successful import can be verified by looking at &lt;code&gt;$points.count&lt;/code&gt;. &lt;/li&gt;    &lt;li&gt;&lt;u&gt;&lt;code&gt;Copy-GpsImage&lt;/code&gt;&lt;/u&gt; copies pictures from a memory card to my computer renaming them, rotating them if need be, and tagging them using the GPS data I stored in &lt;code&gt;$points&lt;/code&gt; (if copying many files, it is useful to use &lt;code&gt;-verbose&lt;/code&gt; switch to see progress) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Steps 2 and 3 might be repeated to tag more than one set of photos provided the camera clock is a consistent interval away from “GPS time”. Here’s what a session looks like in PowerShell &lt;/p&gt;  &lt;hr /&gt;&lt;code&gt;&lt;strong&gt;PS &amp;gt; set-offset &amp;quot;D:\dcim \100Pentx\IMG43272.JPG&amp;quot; –Verbose&lt;/strong&gt;     &lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/4810.image_5F00_2.png"&gt;&lt;img style="display: inline" class="wlDisabledImage" title="Click for a Larger Version" alt="Click for a Larger Version" align="right" src="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/2604.image_5F00_thumb.png" width="357" height="342" /&gt;&lt;/a&gt;Please enter the Date &amp;amp; time in the reference picture, formatted as       &lt;br /&gt;Either MM/DD/yyyy HH:MM:SS ±Z or dd MMMM yyyy HH:mm:ss ±Z: &lt;b&gt;04/04/2010 16:02:17 +1        &lt;br /&gt;&lt;/b&gt;&lt;font color="#ccb400"&gt;VERBOSE: Loading file D:\dcim \100Pentx\IMG43272.JPG        &lt;br /&gt;VERBOSE: OffSet = 3607&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;PS&amp;gt; $points= Get-CSVGPSData 'F:\My Documents\My GPS\Track Log\20100425115503.log' ‑offset $offset        &lt;br /&gt;PS&amp;gt; $points.count         &lt;br /&gt;&lt;/strong&gt;593&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;PS&amp;gt; Dir E:\dcim –include *.jpg –recurse |        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Copy-GpsImage -Points $Points `         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -Keywords &amp;quot;Oxfordshire&amp;quot; `         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -DestPath &amp;quot;C:\users\jamesone\pictures\oxford&amp;quot; `         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -replace &amp;quot;IMG&amp;quot;,&amp;quot;OX-&amp;quot; `         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -verbose&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#d19049"&gt;VERBOSE: Loading file E:\dcim\100PENTX\IMG43624.JPG        &lt;br /&gt;VERBOSE: Checking 593 points for one where DateTime is closest to 04/25/2010 12:36:41         &lt;br /&gt;VERBOSE: Point 229 matched with variance of 2 seconds         &lt;br /&gt;VERBOSE: Performing operation &amp;quot;Write image&amp;quot; on Target &amp;quot; C:\users\jamesone\pictures\oxford\OX-43624&amp;quot;.&lt;/font&gt;&lt;/p&gt; &lt;/code&gt;  &lt;p&gt;In my case this will go through a stack of files, ending    &lt;br /&gt;&lt;code&gt;&lt;font color="#d19049"&gt;VERBOSE: Performing operation &amp;quot;Write image&amp;quot; on Target &amp;quot; C:\users\jamesone\pictures\oxford\OX-43757&amp;quot;&lt;/font&gt;&lt;/code&gt; &lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/5758.image_5F00_6.png"&gt;&lt;img style="display: inline" class="wlDisabledImage" title="image" alt="image" align="right" src="http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-49-74-metablogapi/4762.image_5F00_thumb_5F00_2.png" width="240" height="230" /&gt;&lt;/a&gt;The picture shows a detail from the Radcliffe Observatory building in Oxford (featured in a recent episode of &lt;i&gt;&lt;a href="http://www.imdb.com/title/tt1474296/"&gt;Lewis&lt;/a&gt;&lt;/i&gt;) with its GPS co-ordinates visible through File/Properties. I also wrote a little bit of code to push the data from the log though to MapPoint – this ended up as a function &lt;code&gt;Out-MapPoint&lt;/code&gt; although I later added a function named &lt;code&gt;convertTo-GPX&lt;/code&gt; which does the same job more quickly and also works with programs like GoogleEarth. &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;code&gt;$MPApp = New-Object -ComObject &amp;quot;Mappoint.Application&amp;quot;      &lt;br /&gt;$MPApp.Visible = $true       &lt;br /&gt;$map = $mpapp.ActiveMap       &lt;br /&gt;ForEach ($point in $points) {       &lt;br /&gt;&amp;#160;&amp;#160; $location=$map.GetLocation($point.Lat, $point.lon)       &lt;br /&gt;&amp;#160;&amp;#160; $Pin =$map.AddPushpin( $location, $point.datetime)       &lt;br /&gt;&amp;#160;&amp;#160; if ( $point.datetime -lt [datetime]&amp;quot;04/25/2010 12:12:00&amp;quot;){$pin.symbol= 6 }       &lt;br /&gt;&amp;#160;&amp;#160; else&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;&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;&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;&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; {$pin.symbol = 7}       &lt;br /&gt;}       &lt;br /&gt;&lt;/code&gt;The details behind this this take some explaining, so this will be the first of several parts: if you would like to know more have a look at the next few posts where I will drill into how it all works, but if you want to dive in and play the code is &lt;a href="http://code.msdn.microsoft.com/PSImage/"&gt;available for download&lt;/a&gt; now.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3341582" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Photography" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Photography/" /><category term="Powershell" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Powershell/" /></entry><entry><title>How to make and share Panoramas more easily – Microsoft ICE + Photosynth</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/03/22/how-to-make-and-share-panoramas-more-easily-microsoft-ice-photosynth.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/03/22/how-to-make-and-share-panoramas-more-easily-microsoft-ice-photosynth.aspx</id><published>2010-03-22T11:10:39Z</published><updated>2010-03-22T11:10:39Z</updated><content type="html">&lt;p&gt;I mentioned in &lt;a href="http://blogs.technet.com/jamesone/archive/2010/03/21/the-50th-birthday-that-would-have-been.aspx"&gt;yesterday’s post&lt;/a&gt; that I was working on a post about scanned images – in fact it’s the same set of scanned images I was using in &lt;a href="http://blogs.technet.com/jamesone/archive/2010/03/08/photographic-resolution-and-scans.aspx"&gt;this earlier post&lt;/a&gt;. In that post I talked about putting Panoramas into &lt;strong&gt;SilverLight Deep Zoom&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The teams behind Microsoft ICE* – (the Image Composite and Editing tool) and Photosynth have worked together so the newest version of ICE can upload its results into Photosynth: Photosynth is driven by deep zoom so &lt;strong&gt;I don’t have to any work&lt;/strong&gt; to get a shared, zoomable panorama, with Geotagging thrown in. This is not the only great new addition to ICE** it has support for mechanised capture devices which produce an ordered grid or as ICE terms it a &lt;em&gt;structured&lt;/em&gt; panorama. You can read more &lt;a href="http://hdview.spaces.live.com/blog/cns!1AD33AA162CE96C2!1383.entry?wa=wsignin1.0&amp;amp;sa=201310753"&gt;on the HDview blog&lt;/a&gt; and on the &lt;a href="http://blogs.msdn.com/photosynth/archive/2010/03/18/buttery-smooth-gigapixel-panoramas.aspx"&gt;Photosynth blog&lt;/a&gt; (Matt mentions that the ability to see Geotagged panoramas on the same map as Geotagged synths isn’t there yet, but is coming – and I’ve got another post in the pipeline about Geotagging photos) . &lt;/p&gt; &lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/JJoi_4G6up8&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/JJoi_4G6up8&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;p&gt;I put together a little video to show just how easy the process is (if the embedded video doesn’t work properly, you can view it in its &lt;a href="http://www.youtube.com/watch?v=JJoi_4G6up8"&gt;original location&lt;/a&gt;) - at 1280x720 resolution it doesn’t really do Photosyth’s viewer justice.&amp;#160; You can click the version below and hit the button on the right for the full screen view to see just why I like it so much. I have a couple more panoramas which I will rebuild and upload. &lt;/p&gt; &lt;iframe height="300" src="http://photosynth.net/embed.aspx?cid=e8165776-64e5-4ed1-bdd1-2578071108ab&amp;amp;delayLoad=true&amp;amp;slideShowPlaying=false" frameborder="0" width="500"&gt;&lt;/iframe&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;* Should I proud of myself for not making any contrived “ICEmen” jokes ?    &lt;br /&gt;** I could have said cool new thing in ICE . &lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px; padding:0px 0px 0px 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;
tweetmeme_style = 'compact';
tweetmeme_url = 'http://blogs.technet.com/jamesone/archive/2010/03/22/how-to-make-and-share-panoramas-more-easily-microsoft-ice-photosynth.aspx';
&lt;/script&gt;
&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3320436" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>The 50th birthday that would have been</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/03/21/the-50th-birthday-that-would-have-been.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/03/21/the-50th-birthday-that-would-have-been.aspx</id><published>2010-03-21T13:42:35Z</published><updated>2010-03-21T13:42:35Z</updated><content type="html">&lt;p&gt;If you believe in the parallel universes then there are ones where Ayrton Senna is celebrating his 50th birthday today, having won 6, 7 or 8 world championships.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/blogfiles/jamesone/WindowsLiveWriter/89fc3d7d46ad_AAF1/GP91-23_2.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="Senna and Mansell - click for a bigger version" alt="Senna and Mansell - click for a bigger version" align="left" src="http://blogs.technet.com/blogfiles/jamesone/WindowsLiveWriter/89fc3d7d46ad_AAF1/GP91-23_thumb.jpg" width="251" height="179" /&gt;&lt;/a&gt;In this one, the 50th anniversary of his birth is marked a more sombrely. It’s not quite 16 years since he died with 3 championships to his name and last week when his nephew flipped open the visor on a very similarly patterned helmet to reveal very similar looking eyes I felt like I had seen a ghost – and heard Martin Brundle articulate the same thought on his TV commentary. I said &lt;a href="http://blogs.technet.com/jamesone/archive/2009/05/01/f1-thoughts.aspx"&gt;pretty much all I wanted to about Ayrton on fifteenth anniversary&amp;#160; of his death&lt;/a&gt;. But since I’ve posted recently about scanning pictures and I have another post in draft about that , I thought I’d share a couple of successful scans. &lt;/p&gt;  &lt;p&gt;In 1991 Senna looked like he was going successfully defend the title he won in 1990 – he won the first 3 races before Nigel Mansell had got a finish, and he wasn’t even the leading Williams driver until 7th race. The 8th was the British Grand Prix, and I was there. To cap a perfect day for Mansell and a partisan crowd, Senna ran out of fuel on the last lap. Mansell on his victory lap stopped and gave his adversary a lift back to the pits. In this picture you can see how much more exposed the drivers heads were in those days – which was to be the death of Senna in another Williams, 3 years later. Riding back like that is forbidden now, and that too speaks of the attitudes to safety. But it says something to me about the nature of sport that drivers could fight for everything on the track, yet offer help and not be humiliated by accepting it. &lt;a href="http://blogs.technet.com/blogfiles/jamesone/WindowsLiveWriter/89fc3d7d46ad_AAF1/GP91-035A_2.jpg"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" title="Senna at Silverstone" alt="Senna at Silverstone" align="right" src="http://blogs.technet.com/blogfiles/jamesone/WindowsLiveWriter/89fc3d7d46ad_AAF1/GP91-035A_thumb.jpg" width="250" height="173" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The cheap film, second-rate lenses and my own technique limit how good the scan of the photo can be – but I hope the story explains why I treasure it. Far better from a technical point of view is this second picture – but sometimes the technical quality isn’t what matters.&lt;/p&gt;  &lt;p&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;To mark the anniversary, Autosport have a page &lt;a href="http://www.autosport.com/news/report.php/id/82279"&gt;Ayrton Senna: A life in pictures&lt;/a&gt; – they are arranged with the oldest at the bottom – you can see his first F1 test (in a Williams), another shot of the ride home with Mansell in the middle and on the left of the top row is quite a poor shot – you can’t tell what it is from the thumbnail. It’s the back of the car, and I generally don’t keep those. The caption reads “Ayrton Senna, Williams FW16 Renault; 1994 San Marino Grand Prix at Imola.”&amp;#160; And then slowly it dawns that the wall and trees in the background mean the car is going into the corner named Tamburello and there’s a big gap to car behind, so this must be the sixth lap – a few seconds after this shot was taken the right front wheel of FW16 hit the wall a little further down than we can see in the shot, and parted company from the car. On another day or in another universe it would have passed harmlessly by, but it didn’t and that picture – like the lift home one – captures what we now know to be a decisive moment. &lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px; padding:0px 0px 0px 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;
tweetmeme_style = 'compact';
tweetmeme_url = 'http://blogs.technet.com/jamesone/archive/2010/03/21/the-50th-birthday-that-would-have-been.aspx';
&lt;/script&gt;
&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3320322" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Photography" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Photography/" /></entry><entry><title>Virtualization announcements today.</title><link rel="alternate" type="text/html" href="http://blogs.technet.com/b/jamesone/archive/2010/03/18/virtualization-announcements-today.aspx" /><id>http://blogs.technet.com/b/jamesone/archive/2010/03/18/virtualization-announcements-today.aspx</id><published>2010-03-18T16:23:22Z</published><updated>2010-03-18T16:23:22Z</updated><content type="html">&lt;p&gt;In another window I am listening to the desktop Virtualization hour which I blogged about yesterday. A couple of hours ahead of the broadcast we posted the &lt;a href="http://bit.ly/dsS5gO"&gt;press release on Press pass&lt;/a&gt; which contained the following detail of what we are announcing today. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;• New VDI promotions available for qualified customers to choose from today. Microsoft and Citrix Systems are offering the &lt;strong&gt;“Rescue for VMware VDI” promotion&lt;/strong&gt;, which allows VMware View customers to trade in up to 500 licenses at no additional cost, and the &lt;strong&gt;“VDI Kick Start” promotion&lt;/strong&gt;, which offers new customers a more than 50 percent discount off the estimated retail price. Eligibility and other details on the two promotions can be found at &lt;/em&gt;&lt;a href="http://www.citrixandmicrosoft.com"&gt;&lt;strong&gt;&lt;em&gt;http://www.citrixandmicrosoft.com&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;em&gt;. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;• Improved licensing model for virtual Windows desktop. Beginning July 1, 2010, Windows Client Software Assurance &lt;strong&gt;customers will no longer have to buy a separate license to access their Windows operating system in a VDI environment&lt;/strong&gt;, as virtual desktop access rights now will be a Software Assurance benefit. &lt;/em&gt;[Note the new name VDA is what we used to call VECD.] &lt;/p&gt;  &lt;p&gt;&lt;em&gt;• New roaming use rights improve flexibility. Beginning July 1, 2010, Windows Client Software Assurance and new Virtual Desktop Access license customers will have the right to access their virtual Windows desktop and their Microsoft Office applications hosted on VDI technology on secondary, non-corporate network devices, such as home PCs and kiosks.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;• &lt;strong&gt;Windows XP Mode no longer requires hardware virtualization technology.&lt;/strong&gt; This change simplifies the experience by making virtualization more accessible to many more PCs for small and midsize businesses wanting to migrate to Windows 7 Professional or higher editions, while still running Windows XP-based productivity applications. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;• Two &lt;strong&gt;new features coming in Windows Server 2008 R2 service pack 1&lt;/strong&gt;. Microsoft &lt;strong&gt;Dynamic Memory &lt;/strong&gt;will allow customers to adjust memory of a guest virtual machine on demand to maximize server hardware use. &lt;strong&gt;Microsoft RemoteFX&lt;/strong&gt; will enable users of virtual desktops and applications to receive a rich 3-D, multimedia experience while accessing information remotely. &lt;/em&gt;[Note the new name RemoteFx is the technology we acquired with the purchase of Calista.] &lt;/p&gt;  &lt;p&gt;• &lt;strong&gt;New technology agreement with Citrix Systems&lt;/strong&gt;. The companies will work together to enable the high-definition &lt;a href="http://hdx.citrix.com/hdxrichgraphics"&gt;HDX technology&lt;/a&gt; in Citrix XenDesktop to enhance and extend the capabilities of the Microsoft RemoteFX platform.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Good stuff all round, but from a technical viewpoint it’s the new bits in SP1 which will get the attention. I’ll post a little more on what Dynamic memory is and is not in the next day or two. &lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px; padding:0px 0px 0px 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;
tweetmeme_style = 'compact';
tweetmeme_url = 'http://blogs.technet.com/jamesone/archive/2010/03/18/virtualization-announcements-today.aspx';
&lt;/script&gt;
&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3319875" width="1" height="1"&gt;</content><author><name>James ONeill</name><uri>http://blogs.technet.com/jamesone/ProfileUrlRedirect.ashx</uri></author><category term="Virtualization" scheme="http://blogs.technet.com/b/jamesone/archive/tags/Virtualization/" /></entry></feed>