<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Speaking of which...</title><link>http://blogs.msdn.com/b/johan/</link><description>Sample solutions from Internet development support</description><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.19849 (Build: 5.6.583.19849)</generator><item><title>Changing file dates and other more uncommon properties in PowerShell</title><link>http://blogs.msdn.com/b/johan/archive/2011/12/29/changing-file-dates-and-other-more-uncommon-properties-in-powershell.aspx</link><pubDate>Thu, 29 Dec 2011 15:17:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251760</guid><dc:creator>JohanSt</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=10251760</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2011/12/29/changing-file-dates-and-other-more-uncommon-properties-in-powershell.aspx#comments</comments><description>&lt;p&gt;There are some file properties that aren’t too easy to change. Neither in the command line or in Windows Explorer. One that I’ve wanted to change personally quite often is the created and changed dates of a specific file, or a batch of files.&lt;/p&gt;  &lt;h1&gt;Background&lt;/h1&gt;  &lt;p&gt;I frequently use my Windows Phone (currently a Nokia Lumia 800) for listening to audio books. I’ve found that the best way to do so is to change the category of the files to “podcast” and they’ll show up as podcasts and I won’t have to keep track of where I was, etc. since Zune will do that for me. Zune uses the creation date to order the files in a podcast, and some times the creation dates of my files may not be entirely correct. There are a lot of shareware programs that will allow you to do batch updates on files and change these properties, but it’s actually a lot easier to do it yourself in PowerShell&lt;/p&gt;  &lt;h1&gt;How to fix this&lt;/h1&gt;  &lt;p&gt;If you have the files sorted the way you want alphabetically and want to order them by creation date in the same way, then this is a pretty easy way to do it.&lt;/p&gt;  &lt;div class="SampleCode"&gt;$files = dir    &lt;br /&gt;for($i=0;$i -le $files.GetUpperBound(0); $i++)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160; ($files[$i]).CreationTime = (get-date).AddSeconds($i)     &lt;br /&gt;&amp;#160;&amp;#160; ($files[$i]).LastWriteTime = (get-date).AddSeconds($i)     &lt;br /&gt;}     &lt;br /&gt;&lt;/div&gt;  &lt;p&gt;Naturally you could alter other properties as well simply pass one of the objects into get-method to see what’s available:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Name&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; MemberType&amp;#160;&amp;#160;&amp;#160;&amp;#160; Definition    &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; ----------     &lt;br /&gt;Mode&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; CodeProperty&amp;#160;&amp;#160; System.String Mode{get=Mode;}     &lt;br /&gt;Create&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void Create(System.Security.AccessControl.DirectorySecurity director...     &lt;br /&gt;CreateObjRef&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)     &lt;br /&gt;CreateSubdirectory&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.DirectoryInfo CreateSubdirectory(string path), System.IO.Director...     &lt;br /&gt;Delete&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void Delete(), System.Void Delete(bool recursive)     &lt;br /&gt;Equals&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bool Equals(System.Object obj)     &lt;br /&gt;GetAccessControl&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Security.AccessControl.DirectorySecurity GetAccessControl(), System....     &lt;br /&gt;GetDirectories&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.DirectoryInfo[] GetDirectories(string searchPattern), System.IO.D...     &lt;br /&gt;GetFiles&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.FileInfo[] GetFiles(string searchPattern), System.IO.FileInfo[] G...     &lt;br /&gt;GetFileSystemInfos&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.FileSystemInfo[] GetFileSystemInfos(string searchPattern), System...     &lt;br /&gt;GetHashCode&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int GetHashCode()     &lt;br /&gt;GetLifetimeService&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Object GetLifetimeService()     &lt;br /&gt;GetObjectData&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo in...     &lt;br /&gt;GetType&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; type GetType()     &lt;br /&gt;InitializeLifetimeService Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Object InitializeLifetimeService()     &lt;br /&gt;MoveTo&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void MoveTo(string destDirName)     &lt;br /&gt;Refresh&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void Refresh()     &lt;br /&gt;SetAccessControl&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Void SetAccessControl(System.Security.AccessControl.DirectorySecurit...     &lt;br /&gt;ToString&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; Method&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string ToString()     &lt;br /&gt;PSChildName&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; NoteProperty&amp;#160;&amp;#160; System.String PSChildName=.gimp-2.6     &lt;br /&gt;PSDrive&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; NoteProperty&amp;#160;&amp;#160; System.Management.Automation.PSDriveInfo PSDrive=C     &lt;br /&gt;PSIsContainer&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NoteProperty&amp;#160;&amp;#160; System.Boolean PSIsContainer=True     &lt;br /&gt;PSParentPath&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; NoteProperty&amp;#160;&amp;#160; System.String PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\j...     &lt;br /&gt;PSPath&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; NoteProperty&amp;#160;&amp;#160; System.String PSPath=Microsoft.PowerShell.Core\FileSystem::C:\Users\jstraar...     &lt;br /&gt;PSProvider&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; NoteProperty&amp;#160;&amp;#160; System.Management.Automation.ProviderInfo PSProvider=Microsoft.PowerShell.C...     &lt;br /&gt;Attributes&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.FileAttributes Attributes {get;set;}     &lt;br /&gt;CreationTime&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime CreationTime {get;set;}     &lt;br /&gt;CreationTimeUtc&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime CreationTimeUtc {get;set;}     &lt;br /&gt;Exists&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Boolean Exists {get;}     &lt;br /&gt;Extension&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.String Extension {get;}     &lt;br /&gt;FullName&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.String FullName {get;}     &lt;br /&gt;LastAccessTime&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime LastAccessTime {get;set;}     &lt;br /&gt;LastAccessTimeUtc&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime LastAccessTimeUtc {get;set;}     &lt;br /&gt;LastWriteTime&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime LastWriteTime {get;set;}     &lt;br /&gt;LastWriteTimeUtc&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.DateTime LastWriteTimeUtc {get;set;}     &lt;br /&gt;Name&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.String Name {get;}     &lt;br /&gt;Parent&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.DirectoryInfo Parent {get;}     &lt;br /&gt;Root&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; Property&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.DirectoryInfo Root {get;}     &lt;br /&gt;BaseName&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; ScriptProperty System.Object BaseName {get=$this.Name;}&lt;/div&gt;  &lt;p&gt;Well, that’s basically it. Enjoy!&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251760" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Tools/">Tools</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Off+topic/">Off topic</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Automation/">Automation</category></item><item><title>System.Text.EncoderExceptionFallback</title><link>http://blogs.msdn.com/b/johan/archive/2011/12/01/system-text-encoderexceptionfallback.aspx</link><pubDate>Thu, 01 Dec 2011 13:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10243324</guid><dc:creator>JohanSt</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=10243324</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2011/12/01/system-text-encoderexceptionfallback.aspx#comments</comments><description>&lt;p&gt;Today I found the following e-mail in my inbox:&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #808080;"&gt;&lt;em&gt;Hello According to this article, &lt;span style="color: #3366ff;"&gt;&lt;a href="http://blogs.msdn.com/b/johan/archive/2008/01/31/using-windbg-hunting-exceptions.aspx"&gt;&lt;span style="color: #3366ff;"&gt;http://blogs.msdn.com/b/johan/archive/2008/01/31/using-windbg-hunting-exceptions.aspx&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; written by you, you write that there are three "ever-present exceptions", I can see why they have to be on the heap, but why is 790ff624 3 36 System.Text.DecoderExceptionFallback 790ff5d8 3 36 System.Text.EncoderExceptionFallback Also always there? I always see them on the heep when I do a debug session. I have always discarded them. According to Tess, they are "not real exceptions", refering to that a print of all exceptions on the heap throws an error when the are printed. I think that the are put on the heap when the process is created, like the other three. But why? Why are they so important? I DEMAND an answer, because I love you and your blog :) I am just joking. I have written to you because I think that you know your ways around the CLR and the heap.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I thought the answer might interest others as well, so I decided to answer the e-mail here.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h1&gt;This is not an Exception&lt;/h1&gt;
&lt;p&gt;The reason why these are on the heap and are not possible to examine using !PrintException (!pe) is because they&amp;rsquo;re actually not Exceptions at all. They show up when you run !dumpheap -type Exception because they contain the word &amp;ldquo;Exception&amp;rdquo; in their name, but that&amp;rsquo;s it. The System.Text.DecoderExceptionFallback object for example derives from the DecoderFallback object. It&amp;rsquo;s a fail-safe mechanism that is used when you can&amp;rsquo;t class that is used then you can&amp;rsquo;t complete the decoding conversion.&lt;/p&gt;
&lt;h2&gt;So what is a Decoder Fallback?&lt;/h2&gt;
&lt;p&gt;There are different fallbacks you can use. You can use the DecoderReplacementFallback that will replace any byte sequence that it can&amp;rsquo;t decode with a predefined string. For example; the decoder comes across a segment it can&amp;rsquo;t convert. You&amp;rsquo;ve defined a DecoderReplacementFallback and it replaces the segment with &amp;ldquo;[unknown]&amp;rdquo;. Execution will then continue.&lt;/p&gt;
&lt;p&gt;If you had instead defined a DecoderExceptionFallback a DecoderFallbackException (notice the difference?) would be thrown when the decoder came across the segment that it couldn&amp;rsquo;t convert and execution would stop after that.&lt;/p&gt;
&lt;p&gt;Cheers! / Johan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10243324" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Encoding/">Encoding</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Exceptions/">Exceptions</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Debugging+School/">Debugging School</category></item><item><title>Changing Site Settings through code in SharePoint 2010</title><link>http://blogs.msdn.com/b/johan/archive/2011/09/13/changing-site-settings-through-code-in-sharepoint-2010.aspx</link><pubDate>Tue, 13 Sep 2011 13:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10209886</guid><dc:creator>JohanSt</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=10209886</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2011/09/13/changing-site-settings-through-code-in-sharepoint-2010.aspx#comments</comments><description>&lt;p&gt;It&amp;rsquo;s been quite a while since I had the time to post. A customer dropped me this question today and I thought it&amp;rsquo;d be interesting to share.&lt;/p&gt;
&lt;p&gt;He wanted to change the &amp;ldquo;Allow rules to specify another site as a target location&amp;rdquo;-setting (seen below) through code and needed to know if this could be done. &lt;br /&gt;I hadn&amp;rsquo;t tried this before, but thought it&amp;rsquo;d be fun to try.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-75-43-metablogapi/2210.Setting_5F00_7108B5AF.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="Setting" border="0" alt="Setting" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-75-43-metablogapi/8547.Setting_5F00_thumb_5F00_6185A3E0.png" width="703" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Finding the correct key&lt;/h2&gt;
&lt;p&gt;I suspected that the property could be found in Web.AllProperties, but I had no clue as to what the key might be called, so I simply iterated through all the keys twice. First with the setting enabled and secondly with the setting disabled. I wrote the keys to a label, and simply pasted them into Notepad so I could compare the two listings. The code I used to do this was quite simple:&lt;/p&gt;
&lt;pre&gt;foreach (String key in Web.AllProperties.Keys)
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lblKeys.Text += key + "&amp;lt;BR&amp;gt;";
}&lt;/pre&gt;
&lt;p&gt;Having done this it was quite easy to identify the key I needed. It turned out it was called &amp;ldquo;_routerenablecrosssiterouting&amp;rdquo;. I recommend using the same approach if there is another setting you wish to change.&lt;/p&gt;
&lt;h2&gt;The final code&lt;/h2&gt;
&lt;p&gt;Now that I had the key name I was basically done. I used the following line to read the setting:&lt;/p&gt;
&lt;pre&gt;myString = (Web.AllProperties["_routerenablecrosssiterouting"]).ToString();&lt;/pre&gt;
&lt;p&gt;This is the code I used to change it:&lt;/p&gt;
&lt;pre&gt;Web.AllowUnsafeUpdates = true;
Web.AllProperties["_routerenablecrosssiterouting"] = "False";
Web.Update();&lt;/pre&gt;
&lt;p&gt;Since I was using a GET-request in my little sample I had to set AllowUnsafeUpdates = true&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve seen other people asking how to accomplish this on the net, so hopefully this post will be of use to you.&lt;/p&gt;
&lt;p&gt;/ Johan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10209886" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/SharePoint/">SharePoint</category></item><item><title>Problems running sos-commands</title><link>http://blogs.msdn.com/b/johan/archive/2011/03/04/problems-running-sos-commands.aspx</link><pubDate>Fri, 04 Mar 2011 10:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136853</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=10136853</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2011/03/04/problems-running-sos-commands.aspx#comments</comments><description>&lt;p&gt;Yesterday I tried opening up a standard dump file from a 64-bit Windows 2008 Server. It opened up just fine in windbg, but when I tried executing a command I got the following:&lt;/p&gt;
&lt;div class="SampleCode"&gt;
&lt;pre&gt;0:000&amp;gt; !dumpheap -stat
The garbage collector data structures are not in a valid state for traversal.
It is either in the "plan phase," where objects are being moved around, or
we are at the initialization or shutdown of the gc heap. Commands related to 
displaying, finding or traversing objects as well as gc heap segments may not 
work properly. !dumpheap and !verifyheap may incorrectly complain of heap 
consistency errors.
Error requesting GC Heap data
Unable to build snapshot of the garbage collector state&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This can happen if both the .NET 4.0 and the .NET 2.0 runtime are loaded in the same process. I actually tried using .loadby on both Framework versions and neither of them returned with an error&lt;/p&gt;
&lt;div class="SampleCode"&gt;
&lt;pre&gt;0:000&amp;gt; .loadby sos mscorwks
0:000&amp;gt; .loadby sos clr&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The easiest way to resolve this is to run the following command:&lt;/p&gt;
&lt;div class="SampleCode"&gt;
&lt;pre&gt;0:000&amp;gt; .cordll -I mscorwks.dll -N -ve&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;After that, simply reload the extensions you want to use and you should be fine.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136853" width="1" height="1"&gt;</description></item><item><title>Updating the Smart tag panel of a WebControl requires closing and reopening the panel</title><link>http://blogs.msdn.com/b/johan/archive/2010/09/02/updating-the-smart-tag-panel-of-a-webcontrol-requires-closing-and-reopening-the-panel.aspx</link><pubDate>Thu, 02 Sep 2010 08:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10057159</guid><dc:creator>JohanSt</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=10057159</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2010/09/02/updating-the-smart-tag-panel-of-a-webcontrol-requires-closing-and-reopening-the-panel.aspx#comments</comments><description>&lt;h1&gt;&lt;/h1&gt;
&lt;h1&gt;The problem&lt;/h1&gt;
&lt;p&gt;I came across the following scenario a while back: A customer was creating a custom WebControl in the Visual Web Designer. The control had a smart tag panel with an option that they wanted to behave like a radio button. I.e. The text says &amp;ldquo;Enabled&amp;rdquo;, you click it and it changes to &amp;ldquo;Disabled&amp;rdquo;. The problem was that the panel didn&amp;rsquo;t refresh. Even if they called DesignerActionUIService.Refresh(). They had to close the panel and reopen it for the change to become visible.&lt;/p&gt;
&lt;p&gt;If they instead hosted the same code in a WinForms control then the panel was refreshed immediately. So in effect the code below would update immediately if designing a WinForms component, and require closing and reopening the panel if designing a WebForms panel.&lt;/p&gt;
&lt;div class="SampleCode"&gt;
&lt;pre&gt;public bool LockColors
{
    get
    {
        return colLabel.ColorLocked;
    }
    set
    {
        GetPropertyByName("ColorLocked").SetValue(colLabel, value);

        // Refresh the list.
        this.designerActionUISvc.Refresh(this.Component);
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;h1&gt;Cause&lt;/h1&gt;
&lt;p&gt;Simply put, the Web Developer doesn&amp;rsquo;t subscribe to the DesignerActionUIStateChange event, so this is currently by design.&lt;/p&gt;
&lt;h1&gt;Resolution&lt;/h1&gt;
&lt;p&gt;You can fix this by implementing your own event using code like this:&lt;/p&gt;
&lt;div class="SampleCode"&gt;
&lt;pre&gt;public UserControlDesignerActionList(ISourceControlledItem scItem)
        : base(((IDesigner)scItem).Component)
    {
        this.designerActionUISvc = GetService(typeof(DesignerActionUIService))
as DesignerActionUIService;
 
        if (this.Component is Control) {
            this.designerActionUISvc.DesignerActionUIStateChange += 
new DesignerActionUIStateChangeEventHandler(OnDesignerActionUIStateChange);
        }
    }
 
    void OnDesignerActionUIStateChange(object sender, DesignerActionUIStateChangeEventArgs e) {
        if (e.ChangeType == DesignerActionUIStateChangeType.Refresh) {
            ElementDesigner ed = ElementDesigner.GetElementDesigner((Control)this.Component);
            IWebElementDesigner wed = (IWebElementDesigner)ed;
            if (wed != null) {
                wed.UpdateView();
            }
        }
    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In order for this to work you need to add a reference to Microsoft.Web.Design.Client.dll, which is located at C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\Microsoft.Web.Design.Client.dll as well as in the Global Assembly Cache.&lt;/p&gt;
&lt;h1&gt;Licensing&lt;/h1&gt;
&lt;p&gt;The main issue with this approach is that of licencing. If you intend to redistribute this component to a customer you may redistribute the .dll to that customer if they already own a valid license of that same .dll. Any component you design that need this change to work would require a copy of Visual Studio to be at all usefull, but you never know...&lt;/p&gt;
&lt;p&gt;The best approach would probably be to rely on the version in the GAC and not distribute the .dll at all.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10057159" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Visual+Studio/">Visual Studio</category></item><item><title>Using SSL without an Internet connection</title><link>http://blogs.msdn.com/b/johan/archive/2010/02/02/using-ssl-without-an-internet-connection.aspx</link><pubDate>Tue, 02 Feb 2010 12:39:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9956912</guid><dc:creator>JohanSt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9956912</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2010/02/02/using-ssl-without-an-internet-connection.aspx#comments</comments><description>&lt;h1&gt;Problem&lt;/h1&gt;  &lt;p&gt;If you have a web application that uses SSL and this application, for some reason, is hosted on an IIS that doesn’t have Internet access you will eventually find that any call to the server over SSL will take a lot of time to reply. It doesn’t matter if it’s ASP.NET, classic ASP or even CSS. As long as the request is made via SSL the response-time will skyrocket.&lt;/p&gt;  &lt;p&gt;This isn’t a very common situation, since normally the IIS is connected to the Internet. HoweverI’ve come across this “in the field” where clients were routed internally to the IIS through a proxy, so it &lt;em&gt;does&lt;/em&gt; happen.&lt;/p&gt;  &lt;h1&gt;Cause&lt;/h1&gt;  &lt;p&gt;This is a variation of the problem described in &lt;a href="http://blogs.msdn.com/johan/archive/2009/11/12/make-sure-you-have-an-internet-connection-when-using-signed-assemblies.aspx"&gt;this&lt;/a&gt; article. The IIS will want to go on-line and verify that the certificate has not been revoked. In order to do this is requires a working Internet connection. Otherwise it will wait until the request times out and then service the request. When the next SSL-request comes along it will attempt to go on-line again, time out, and so on.&lt;/p&gt;  &lt;p&gt;If you've had your server connected to the Internet during testing, then you will most likely not come across this problem straight away, since the response from the lookup in the certificate revocation list (CRL) will be cached. This makes it harder to pinpoint the root cause, unless you know where to look.&lt;/p&gt;  &lt;h1&gt;Resolution&lt;/h1&gt;  &lt;p&gt;The easiest way to resolve this is to skip CRL checking. This is done by setting the metabase property &lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0c08d268-1634-4486-8382-b735e295b3aa.mspx?mfr=true"&gt;CertCheckMode&lt;/a&gt; to 1.&lt;/p&gt;  &lt;p&gt;Create a blank .txt file on the server and paste the following code into it:&lt;/p&gt;  &lt;div class="SampleCode"&gt;   &lt;pre&gt;Set oWeb = GetObject(&amp;quot;IIS://localhost/W3SVC&amp;quot;)
oWeb.CertCheckMode = 1
oWeb.SetInfo
Set oWeb = Nothing&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Running this script will change the property so that revocation checking is no longer done. If you want to switch back to the default value, then you should set CertCheckMode to 0 instead.&lt;/p&gt;

&lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9956912" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Performance/">Performance</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/SSL/">SSL</category></item><item><title>Make sure you have an Internet connection when using signed assemblies</title><link>http://blogs.msdn.com/b/johan/archive/2009/11/12/make-sure-you-have-an-internet-connection-when-using-signed-assemblies.aspx</link><pubDate>Thu, 12 Nov 2009 11:08:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9921295</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9921295</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/11/12/make-sure-you-have-an-internet-connection-when-using-signed-assemblies.aspx#comments</comments><description>&lt;p&gt;A customer called in the other day and told me that his web application took a long time to start. My initial thought was (off course) that it was a matter of the classic slow-to start web services I’ve written about earlier.&lt;/p&gt;  &lt;p&gt;(&lt;a title="What to do about the slow startup of web services" href="http://blogs.msdn.com/johan/archive/2008/04/02/what-to-do-about-the-slow-startup-of-web-services.aspx"&gt;What to do about the slow startup of web services&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;As I learned more about his problem I found that this was more than just a simple matter of pre-compilation and keeping your w3wp.exe alive.&lt;/p&gt;  &lt;h1&gt;The Cause&lt;/h1&gt;  &lt;p&gt;The customer was using authenticode signed assemblies in his web application. When that application calls the assembly for the first time it will want to go on-line and check that the certificate is still valid. So, what if this is an internal server with no Internet access? Well, then we have a problem. The process will spend quite some time trying to check the certificate revocation lists. Eventually it will give up, but for my customer this meant that it hung for at least 20 seconds upon startup.&lt;/p&gt;  &lt;h1&gt;The Resolution&lt;/h1&gt;  &lt;p&gt;To resolve this I’d chose one of the following three options:&lt;/p&gt;  &lt;h3&gt;Grant Internet access to the server&lt;/h3&gt;  &lt;p&gt;This is will obviously resolve the problem, but may not always be possible.&lt;/p&gt;  &lt;h3&gt;Review the need for Authenticode signing&lt;/h3&gt;  &lt;p&gt;If you own the assemblies then you might want to consider not using Authenticode signing at all. A Strong Named Assembly might be sufficient. For more information on Strong Named Assemblies and how to create them, please see the following article on MSDN: &lt;a title="How to- Sign an Assembly with a Strong Name" href="http://msdn.microsoft.com/en-us/library/xc31ft41.aspx" target="_blank"&gt;How to: Sign an Assembly with a Strong Name&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Disable Signature Verification&lt;/h3&gt;  &lt;p&gt;If all else fails you can disable Signature Verification by adding the following to your machine.config or application.exe.config:&lt;/p&gt;  &lt;div class="SampleCode"&gt;&amp;lt;configuration&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;runtime&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;generatepublisherevidence enabled=&amp;quot;false&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/runtime&amp;gt;     &lt;br /&gt;&amp;lt;/configuration&amp;gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h1&gt;Identifying the problem using windbg&lt;/h1&gt;  &lt;p&gt;Okay, so if we suspect that this is the problem, how can we verify this?&lt;/p&gt;  &lt;p&gt;I got a memory dump from my customer, so I’ll use that to demonstrate.&lt;/p&gt;  &lt;p&gt;First of all you want to make sure the dump is taken as the application pool hangs upon the first request. Getting a dump right after the problem has occurred will usually do us no good at all. We need to get the dump as the problem is actually ocurring. Having made sure the dump is fine I open up the dump in windbg and load sos.dll. I then use the !aspxpages command to see the pending requests currently on the server. !aspxpages dumps all the HttpContexts found on the heap so we get a list of all currently executing requests, as well as recently finished ones that haven’t been garbage collected yet.&lt;/p&gt;  &lt;div class="DebugSample"&gt;0:000&amp;gt; .load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll    &lt;br /&gt;0:000&amp;gt; !aspxpages     &lt;br /&gt;Going to dump the HttpContexts found in the heap.     &lt;br /&gt;Loading the heap objects into our cache.     &lt;br /&gt;HttpContext&amp;#160;&amp;#160;&amp;#160; Timeout&amp;#160; Completed&amp;#160;&amp;#160;&amp;#160;&amp;#160; Running&amp;#160; ThreadId ReturnCode&amp;#160;&amp;#160; Verb RequestPath+QueryString     &lt;br /&gt;0x01b41ad4&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; no&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 11 Sec&amp;#160;&amp;#160;&amp;#160;&amp;#160; XXX&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 200&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; /App/     &lt;br /&gt;0x01b75f48&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 110 Sec&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; no&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 11 Sec&amp;#160;&amp;#160;&amp;#160;&amp;#160; XXX&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 401&amp;#160;&amp;#160; GET /App/Default.aspx     &lt;br /&gt;0x01b7eb40&amp;#160;&amp;#160;&amp;#160; 19200 Sec&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; no&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 11 Sec&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#ff0000"&gt;19&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 200&amp;#160;&amp;#160; GET /App/Default.aspx     &lt;br /&gt;Total 3 HttpContext objects &lt;/div&gt;  &lt;p&gt;So, the request on thread 19 is the one we want. As we can see in the ThreadId column it is the only active request. Let’s jump to that thread and investigate what it is doing.&lt;/p&gt;  &lt;div class="DebugSample"&gt;0:000&amp;gt; ~19s    &lt;br /&gt;eax=01510000 ebx=00000000 ecx=03e2d348 edx=776d9a94 esi=03e2d07c edi=00000000     &lt;br /&gt;eip=776d9a94 esp=03e2d034 ebp=03e2d0a4 iopl=0&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nv up ei ng nz ac pe cy     &lt;br /&gt;cs=001b&amp;#160; ss=0023&amp;#160; ds=0023&amp;#160; es=0023&amp;#160; fs=003b&amp;#160; gs=0000&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; efl=00000297     &lt;br /&gt;ntdll!KiFastSystemCallRet:     &lt;br /&gt;776d9a94 c3&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; ret     &lt;br /&gt;0:019&amp;gt; !clrstack     &lt;br /&gt;OS Thread Id: 0x11cc (19)     &lt;br /&gt;ESP&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EIP&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;03e2eb8c 776d9a94 [PrestubMethodFrame: 03e2eb8c] App.BasePage.&lt;font color="#ff0000"&gt;Page_Load&lt;/font&gt;(System.Object, System.EventArgs)     &lt;br /&gt;03e2eba0 6aada7ff System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)     &lt;br /&gt;03e2ebb0 6c392594 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)     &lt;br /&gt;03e2ebc4 6c38ba84 System.Web.UI.Control.OnLoad(System.EventArgs)     &lt;br /&gt;03e2ebd8 6c38bac3 System.Web.UI.Control.LoadRecursive()     &lt;br /&gt;03e2ebf0 6c387b74 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)     &lt;br /&gt;03e2ed48 6c3877a4 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)     &lt;br /&gt;03e2ed80 6c3876d1 System.Web.UI.Page.ProcessRequest()     &lt;br /&gt;03e2edb8 6c387666 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)     &lt;br /&gt;03e2edc4 6c387642 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)     &lt;br /&gt;03e2edd8 012b02a6 ASP.text.ProcessRequest(System.Web.HttpContext)     &lt;br /&gt;03e2ede8 6c38db16 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()     &lt;br /&gt;03e2ee1c 6c36132c System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)     &lt;br /&gt;03e2ee5c 6c95531f System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)     &lt;br /&gt;03e2ee60 6c94b704 [InlinedCallFrame: 03e2ee60]     &lt;br /&gt;03e2ef00 6c93613d System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)     &lt;br /&gt;03e2ef70 6ca0a7a2 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)     &lt;br /&gt;03e2ef74 6ca0a58f [InlinedCallFrame: 03e2ef74]     &lt;br /&gt;03e2f4c8 01092314 [NDirectMethodFrameStandalone: 03e2f4c8] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)     &lt;br /&gt;03e2f4d8 6ca0a839 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)     &lt;br /&gt;03e2f55c 6ca0a58f System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)     &lt;br /&gt;03e2f65c 01092314 [ContextTransitionFrame: 03e2f65c] &lt;/div&gt;  &lt;p&gt;So we’re in the Page_Load event of the page in question, but apart from that !clrstack doesn’t tell us much. Let’s take a look at the native callstack instead using the kb-command.&lt;/p&gt;  &lt;div class="DebugSample"&gt;0:019&amp;gt; kb20    &lt;br /&gt;ChildEBP RetAddr&amp;#160; Args to Child&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;03e2d030 776d9254 76adc244 000006d8 00000000 ntdll!KiFastSystemCallRet     &lt;br /&gt;03e2d034 76adc244 000006d8 00000000 03e2d07c ntdll!ZwWaitForSingleObject+0xc     &lt;br /&gt;03e2d0a4 74256247 000006d8 00003a98 00000000 kernel32!&lt;font color="#ff0000"&gt;WaitForSingleObjectEx&lt;/font&gt;+0xbe     &lt;br /&gt;03e2d0d8 74251f7c 0141f2e4 00000002 00202005 cryptnet!CryptRetrieveObjectByUrlWithTimeout+0x1a5     &lt;br /&gt;03e2d1c8 742527a1 0141f2e4 00000002 00202005 cryptnet!CryptRetrieveObjectByUrlW+0xcc     &lt;br /&gt;03e2d268 742591be 00000000 0141f2e4 00000002 cryptnet!RetrieveObjectByUrlValidForSubject+0xa0     &lt;br /&gt;03e2d2c8 74252556 00000000 00000000 00000001 cryptnet!RetrieveTimeValidObjectByUrl+0x15c     &lt;br /&gt;03e2d374 74253fc1 00000082 0141f2d8 00000000 cryptnet!CTVOAgent::GetTimeValidObjectByUrl+0x178     &lt;br /&gt;03e2d45c 74253d98 00000003 018aa590 00000002 cryptnet!CTVOAgent::GetTimeValidObject+0x4a8     &lt;br /&gt;03e2d48c 74253428 00000003 018aa590 018c8220 cryptnet!FreshestCrlFromCrlGetTimeValidObject+0x2d     &lt;br /&gt;03e2d4d0 74259283 00000003 018aa590 018c8220 cryptnet!CryptGetTimeValidObject+0x58     &lt;br /&gt;03e2d54c 74253b1c 00000003 018aa590 018aa590 cryptnet!GetTimeValidCrl+0x2cb     &lt;br /&gt;03e2d590 74253992 018aa590 018c8220 03e2d5c8 cryptnet!GetBaseCrl+0x34     &lt;br /&gt;03e2d63c 757f77d5 00000001 00000001 00000001 cryptnet!&lt;font color="#ff0000"&gt;MicrosoftCertDllVerifyRevocation&lt;/font&gt;+0x163     &lt;br /&gt;03e2d6c8 757f7641 00000001 00000001 00000001 crypt32!I_CryptRemainingMilliseconds+0x2aa     &lt;br /&gt;03e2d74c 757f7a26 00000001 00000001 00000001 crypt32!CertVerifyRevocation+0xd4     &lt;br /&gt;03e2d7f8 757f7838 01899590 00000000 00000000 crypt32!CChainPathObject::CalculateRevocationStatus+0x2d0     &lt;br /&gt;03e2d83c 75806c44 01899590 018c3018 01870fc0 crypt32!CChainPathObject::CalculateAdditionalStatus+0x152     &lt;br /&gt;03e2d904 758069a5 01899590 018aa590 01870fc0 crypt32!CCertChainEngine::CreateChainContextFromPathGraph+0x23e     &lt;br /&gt;03e2d93c 7580be14 018aa590 018aff94 01870fc0 crypt32!CCertChainEngine::GetChainContext+0x46     &lt;br /&gt;03e2d974 749172ba 01421338 018aa590 018aff94 crypt32!CertGetCertificateChain+0x72     &lt;br /&gt;03e2d9dc 749170fc 40000001 00000000 03e2da10 wintrust!_WalkChain+0x1ae     &lt;br /&gt;03e2da18 7491363b 00000000 03e2dbdc 03e2db74 wintrust!WintrustCertificateTrust+0xb9     &lt;br /&gt;03e2db30 7491346c 00000000 03e2dbe4 00000000 wintrust!_VerifyTrust+0x253     &lt;br /&gt;03e2db54 64025b1b 00000000 03e2dbe4 03e2db74 wintrust!WinVerifyTrust+0x50     &lt;br /&gt;03e2dbf8 716b7f4d &lt;font color="#ff0000"&gt;014443f8&lt;/font&gt; 00000000 00000003 mscorsec!&lt;font color="#ff0000"&gt;GetPublisher&lt;/font&gt;+0xe4     &lt;br /&gt;03e2dc50 7145ed3b d60caabc 0188c4a8 00603c48 mscorwks!PEFile::CheckSecurity+0xcb     &lt;br /&gt;03e2dc78 7145ec84 d60caa64 00000000 0188c4a8 mscorwks!PEAssembly::DoLoadSignatureChecks+0x3a     &lt;br /&gt;03e2dca0 7145f0ca 01879f00 00000000 0188c4a8 mscorwks!PEAssembly::PEAssembly+0x109     &lt;br /&gt;03e2df3c 7145f1c5 0188c4a8 00000000 00000000 mscorwks!PEAssembly::DoOpen+0x103     &lt;br /&gt;03e2dfd0 71459062 0188c4a8 00000000 00000000 mscorwks!PEAssembly::Open+0x79     &lt;br /&gt;03e2e134 71456ace 03e2e15c 00000001 00000000 mscorwks!AppDomain::BindAssemblySpec+0x247 &lt;/div&gt;  &lt;p&gt;Here we see that we’re currently trying to check the certificate revocation list. This is done on a separate thread so this thread is currently doing nothing but waiting. Our next step would be to find this thread, but first we can find out the name of the .dll that we’re trying to verify. Look at the first argument to GetPublisher.&lt;/p&gt;  &lt;div class="DebugSample"&gt;0:019&amp;gt; du &lt;font color="#ff0000"&gt;014443f8&lt;/font&gt;     &lt;br /&gt;014443f8&amp;#160; &amp;quot;C:\Windows\Microsoft.NET\Framewo&amp;quot;     &lt;br /&gt;01444438&amp;#160; &amp;quot;rk\v2.0.50727\Temporary ASP.NET &amp;quot;     &lt;br /&gt;01444478&amp;#160; &amp;quot;Files\scstt\57ae16cd\2f8637d5\as&amp;quot;     &lt;br /&gt;014444b8&amp;#160; &amp;quot;sembly\dl3\078f3d05\00fba208_c03&amp;quot;     &lt;br /&gt;014444f8&amp;#160; &amp;quot;6ca01\Microsoft.Practices.Enterp&amp;quot;     &lt;br /&gt;01444538&amp;#160; &amp;quot;riseLibrary.Logging.DLL&amp;quot; &lt;/div&gt;  &lt;p&gt;So it’s a Microsoft .dll that is part of the Enterprise Library. Good to know. Now let’s find the thread that is attempting to retrieve the revocation list by running ~*kb and scanning through the threads until we find this one:&lt;/p&gt;  &lt;div class="DebugSample"&gt;0:021&amp;gt; kb2000    &lt;br /&gt;ChildEBP RetAddr&amp;#160; Args to Child&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;0427d7f8 776d9254 75502283 0000070c 00000001 ntdll!KiFastSystemCallRet     &lt;br /&gt;0427d7fc 75502283 0000070c 00000001 0427d824 ntdll!ZwWaitForSingleObject+0xc     &lt;br /&gt;0427d83c 75501fc8 0000070c 00000714 00000001 mswsock!SockWaitForSingleObject+0x19f     &lt;br /&gt;0427d928 77801693 00000001 00000000 0427d9d0 mswsock!WSPSelect+0x38c     &lt;br /&gt;0427d9a8 72a733e5 00000001 00000000 0427d9d0 ws2_32!select+0x494     &lt;br /&gt;0427e1ec 72a730fd 00000714 0427e210 72a72e88 winhttp!ICSocket::Connect_Start+0x3b0     &lt;br /&gt;0427e1f8 72a72e88 01828250 72a737bc 00000000 winhttp!CFsm_SocketConnect::RunSM+0x42     &lt;br /&gt;0427e210 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     &lt;br /&gt;0427e234 72a7467d 01828250 018ccf30 0427e258 winhttp!DoFsm+0x2a     &lt;br /&gt;0427e244 72a74646 0000ea60 00000005 00000020 winhttp!ICSocket::Connect+0x32     &lt;br /&gt;0427e258 72a742b5 0000ea60 00000005 0000ea60 winhttp!ICSocket::Connect+0x13     &lt;br /&gt;0427e2a4 72a74038 01434458 0427e2c8 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::OpenConnection_Fsm+0x471     &lt;br /&gt;0427e2b0 72a72e88 01434458 00000000 00000000 winhttp!CFsm_OpenConnection::RunSM+0x37     &lt;br /&gt;0427e2c8 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     &lt;br /&gt;0427e2ec 72a74625 01434458 018ccf30 0427e324 winhttp!DoFsm+0x2a     &lt;br /&gt;0427e2fc 72a745bc 00000000 00000000 018b0c60 winhttp!HTTP_REQUEST_HANDLE_OBJECT::OpenConnection+0x2f     &lt;br /&gt;0427e324 72a74526 0141f638 0427e348 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::MakeConnection_Fsm+0x9b     &lt;br /&gt;0427e330 72a72e88 0141f638 00000000 00000000 winhttp!CFsm_MakeConnection::RunSM+0x37     &lt;br /&gt;0427e348 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     &lt;br /&gt;0427e36c 72a743c1 0141f638 018b0c60 014343c0 winhttp!DoFsm+0x2a     &lt;br /&gt;0427e3ac 72a74339 014343c0 0427e3d0 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::SendRequest_Fsm+0x93     &lt;br /&gt;0427e3b8 72a72e88 014343c0 018ccf30 00000000 winhttp!CFsm_SendRequest::RunSM+0x37     &lt;br /&gt;0427e3d0 72a7382b 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     &lt;br /&gt;0427e3f4 72a73db0 014343c0 018b0c60 01888820 winhttp!DoFsm+0x2a     &lt;br /&gt;0427e414 72a76f71 00000000 0427e438 72a72e88 winhttp!HTTP_REQUEST_HANDLE_OBJECT::HttpSendRequest_Start+0x2af     &lt;br /&gt;0427e420 72a72e88 01888820 00000001 00000000 winhttp!CFsm_HttpSendRequest::RunSM+0x4c     &lt;br /&gt;0427e438 72a73c3e 018b0c60 00000000 00000000 winhttp!CFsm::Run+0x20     &lt;br /&gt;0427e480 72a73b8b 01888820 018ccf30 00000000 winhttp!StartFsmChain+0xcf     &lt;br /&gt;0427e4c4 72a739d8 018ccf30 00000000 00000000 winhttp!HttpWrapSendRequest+0x18c     &lt;br /&gt;0427e544 742599b4 018ccf30 00000000 00000000 winhttp!WinHttpSendRequest+0x19b     &lt;br /&gt;0427f5e4 74259741 005f7bc0 018ccf30 01898e60 cryptnet!InetSendAuthenticatedRequestAndReceiveResponse+0x56f     &lt;br /&gt;0427f6ec 7425921d 005f7bc0 &lt;font color="#ff0000"&gt;01898e60&lt;/font&gt; 00202005 cryptnet!InetSendReceiveUrlRequest+0x2c8     &lt;br /&gt;0427f724 742523e9 &lt;font color="#ff0000"&gt;01898e60&lt;/font&gt; 00000002 00202005 cryptnet!CInetSynchronousRetriever::RetrieveObjectByUrl+0x5f     &lt;br /&gt;0427f75c 742521a8 &lt;font color="#ff0000"&gt;01898e60&lt;/font&gt; 00000002 00202005 cryptnet!InetRetrieveEncodedObject+0x64     &lt;br /&gt;0427f7b8 74256350 &lt;font color="#ff0000"&gt;01898e60&lt;/font&gt; 00000002 00202005 cryptnet!CObjectRetrievalManager::RetrieveObjectByUrl+0xbb     &lt;br /&gt;0427f810 76ad4911 00000000 0427f85c 776be4b6 cryptnet!CryptRetrieveObjectByUrlWithTimeoutThreadProc+0x67     &lt;br /&gt;0427f81c 776be4b6 01898db0 4e080acf 00000000 kernel32!BaseThreadInitThunk+0xe     &lt;br /&gt;0427f85c 776be489 742562f7 01898db0 ffffffff ntdll!__RtlUserThreadStart+0x23     &lt;br /&gt;0427f874 00000000 742562f7 01898db0 00000000 ntdll!_RtlUserThreadStart+0x1b     &lt;br /&gt;0:021&amp;gt; du &lt;font color="#ff0000"&gt;01898e60&lt;/font&gt;     &lt;br /&gt;01898e60&amp;#160; &amp;quot;http://crl.microsoft.com/pki/crl&amp;quot;     &lt;br /&gt;01898ea0&amp;#160; &amp;quot;/products/CodeSignPCA2.crl&amp;quot; &lt;/div&gt;  &lt;p&gt;This is the thread. To finally verify that it is in fact attempting to download the Certificate Revocation List we can check the value of the first argument to cryptnet!CInetSynchronousRetriever, InetRetrieveEncodedObject and CObjectRetrievalManager::RetrieveObjectByUrl or the second argument to cryptnet!InetSendReceiveUrlRequest as I did above.&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;In this case the customer chose to disable Signature Verification completely rather than granting Internet access to the server.&lt;/p&gt;  &lt;p&gt;If you found the windbg-portion of this post hard to understand I can recommend a closer look at my Debugging School (In the menu to the left). Begin with &lt;a title="Getting started with windbg - Part I" href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx"&gt;Getting started with windbg - Part I&lt;/a&gt; and you should be set to go in no time.&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921295" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Performance/">Performance</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Worker+Process/">Worker Process</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Debugging+School/">Debugging School</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Did+you+know_3F00_/">Did you know?</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Hangs/">Hangs</category></item><item><title>Investigating Locks</title><link>http://blogs.msdn.com/b/johan/archive/2009/10/09/investigating-locks.aspx</link><pubDate>Fri, 09 Oct 2009 16:49:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9905467</guid><dc:creator>JohanSt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9905467</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/10/09/investigating-locks.aspx#comments</comments><description>&lt;p&gt;Consider the following scenario:&lt;/p&gt;  &lt;p&gt;You have an ASP.NET application which intermittently responds sluggishly. As the problem occurs memory usage is about average, as is CPU usage, but still certain pages respond slower and slower. The machine acts just as if it is under heavy load, but judging from the CPU it isn't. In fact CPU usage might even &lt;em&gt;decrease&lt;/em&gt; rather than increase. When trying to access non .NET content such as plain text/html or images you usually find that response times are just as fast as ever.&lt;/p&gt;  &lt;p&gt;When you find that your application has hung in a low CPU state it is usually because of one of the following reasons (in order of likelihood based on my experience) :&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;External resources responding slowly. E.g. a database query or AD lookup is taking a long time to complete and so the application is simply waiting for another server to respond. &lt;/li&gt;    &lt;li&gt;One of the threads of the application has entered a critical section and now several other threads are waiting to enter the same critical section. &lt;/li&gt;    &lt;li&gt;A classic deadlock. Thread A waits for thread B which waits for thread C which waits for thread A. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Quite often you'll see a mixture of items 1 and 2. A thread enters a critical section, calls a remote database, or similar, and all other threads attempting to enter the same critical section will have to nicely stay in line until the struggling database has responded. Still, it is quite possible that the critical section is waiting for a local event to finish, but then you'd usually see a higher CPU load on the machine. (Though not necessarily in the w3wp.exe process.)&lt;/p&gt;  &lt;h1&gt;What are Critical Sections?&lt;/h1&gt;  &lt;p&gt;In case you've forgotten or simply not worked that much with critical sections it might be necessary to refresh your memory on this.&lt;/p&gt;  &lt;p&gt;A Critical Section is a segment of code that you do not want to be executed more than one at a time. In order to ensure this you use the &lt;strong&gt;lock&lt;/strong&gt; keyword to ensure that a certain block of code is able to complete with no interruption from any other threads. To illustrate this I've created the following code sample:&lt;/p&gt;  &lt;div class="SampleCode"&gt;   &lt;pre&gt;public class FileIO
{
    private static object myLock = new object();

	public FileIO()
	{
	}

    public string performLockOperation()
    {
        string strResult = &amp;quot;The Lock Operation started on &amp;quot; + System.DateTime.Now.ToLongTimeString();
        lock (myLock)
        {
            // Let the thread sleep for 10 seconds
            // This way we simulate a File IO operation that takes some time to complete.
            System.Threading.Thread.Sleep(10000);
        }
        strResult += &amp;quot; and ended on &amp;quot; + System.DateTime.Now.ToLongTimeString();
        return strResult;
    }

    public string performNoLockOperation()
    {
        string strResult = &amp;quot;The No Lock Operation started on &amp;quot; + System.DateTime.Now.ToLongTimeString();
        System.Threading.Thread.Sleep(10000);
        strResult += &amp;quot; and ended on &amp;quot; + System.DateTime.Now.ToLongTimeString();
        return strResult;
    }

}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Let's take a quick look at the parts of this class that I've written, called FileIO:&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;myLock&lt;/h2&gt;

&lt;p&gt;The class has a static variable called myLock that I will be using to identify the lock I'm about to create. This is why the variable is static. Otherwise I'd be creating new locks for each instance of the FileIO class leaving the lock operation completely redundant. Now that I use a static variable the lock spans all instances of the FileIO class.&lt;/p&gt;

&lt;h2&gt;constructor&lt;/h2&gt;

&lt;p&gt;The constructor is empty. Move along. Nothing to see here.&lt;/p&gt;

&lt;h2&gt;performLockOperation&lt;/h2&gt;

&lt;p&gt;This is the most interesting part of the class. It is the function we'll be using to actually reproduce the potential problems. The function returns a string which will contain information about when the call to the function was made and when it completed. We store this data in a string called strResult which we will eventually be returning as the result of the function call.&lt;/p&gt;

&lt;p&gt;Having declared this variable and put the initial time of the function call in it we then create our lock. This is simply done with the following syntax:&lt;/p&gt;

&lt;div class="SampleCode"&gt;
  &lt;pre&gt;lock (object)
{
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Any code within this block will first make sure that there is not already a lock taken on this object. If there is, then they will pause execution and wait for the lock to become available before continuing execution.&lt;/p&gt;

&lt;p&gt;Inside our lock we then simulate a slow File IO operation by letting the thread sleep for 10 seconds.&lt;/p&gt;

&lt;p&gt;After that we append the current time to the result and return it.&lt;/p&gt;

&lt;h2&gt;performNoLockOperation&lt;/h2&gt;

&lt;p&gt;This function is identical to the previous one, except this time we do not have a critical section. This function is included just for comparison.&lt;/p&gt;

&lt;h1&gt;The potential problem&lt;/h1&gt;

&lt;p&gt;Now, let's get down to business. If we have a web page that makes a call to the performLockOperation-function and that page is requested at the same time by four different clients. What would be the response times?&lt;/p&gt;

&lt;p&gt;The answer is 10, 20, 30 &amp;amp; 40 seconds.&lt;/p&gt;

&lt;p&gt;Here's why:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The thread handling the first request enters the critical section, effectively locking it for everyone else. When it is complete 10 seconds have passed due to the Sleep-call. &lt;/li&gt;

  &lt;li&gt;One of the other threads enters the critical section once the first request is finished. It has already waited for 10 seconds, and the thread will now sleep for an additional 10 seconds. &lt;/li&gt;

  &lt;li&gt;As the second thread finishes one of the remaining two enters the critical section. It has now waited for 20 seconds and will sleep for an additional 10. &lt;/li&gt;

  &lt;li&gt;The final request is able to enter the critical section after having waited for 30 seconds. Once it is complete 40 seconds have passed. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we'd been using the performNoLockOperation instead then all requests would have responded after 10 seconds.&lt;/p&gt;

&lt;p&gt;Now, I know that 10 seconds is an exceptionally long time to let the thread sleep, but this was all for illustration purposes. Imagine instead that the sleeping time was 1 second and the number of requests was 200...&lt;/p&gt;

&lt;h1&gt;&lt;/h1&gt;

&lt;h1&gt;Troubleshooting this issue&lt;/h1&gt;

&lt;p&gt;Okay, so what would it look like when this problem occurs? Let's have a look. If you haven't looked at my posts on getting started with Windbg, then I suggest reading them before continuing. (&lt;a href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx"&gt;Part I&lt;/a&gt; &amp;amp; &lt;a href="http://blogs.msdn.com/johan/archive/2008/05/28/powershell-an-introduction-part-ii.aspx"&gt;Part II&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;First of all I fire up WinDbg, then I attach to the w3wp.exe. I then use &amp;quot;~*e!clrstack&amp;quot; to look at the managed threads of the w3wp.exe application. Here is a snippet of what I get:&lt;/p&gt;

&lt;div class="DebugSample"&gt;
  &lt;pre&gt;OS Thread Id: 0xce0 (24)
Child-SP         RetAddr          Call Site
000000000447e0f0 000007ff001e13d2 FileIO.performLockOperation()
000000000447e170 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
000000000447e1b0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
000000000447e1e0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
000000000447e210 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
000000000447e250 000007fee79498ac System.Web.UI.Control.LoadRecursive()
000000000447e2a0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
000000000447e370 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
000000000447e3d0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
000000000447e430 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
000000000447e490 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
000000000447e4c0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
000000000447e570 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
000000000447e610 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
000000000447e7a0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
000000000447e7f0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000000447e910 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000447ea80 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000447eae0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
000000000447f310 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000000447f3f0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000447f560 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000447f5c0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x15ec (25)
Unable to walk the managed stack. The current thread is likely not a 
managed thread. You can run !threads to get a list of managed threads in
the process
OS Thread Id: 0x1958 (26)
Child-SP         RetAddr          Call Site
0000000004c1dd10 000007ff001e13d2 FileIO.performLockOperation()
0000000004c1dd90 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
0000000004c1ddd0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
0000000004c1de00 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
0000000004c1de30 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
0000000004c1de70 000007fee79498ac System.Web.UI.Control.LoadRecursive()
0000000004c1dec0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
0000000004c1df90 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
0000000004c1dff0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
0000000004c1e050 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
0000000004c1e0b0 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
0000000004c1e0e0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
0000000004c1e190 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
0000000004c1e230 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
0000000004c1e3c0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
0000000004c1e410 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
0000000004c1e530 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1e6a0 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1e700 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
0000000004c1ef30 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
0000000004c1f010 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1f180 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004c1f1e0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x1e28 (27)
Child-SP         RetAddr          Call Site
000000000492dcf0 000007ff001e13d2 FileIO.performLockOperation()
000000000492dd70 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
000000000492ddb0 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
000000000492dde0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
000000000492de10 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
000000000492de50 000007fee79498ac System.Web.UI.Control.LoadRecursive()
000000000492dea0 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
000000000492df70 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
000000000492dfd0 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
000000000492e030 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
000000000492e090 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
000000000492e0c0 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
000000000492e170 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
000000000492e210 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
000000000492e3a0 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
000000000492e3f0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000000492e510 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000492e680 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000492e6e0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
000000000492ef10 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000000492eff0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000000492f160 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000000492f1c0 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
OS Thread Id: 0x1c38 (28)
Child-SP         RetAddr          Call Site
0000000004d0e0b0 000007ff001e13d2 FileIO.performLockOperation()
0000000004d0e130 000007feee323ec9 _Default.Page_Load(System.Object, System.EventArgs)
0000000004d0e170 000007fee7956aea System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
0000000004d0e1a0 000007fee794d2c4 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
0000000004d0e1d0 000007fee794d322 System.Web.UI.Control.OnLoad(System.EventArgs)
0000000004d0e210 000007fee79498ac System.Web.UI.Control.LoadRecursive()
0000000004d0e260 000007fee7948db0 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
0000000004d0e330 000007fee7948cdb System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
0000000004d0e390 000007fee7948c70 System.Web.UI.Page.ProcessRequest()
0000000004d0e3f0 000007ff001e0c09 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
0000000004d0e450 000007fee7950117 ASP.default_aspx.ProcessRequest(System.Web.HttpContext)
0000000004d0e480 000007fee791449b System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
0000000004d0e530 000007fee7ffbd41 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)
0000000004d0e5d0 000007fee7fed132 System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)
0000000004d0e760 000007fee7fcf599 System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)
0000000004d0e7b0 000007fee80f5344 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
0000000004d0e8d0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0ea40 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0eaa0 000007fef72701ea DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)
0000000004d0f2d0 000007fee80f5424 DomainNeutralILStubClass.IL_STUB(IntPtr, System.Web.RequestNotificationStatus ByRef)
0000000004d0f3b0 000007fee80f65bb System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0f520 000007fee80f4994 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
0000000004d0f580 000007fef727043b DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, what does this tell us?&lt;/p&gt;

&lt;p&gt;Well, obviously we have four threads that call my function FileIO.performLockOperation() from Page_Load.&lt;/p&gt;

&lt;p&gt;Please note that we don't have any additional callstack, and since the performLockOperation-function was named by me it could just as well have been named &amp;quot;foo&amp;quot;. In order to find out that these threads are actually waiting for a lock we need to look at the native callstack using the kb-command. Let's take a look at thread 24: &lt;/p&gt;

&lt;div class="DebugSample"&gt;
  &lt;pre&gt;0:029&amp;gt; ~24kb
ntdll!NtDelayExecution+0xa
kernel32!SleepEx+0x84
mscorwks!EESleepEx+0x2d
mscorwks!Thread::UserSleep+0x71
mscorwks!&lt;font color="#ff0000"&gt;ThreadNative::Sleep&lt;/font&gt;+0xf9
App_Code_tvh3usvo!&lt;font color="#ff0000"&gt;FileIO.performLockOperation&lt;/font&gt;()+0x8a
App_Web_uywrbugj!_Default.Page_Load(System.Object, System.EventArgs)+0x32
System_Web_RegularExpressions_ni!System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)+0x19
System_Web_ni!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)+0x2a
System_Web_ni!System.Web.UI.Control.OnLoad(System.EventArgs)+0x84
System_Web_ni!System.Web.UI.Control.LoadRecursive()+0x42
System_Web_ni!System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)+0x97c
System_Web_ni!System.Web.UI.Page.ProcessRequest(Boolean, Boolean)+0xa0
System_Web_ni!System.Web.UI.Page.ProcessRequest()+0x5b
System_Web_ni!System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)+0xf0
App_Web_uywrbugj!ASP.default_aspx.ProcessRequest(System.Web.HttpContext)+0x9
System_Web_ni!System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+0x257
System_Web_ni!System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)+0xab
System_Web_ni!System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)+0x501
System_Web_ni!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)+0x72&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Apparently we entered FileIO.performLockOperation, and then called sleep, (which is what we're doing in this repro in order to simulate a slow IO operation.) So, what do the other threads look like? Here's thread 26:&lt;/p&gt;

&lt;div class="DebugSample"&gt;
  &lt;pre&gt;0:029&amp;gt; ~26kb
ntdll!ZwWaitForMultipleObjects+0xa
kernel32!WaitForMultipleObjectsEx+0x10b
mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0xc1
mscorwks!Thread::DoAppropriateAptStateWait+0x41
mscorwks!Thread::DoAppropriateWaitWorker+0x191
mscorwks!Thread::DoAppropriateWait+0x5c
mscorwks!&lt;font color="#ff0000"&gt;CLREvent::WaitEx&lt;/font&gt;+0xbe
mscorwks!AwareLock::EnterEpilog+0xc9
mscorwks!AwareLock::Enter+0x72
mscorwks!AwareLock::Contention+0x1fb
mscorwks!JITutil_MonContention+0xdf
App_Code_tvh3usvo!&lt;font color="#ff0000"&gt;FileIO.performLockOperation&lt;/font&gt;()+0x7f
App_Web_uywrbugj!_Default.Page_Load(System.Object, System.EventArgs)+0x32
System_Web_RegularExpressions_ni!System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)+0x19
System_Web_ni!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)+0x2a
System_Web_ni!System.Web.UI.Control.OnLoad(System.EventArgs)+0x84
System_Web_ni!System.Web.UI.Control.LoadRecursive()+0x42
System_Web_ni!System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)+0x97c
System_Web_ni!System.Web.UI.Page.ProcessRequest(Boolean, Boolean)+0xa0
System_Web_ni!System.Web.UI.Page.ProcessRequest()+0x5b&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is one of the threads waiting for the critical section. It then found that it was unable to get a lock and so began waiting for the critical section on thread 24 to end.&lt;/p&gt;

&lt;h1&gt;Resolving the problem&lt;/h1&gt;

&lt;p&gt;This is the tricky part. There is no quick-fix for this. We can use the debugger to identify the bottleneck, but after that we'll need to review our design in order to get this working smoothly. A couple of generic things to try would be the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Review what you're doing inside the critical section. Is it really necessary to perform all of the operations you're doing, or would it be possible to do some/all of them outside the scope of the critical section?&lt;/li&gt;

  &lt;li&gt;Identify the reason for the lock taking so much time. Can it be resolved by load-balancing or clustering the resource we're waiting for?&lt;/li&gt;

  &lt;li&gt;If we're waiting for another server, make sure the physical infrastructure is okay. Are network response times within the expected parameters or do you need to fix your wiring, router, etc?&lt;/li&gt;

  &lt;li&gt;Are &lt;em&gt;all &lt;/em&gt;calls to the critical section taking the same amount of time, or are there certain calls that take an &lt;em&gt;exceptional&lt;/em&gt; amount of time? Perhaps most calls to the function are just fine, but intermittently a call comes along that tries to get &lt;em&gt;everything &lt;/em&gt;from the AD, database, etc. In order to investigate this I'd use the commands outlined in &lt;a href="http://blogs.msdn.com/johan/archive/2007/11/26/getting-started-with-windbg-part-ii.aspx"&gt;Getting started with windbg -part II&lt;/a&gt;. Identify the thread owning the lock and investigate the callstack and stack objects using !clrstack and !dso. Use !dso and !do to query the stack objects and try to find the SQL query or AD query that is causing the thread to take such a long time to finish. Is the query significantly different from the ones waiting to execute, then this is most likely our culprit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;Post Script&lt;/h1&gt;

&lt;p&gt;A quick thought on locks and their limits:&lt;/p&gt;

&lt;p&gt;Locks do not scale well. A lock can only be made within a specific process, so if you're using a web farm, or in any other way more than one w3wp.exe, then you will not be able to lock &lt;em&gt;all &lt;/em&gt;processes. In other words. Server 1 can get a lock, and so can Server 2. Both will happily execute their code independent of each other. For products such as SQL server you'd deal with this in your SQL query, but if you're performing other operations, such as File IO you might have to work around this by using the same approach as Ms Word. Create a lock file in a shared space, and before you enter your critical section you simply check if the file exists:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You are entering your critical section. Look for lock file in shared location&lt;/li&gt;

  &lt;li&gt;If file exists, then wait&lt;/li&gt;

  &lt;li&gt;If/when file doesn't/no longer exist, create file and enter critical section&lt;/li&gt;

  &lt;li&gt;Make sure you have &lt;em&gt;solid&lt;/em&gt; exception handling within the critical section so that you under no circumstances leave the critical section without removing the lock file.&lt;/li&gt;

  &lt;li&gt;When done, remove lock file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905467" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Performance/">Performance</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/WinDbg/">WinDbg</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Debugging+School/">Debugging School</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/ASP-NET/">ASP.NET</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Hangs/">Hangs</category></item><item><title>Problems with Flash-content in the WebBrowser control</title><link>http://blogs.msdn.com/b/johan/archive/2009/08/06/problems-with-flash-content-in-the-webbrowser-control.aspx</link><pubDate>Thu, 06 Aug 2009 17:59:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9859220</guid><dc:creator>JohanSt</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9859220</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/08/06/problems-with-flash-content-in-the-webbrowser-control.aspx#comments</comments><description>&lt;p&gt;A recent case I worked on involved the following scenario.&lt;/p&gt;  &lt;h1&gt;Problem description&lt;/h1&gt;  &lt;p&gt;The client was building a kiosk-like application. I.e. a WinForms application with the WebBrowser control slapped onto it. The application worked fine for the most part, but they'd found that when viewing video via &lt;a href="http://www.facebook.com/" target="_blank"&gt;facebook&lt;/a&gt; they were only able to view the video the first time. Any additional attempt to view the video would fail with a custom error from the facebook application stating that the video was either restricted or no longer available.&lt;/p&gt;  &lt;p&gt;This only happened when viewing the page via the WinForms application. Using IE directly worked just fine. We also found that this problem occurred with both IE7 and IE8 installed, so it seemed not to be related to the browser version.&lt;/p&gt;  &lt;p&gt;Other sites using the Adobe Flash player to display video, such as &lt;a href="http://video.msn.com" target="_blank"&gt;MSN&lt;/a&gt; or &lt;a href="http://www.youtube.com/" target="_blank"&gt;Youtube&lt;/a&gt; worked just fine.&lt;/p&gt;  &lt;h1&gt;Troubleshooting&lt;/h1&gt;  &lt;p&gt;Using the Developer tools included in IE8 I found that the facebook application displays a placeholder image with a play-button. Once that button is clicked the .swf player is loaded via client-side script. The .swf player then downloads the .mp4 that is to be displayed and divides it into suitable chunks.&lt;/p&gt;  &lt;p&gt;Fiddler traces revealed that the mp4 was downloaded when using IE but not when using the WinForms application. No errors were reported, instead the request was simply never made.&lt;/p&gt;  &lt;p&gt;We removed all code behind. All that remained was the On_Load event that set a starting page for the WebBrowser control, still we were unable to successfully load the movie.&lt;/p&gt;  &lt;p&gt;Adding facebook to the trusted zone changed nothing.&lt;/p&gt;  &lt;p&gt;Using the COM-version of the WebBrowser control still reproduced the problem.&lt;/p&gt;  &lt;p&gt;I then suspected restrictions in cross-domain access or similar, (facebook uses a lot of different domains,) but couldn't find anything conclusive.&lt;/p&gt;  &lt;p&gt;Finally I stumbled upon the root cause.&lt;/p&gt;  &lt;h1&gt;Cause&lt;/h1&gt;  &lt;p&gt;The problem is due to a bug within the Adobe Flash-player: &lt;a href="http://bugs.adobe.com/jira/browse/FP-256"&gt;http://bugs.adobe.com/jira/browse/FP-256&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The problem occurs when dynamically trying to display a cached .swf application with an external interface through script. So, another quick repro would be the following (Copied from the Adobe bug report):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a C# application with an embedded WebBrowser control.&lt;/li&gt;    &lt;li&gt;Load a HTML page with no content.&lt;/li&gt;    &lt;li&gt;Via JavaScript, add a SWF with external interface to the page via an object tag. (At this point I see server traffic, requesting the SWF.)&lt;/li&gt;    &lt;li&gt;From JavaScript, access the external interface of the SWF. Works OK.&lt;/li&gt;    &lt;li&gt;Browse to a second web page.&lt;/li&gt;    &lt;li&gt;Browse back to the empty one.&lt;/li&gt;    &lt;li&gt;Via JavaScript, add the SWF again. Cannot contact the external interface. (There is no server traffic, indicating that the SWF is already being cached.)&lt;/li&gt; &lt;/ol&gt;  &lt;h1&gt;Solution&lt;/h1&gt;  &lt;p&gt;While waiting for a fix from Adobe the only way to circumvent this is to manually remove the cached .swf. Article &lt;a href="http://support.microsoft.com/kb/262110" target="_blank"&gt;262110&lt;/a&gt; describes in detail how you can do this. Unfortunately this can be a bit tricky some times. In the sample repro above you'd resolve it by simply removing all .swf items from the cache upon page-load, but this wouldn't work in the facebook situation, since it might use the same control repeatedly without refreshing the page in between. Depending on your level of control over the target platform it might be easier to simply turn of caching.&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9859220" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Shockwave/">Shockwave</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/WebBrowser+control/">WebBrowser control</category></item><item><title>Adding Server ROles to an IIS installation on an RODC</title><link>http://blogs.msdn.com/b/johan/archive/2009/05/05/adding-server-roles-to-an-iis-installation-on-an-rodc.aspx</link><pubDate>Tue, 05 May 2009 17:10:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9588868</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9588868</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/05/05/adding-server-roles-to-an-iis-installation-on-an-rodc.aspx#comments</comments><description>&lt;p&gt;In a recent case I was involved with I stumbled upon something quite interesting. The customer had set up a brand new Windows 2008 Server running IIS, and made it into a &lt;em&gt;Read Only Domain Controller&lt;/em&gt; (RODC). Having done this they now wanted to add the FTP-server Role to the existing IIS installation and found that they couldn't.&lt;/p&gt;  &lt;p&gt;The reason for this is that the RODC is quite picky about what server roles and features it will allow you to install. I recommend looking at the following articles, but they still don't cover everything.&lt;/p&gt;  &lt;p&gt;Applications That Are Known to Work with RODCs   &lt;br /&gt;&lt;a title="http://technet.microsoft.com/en-us/library/cc732790.aspx" href="http://technet.microsoft.com/en-us/library/cc732790.aspx"&gt;http://technet.microsoft.com/en-us/library/cc732790.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Planning for Application Compatibility with RODCs   &lt;br /&gt;&lt;a title="http://technet.microsoft.com/en-us/library/cc731746.aspx" href="http://technet.microsoft.com/en-us/library/cc731746.aspx"&gt;http://technet.microsoft.com/en-us/library/cc731746.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The main lesson to be learned is that although the application is listed as known to work with RODCs that doesn't necessarily mean it installs well once the server has been promoted to RODC. When it comes to FTP you have two valid options to get this working:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Install the FTP server &lt;em&gt;before&lt;/em&gt; promoting the server to RODC&lt;/li&gt;    &lt;li&gt;Install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=b7f5b652-8c5c-447a-88b8-8cfc5c13f571" target="_blank"&gt;FTP Service 7.5 for IIS7&lt;/a&gt;. This is a stand-alone installer and works just fine.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9588868" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/IIS7/">IIS7</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category></item><item><title>Creating a game for the Zune</title><link>http://blogs.msdn.com/b/johan/archive/2009/03/31/creating-a-game-for-the-zune.aspx</link><pubDate>Tue, 31 Mar 2009 17:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9522814</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9522814</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/03/31/creating-a-game-for-the-zune.aspx#comments</comments><description>&lt;P&gt;I've finally had the time to sit down and create a simple game for my Zune. Rather than running off and creating a complex game requiring a lot of AI, etc I wanted to create a simple application so that I could focus on the XNA-specifics. I decided to make a Code Breaker game, also known as Master Mind. It's a pretty straight-forward game. There is no increasing difficulty curve and no fancy AI to be written, so it seemed like an excellent first attempt.&lt;/P&gt;
&lt;H1&gt;&lt;/H1&gt;
&lt;H1&gt;Prerequisites&lt;/H1&gt;
&lt;P&gt;Before I could start I needed to install the necessary software. I already had &lt;A href="http://www.microsoft.com/visualstudio/en-us/default.mspx" target=_blank mce_href="http://www.microsoft.com/visualstudio/en-us/default.mspx"&gt;Visual Studio 2008&lt;/A&gt; and the &lt;A href="http://www.zune.net/en-us/software/download/default.htm" target=_blank mce_href="http://www.zune.net/en-us/software/download/default.htm"&gt;Zune Software&lt;/A&gt;. Actually you don't need the full Visual Studio 2008. You can use the completely free &lt;A href="http://www.microsoft.com/express/download/" target=_blank mce_href="http://www.microsoft.com/express/download/"&gt;Visual C# 2008 Express Edition&lt;/A&gt; instead.&lt;/P&gt;
&lt;P&gt;You &lt;EM&gt;do&lt;/EM&gt; need to sign up as a creator in the &lt;A href="http://creators.xna.com/en-US" target=_blank mce_href="http://creators.xna.com/en-US"&gt;XNA Creators Club&lt;/A&gt;. Having done that, download the XNA Game Studio and install it. Now you're set to go.&lt;/P&gt;
&lt;H1&gt;Creating content&lt;/H1&gt;
&lt;P&gt;I gathered a few sound effects and whipped up some graphics for my project. I decided that this is what I wanted the game to look like:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/johan/images/9522730/original.aspx" mce_src="http://blogs.msdn.com/photos/johan/images/9522730/original.aspx"&gt; &lt;/P&gt;
&lt;P&gt;The background would be customizable. I wanted to be able to cycle through the available pictures on your device.&lt;/P&gt;
&lt;H1&gt;The architecture&lt;/H1&gt;
&lt;P&gt;I decided on a fairly simple architecture for my game. In my main class (Game1.cs) I deal with the necessities. E.g. I load the sound effects that will be used throughout the application, and I create the GraphicsDeviceManager that will be used to draw to the screen. Apart from that I have two classes that I use. MainGame and MainMenu. As their names imply they either show a menu or the game screen. User input is handled in the main class and it then calls methods in the relevant classes. E.g. if the menu is shown and the user clicks on the Zune "squircle" then a menu item has been selected and the event should bubble to the MainMenu class and not to the MainGame class.&lt;/P&gt;
&lt;P&gt;I do more or less the same thing in the Draw-method of the main class. Depending on what is shown on screen individual methods of the two classes are called. And the screen is updated accordingly.&lt;/P&gt;
&lt;H1&gt;Zune features&lt;/H1&gt;
&lt;P&gt;I made sure to add at least &lt;EM&gt;some&lt;/EM&gt; of the Zune-specific features.&lt;/P&gt;
&lt;H2&gt;Pictures&lt;/H2&gt;
&lt;P&gt;Like I've already mentioned I added support for getting backgrounds from the pictures on the device.&lt;/P&gt;
&lt;H2&gt;Music&lt;/H2&gt;
&lt;P&gt;I also let the player choose a playlist to be running in the background. (Anything already playing when the game is started will continue to play until the player actually changes this setting) I could have given full access to each individual song, but building an interface for that would have been quite ridiculous. Playlists only seemed like a good idea.&lt;/P&gt;
&lt;H2&gt;Touch interface&lt;/H2&gt;
&lt;P&gt;After some usability testing I found that in order to get this game working properly I needed to decide if I should incorporate the touch/sweep interface of the Zune 2.0 devices, or if I should settle for "proper" clicks only. I decided on the latter. Mainly because I still needed to rely on the center click, and it was easy to accidentally brush away to the side when trying to click. It also ment that this application would work with &lt;EM&gt;all&lt;/EM&gt; Zunes.&lt;/P&gt;
&lt;H2&gt;Other design choices&lt;/H2&gt;
&lt;P&gt;In the beginning I let the player change colors by clicking up/down and going to the next "peg" by clicking right/left.&lt;/P&gt;
&lt;P&gt;This turned out to be a bit complicated. It was quite easy to accidentally click up or down as well which would mean that you not only moved to the next peg, but also changed the previous pegs color. I ended up using the following key settings.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Click Right - Move Right&lt;/LI&gt;
&lt;LI&gt;Click Left - Move Left&lt;/LI&gt;
&lt;LI&gt;Center Click - Change color / Click button&lt;/LI&gt;
&lt;LI&gt;Play / Pause - Change color "back"&lt;/LI&gt;
&lt;LI&gt;Back - Menu&lt;/LI&gt;&lt;/UL&gt;
&lt;H1&gt;Installing&lt;/H1&gt;
&lt;P&gt;If you want to install and run this little game you need to go through the motions filed under &lt;EM&gt;Prerequisites &lt;/EM&gt;above. Open the project in Visual Studio 2008 and dock your Zune. You should then be able to deploy the release version or debug the application directly on the device.&lt;/P&gt;
&lt;H1&gt;Download&lt;/H1&gt;
&lt;P&gt;You can download the project &lt;A href="http://blogs.msdn.com/johan/attachment/9522814.ashx" mce_href="http://blogs.msdn.com/johan/attachment/9522814.ashx"&gt;here&lt;/A&gt;&lt;/P&gt;
&lt;H1&gt;Additional screenshots&lt;/H1&gt;
&lt;P&gt;Here are some additional screenshots of the game:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/photos/johan/images/9522727/original.aspx" mce_src="http://blogs.msdn.com/photos/johan/images/9522727/original.aspx"&gt;&amp;nbsp;&lt;IMG src="http://blogs.msdn.com/photos/johan/images/9522647/original.aspx" mce_src="http://blogs.msdn.com/photos/johan/images/9522647/original.aspx"&gt; &lt;IMG src="http://blogs.msdn.com/photos/johan/images/9522729/original.aspx" mce_src="http://blogs.msdn.com/photos/johan/images/9522729/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;I hope you enjoy it!&lt;/P&gt;
&lt;P&gt;/ Johan&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9522814" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-52-28-14/Crack-the-code.zip" length="286924" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Off+topic/">Off topic</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/XNA/">XNA</category></item><item><title>Internet Explorer 8 Released today</title><link>http://blogs.msdn.com/b/johan/archive/2009/03/19/internet-explorer-8-released-today.aspx</link><pubDate>Thu, 19 Mar 2009 15:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9489849</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9489849</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/03/19/internet-explorer-8-released-today.aspx#comments</comments><description>&lt;P&gt;Today we release Internet Explorer 8. You'll be able to download it later today from &lt;A href="http://www.microsoft.se/ie8"&gt;http://www.microsoft.se/ie8&lt;/A&gt;&lt;A title=http://www.microsoft.com/windows/internet-explorer/download-ie.aspx href="http://www.microsoft.com/windows/internet-explorer/download-ie.aspx" mce_href="http://www.microsoft.com/windows/internet-explorer/download-ie.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;/ Johan&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9489849" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/IE8/">IE8</category></item><item><title>Glimpsing 10 years into the future</title><link>http://blogs.msdn.com/b/johan/archive/2009/03/09/glimpsing-10-years-into-the-future.aspx</link><pubDate>Mon, 09 Mar 2009 13:58:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9467642</guid><dc:creator>JohanSt</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9467642</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/03/09/glimpsing-10-years-into-the-future.aspx#comments</comments><description>&lt;p&gt;Stephen Elop, the president of Microsoft's Business Division recently held a presentation where he allowed the viewers to glimpse 10 years into the future. It's amazing to look at a &amp;quot;real&amp;quot; interpretation of the future interfaces and technologies rather than the standard hollywood stuff. - You know the holographic projections that for some strange reason still use slow-typing green text on a black background. The video is really inspirational, and what I &lt;em&gt;really&lt;/em&gt; liked was how Stephen, after showing the video, went through all the technologies show in the clip and discussed how they could be accomplished.&lt;/p&gt; &lt;iframe src="http://www.microsoft.com/PressPass/SilverlightApps/videoplayer_3/standalone.aspx?xml=http://www.microsoft.com/winme/0902/1000046/Wharton_Tech_Conference_MBR.asx&amp;amp;r=embed&amp;amp;id=0" frameborder="0" width="350" scrolling="no" height="340"&gt;&lt;/iframe&gt;  &lt;p&gt;If you're in a rush you can skip the first part of the presentation and jump to directly to the video at about 14&amp;#189; minutes. But I really recommend watching the whole thing, especially the final rundown where he discusses the underlying technologies.&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9467642" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Off+topic/">Off topic</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Future+releases/">Future releases</category></item><item><title>Running a scheduled PowerShell script on a pre-Vista OS</title><link>http://blogs.msdn.com/b/johan/archive/2009/03/05/running-a-scheduled-powershell-script-on-a-pre-vista-os.aspx</link><pubDate>Thu, 05 Mar 2009 13:00:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9459530</guid><dc:creator>JohanSt</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9459530</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2009/03/05/running-a-scheduled-powershell-script-on-a-pre-vista-os.aspx#comments</comments><description>&lt;p&gt;It's been fun to see the reception that PowerShell has gotten. People are using it for tons of different stuff and the ingenuity in some of the scenarios is quite impressive. There is one thing, however, that you should be aware of. PowerShell is not an ideal candidate for execution through the Task Scheduler.&lt;/p&gt;  &lt;h1&gt;Problem&lt;/h1&gt;  &lt;p&gt;A long-running PowerShell script is being executed using the Task Scheduler. At apparently random intervals the script will fail with a &lt;span class="InlineCode"&gt;System.Management.Automation.PipelineStoppedException&lt;/span&gt;.&lt;/p&gt;  &lt;h1&gt;Cause&lt;/h1&gt;  &lt;p&gt;Looking up the exception on &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.pipelinestoppedexception(VS.85).aspx" target="_blank"&gt;MSDN&lt;/a&gt; might not shed any light on the situation unless you know what is happening.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The exception thrown when a cmdlet or a Windows PowerShell provider attempts to write to the pipeline or perform a number of other Windows PowerShell operations after the pipeline has been terminated. The pipeline could have been terminated before the call was made or during the call.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;When the Task Scheduler executes a PowerShell script it needs to use the .NET Framework. When running the .NET Framework it uses the console session (Session 0). This problem occurs when someone is logged on to the root console (either physically or using Terminal Services) and logs off &lt;em&gt;while the script is executing&lt;/em&gt;.&lt;/p&gt;  &lt;h1&gt;Repro&lt;/h1&gt;  &lt;p&gt;You can easily reproduce this by creating a small script that sleeps for a while. Schedule the script to run immediately and then log off. To illustrate I've used the following script:&lt;/p&gt;  &lt;div class="SampleCode"&gt;function Main()    &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Start-Transcript &amp;quot;C:\Test\Psjob.txt&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 'Start-Sleep'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Start-Sleep (2*60)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 'Ready'     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Stop-Transcript     &lt;br /&gt;}     &lt;br /&gt;&amp;#160; &lt;br /&gt;Main&lt;/div&gt;  &lt;p&gt;When correctly executed this script will generate a transcript that looks like this:&lt;/p&gt;  &lt;div class="DebugSample"&gt;**********************    &lt;br /&gt;Windows PowerShell Transcript Start     &lt;br /&gt;Start time: 20090305111600     &lt;br /&gt;Username&amp;#160; : DOMAIN\SYSTEM     &lt;br /&gt;Machine&amp;#160;&amp;#160; : MACHINENAME (Microsoft Windows NT 5.2.3790 Service Pack 2)     &lt;br /&gt;**********************     &lt;br /&gt;Transcript started, output file is C:\Test\Psjob.txt     &lt;br /&gt;Start-Sleep     &lt;br /&gt;Ready     &lt;br /&gt;**********************     &lt;br /&gt;Windows PowerShell Transcript End     &lt;br /&gt;End time: 20090305111800     &lt;br /&gt;**********************&lt;/div&gt;  &lt;p&gt;However, if I log off the console while the script is executing I get the following transcript:&lt;/p&gt;  &lt;div class="DebugSample"&gt;**********************    &lt;br /&gt;Windows PowerShell Transcript Start     &lt;br /&gt;Start time: 20090305114300     &lt;br /&gt;Username&amp;#160; : DOMAIN\SYSTEM     &lt;br /&gt;Machine&amp;#160;&amp;#160; : MACHINENAME (Microsoft Windows NT 5.2.3790 Service Pack 2)     &lt;br /&gt;**********************     &lt;br /&gt;Transcript started, output file is C:\Test\Psjob.txt     &lt;br /&gt;Start-Sleep     &lt;br /&gt;**********************     &lt;br /&gt;Windows PowerShell Transcript End     &lt;br /&gt;End time: 20090305114340     &lt;br /&gt;**********************&lt;/div&gt;  &lt;p&gt;As you can see the transcript is properly ended as PowerShell shuts down, but if you look at the output in the middle you'll see that we never write &amp;quot;Ready&amp;quot; to the file. This is because the script was prematurely terminated.&lt;/p&gt;  &lt;h1&gt;Resolution&lt;/h1&gt;  &lt;p&gt;The quick and easy resolution is to upgrade to Vista, Windows Server 2008 or later, since as of Windows Vista the console session is no longer running in Session 0.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9459530" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>PowerShell - Managing Feature Delegation in IIS7</title><link>http://blogs.msdn.com/b/johan/archive/2008/12/16/powershell-managing-feature-delegation-in-iis7.aspx</link><pubDate>Tue, 16 Dec 2008 16:51:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9225881</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=9225881</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/12/16/powershell-managing-feature-delegation-in-iis7.aspx#comments</comments><description>&lt;p&gt;Perhaps you've read my earlier post on &lt;a href="http://blogs.msdn.com/johan/archive/2008/10/02/powershell-advanced-configuration-editing-in-iis7.aspx"&gt;advanced feature delegation&lt;/a&gt; using PowerShell and the &lt;a href="http://learn.iis.net/page.aspx/429/installing-the-iis-70-powershell-provider/"&gt;IIS 7.0 PowerShell Provider&lt;/a&gt;. This could actually be called Part II.&lt;/p&gt;  &lt;p&gt;The previous post was based on a quick question from a premier customer. He is a never-ending source of intriguing questions and I always enjoy his &amp;quot;just one thing&amp;quot;-type of inquiries. They often force you to think a little extra. Anyway, the other day he came with a question, which (as always) seemed simple enough at a first glance. The goal was to set Feature Delegation for SMTP E-mail And Forms Authentication to &amp;quot;Read Only&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johan/images/9225741/original.aspx" /&gt; &lt;/p&gt;  &lt;p&gt;Now, most basic configuration topics have been covered in countless posts, and at first I thought that this shouldn't be so hard. There is, however, a major difference. The SMTP E-mail and Forms Authentication settings are set in the root web.config. Not in applicationhost.config.&lt;/p&gt;  &lt;p&gt;If we open up and compare web.config before, and after we change the setting, we'll notice that the change made by the IIS Manager is adding the following into the root &amp;lt;configuration&amp;gt;-block:&lt;/p&gt;  &lt;div class="DebugSample"&gt;&amp;lt;location path=&amp;quot;&amp;quot; overrideMode=&amp;quot;Deny&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;system.net&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;mailSettings&amp;gt;     &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;lt;smtp&amp;gt;     &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;lt;network /&amp;gt;     &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;lt;specifiedPickupDirectory /&amp;gt;     &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;lt;/smtp&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/mailSettings&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/system.net&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;system.web&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;authentication&amp;gt;     &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;lt;forms&amp;gt;     &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;lt;credentials /&amp;gt;     &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;lt;/forms&amp;gt;     &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;lt;passport /&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/authentication&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/system.web&amp;gt;     &lt;br /&gt;&amp;lt;/location&amp;gt; &lt;/div&gt;  &lt;p&gt;Okay, so using what we already know from the &lt;a href="http://blogs.msdn.com/johan/archive/2008/10/02/powershell-advanced-configuration-editing-in-iis7.aspx"&gt;old post&lt;/a&gt; we should put together a call that looks something like this:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Set-WebConfiguration &amp;quot;/System.Net/mailSettings/smtp&amp;quot;&amp;#160; -value @{&amp;lt;something... overrideMode=&amp;quot;Deny&amp;quot;, maybe?&amp;gt;} -PSPath IIS:\&lt;/div&gt;  &lt;p&gt;Please note that this is &lt;strong&gt;NOT&lt;/strong&gt; the correct syntax. It is close, but no cigar. What we need to do is:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Correctly set the overrideMode. The above sample is &lt;em&gt;not &lt;/em&gt;the way to do it. &lt;/li&gt;    &lt;li&gt;Make sure the changes are saved to web.config &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So, the final, (and correct,) call to the Set-WebConfiguration cmdlet would look like this:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Set-WebConfiguration //System.Net/mailSettings/smtp -metadata overrideMode -value Deny -PSPath MACHINE/WEBROOT&lt;/div&gt;  &lt;p&gt;The Forms Authentication call would look like this:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Set-WebConfiguration //System.Web/authentication -metadata overrideMode -value Deny -PSPath MACHINE/WEBROOT&lt;/div&gt;  &lt;p&gt;I've searched quite extensively for samples on this and so far I've found none. So I thought &lt;em&gt;someone &lt;/em&gt;should write it down. :)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy Holidays! / Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9225881" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/IIS7/">IIS7</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>Office Automation</title><link>http://blogs.msdn.com/b/johan/archive/2008/10/14/office-automation.aspx</link><pubDate>Tue, 14 Oct 2008 16:15:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8999436</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8999436</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/10/14/office-automation.aspx#comments</comments><description>&lt;p&gt;A very common scenario that keeps sprouting new heads like a hydra is Office Automation. Let me start by saying that this is &lt;strong&gt;not &lt;/strong&gt;supported.&lt;/p&gt;  &lt;p&gt;There is a KB-article number &lt;a href="http://support.microsoft.com/kb/257757/en-us"&gt;257757&lt;/a&gt; discusses this, and clearly states the following:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.&lt;/strong&gt;&lt;/p&gt;  &lt;h1&gt;&lt;strong&gt;Why is this not supported?&lt;/strong&gt;&lt;/h1&gt;  &lt;p&gt;The crucial thing to consider is the fact that Microsoft Office is designed to be an end-user, single client product. Automating Microsoft Office in a client application, using the identity and security context of the logged on client is supported, but unattended execution is not.&lt;/p&gt;  &lt;p&gt;There are a number of things that can go wrong and article &lt;a href="http://support.microsoft.com/kb/257757/en-us"&gt;257757&lt;/a&gt; lists most of them. For arguments sake, let's consider the following scenario:&lt;/p&gt;  &lt;p&gt;Your server application starts up and uses CreateObject to create an instance of MS Word. Word tries to read the settings of the current client and since your application is using the Network Service account this presents an immediate problem. There are, for example, certain methods that rely on a default printer being installed. All this can lead to serious problems. You then need to monitor the server, since Office might show a modal dialogue for some reason. The &amp;quot;install on first use&amp;quot; feature of MSI might also kick in, prompting the client to install additional features. All this would hang the current thread. Also, running one instance of Word, might be okay, but what happens when you get 100 more or less concurrent requests and each request starts up an instance of Word? MS Word is not a server, it's an excellent piece of single-client software.&lt;/p&gt;  &lt;h1&gt;So what should I do instead?&lt;/h1&gt;  &lt;p&gt;Actually, most of your problems can be resolved using HTML. I've seen applications where lines and lines of complex code were used for generating an Excel document, when it could just as well have been made using a standard HTML-table. Excel would have no problems whatsoever reading a table like the one below:&lt;/p&gt;  &lt;div class="SampleCode"&gt;&amp;lt;table&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Person&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;&amp;lt;b&amp;gt;Age&amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;Pete&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;30&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;Claire&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;40&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;tr&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;Average age&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;td&amp;gt;=AVERAGE(B2:B3)&amp;lt;/td&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/tr&amp;gt;     &lt;br /&gt;&amp;lt;/table&amp;gt;&lt;/div&gt;  &lt;p&gt;As you can see all formatting, and even the functions, would be interpreted correctly.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johan/images/8999380/original.aspx" /&gt; &lt;/p&gt;  &lt;p&gt;Obviously Word is great with HTML as well, so most formatting issues can quite easily be resolved using this approach.&lt;/p&gt;  &lt;h2&gt;So how do I do this?&lt;/h2&gt;  &lt;p&gt;The solution is quite easy. In order to generate an Excel document all you need to do is to create a table with the data you want, and add the following two lines to the Page_Load event of your page:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Response.ContentType = &amp;quot;application/vnd.ms-excel&amp;quot;;    &lt;br /&gt;Response.AddHeader(&amp;quot;Content-Disposition&amp;quot;, &amp;quot;attachment; filename=Data.xls;&amp;quot;);&lt;/div&gt;  &lt;p&gt;The first line, sets the returned ContentType to Excel, and the second changes the filename of the returned file. This means that the client will be prompted to Open/Save the file, and the filename will be set to &amp;quot;Data.xls&amp;quot; rather than &amp;quot;Default.aspx&amp;quot; (or whatever your original document may be called.)&lt;/p&gt;  &lt;p&gt;If you wanted to return a word document you'd set the ContentType to &amp;quot;application/msword&amp;quot; instead.&lt;/p&gt;  &lt;p&gt;One little thing to consider is the fact that by default you're probably adding a lot of redundant information to your webpage. You might want to remove all excessive HTML from the page so that you remove all unnecessary headers, stylesheets, viewstate, etc. For an example, please consider the code below:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Response.Clear();    &lt;br /&gt;Response.Buffer = true;     &lt;br /&gt;Response.ContentType = &amp;quot;application/vnd.ms-excel&amp;quot;;     &lt;br /&gt;Response.AddHeader(&amp;quot;Content-Disposition&amp;quot;, &amp;quot;attachment; filename=Data.xls;&amp;quot;);     &lt;br /&gt;this.EnableViewState = false;     &lt;br /&gt;System.IO.StringWriter oSw = new System.IO.StringWriter();     &lt;br /&gt;System.Web.UI.HtmlTextWriter oHtml = new System.Web.UI.HtmlTextWriter(oSw);     &lt;br /&gt;Table oTable = new Table();     &lt;br /&gt;for (int ctr = 1; ctr &amp;lt;= 10; ctr++)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; TableRow oRow = new TableRow();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; TableCell oCell1 = new TableCell();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; oCell1.Text = ctr.ToString();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; TableCell oCell2 = new TableCell();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; oCell2.Text = (ctr*10).ToString();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; oRow.Cells.Add(oCell1);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; oRow.Cells.Add(oCell2);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; oTable.Rows.Add(oRow);     &lt;br /&gt;}     &lt;br /&gt;oTable.RenderControl(oHtml);     &lt;br /&gt;Response.Write(oSw.ToString());     &lt;br /&gt;Response.End();&lt;/div&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;Security issues in Office 2007&lt;/h2&gt;  &lt;p&gt;If you're running Office 2007 you might come across the following error message:&lt;/p&gt;  &lt;p&gt;&amp;quot;The file you are trying to open, 'Data.xls', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?&lt;/p&gt;  &lt;p&gt;&amp;lt;Yes&amp;gt; &amp;lt;No&amp;gt; &amp;lt;Help&amp;gt;&lt;/p&gt;  &lt;p&gt;This is completely by design. In this example Excel has noticed that though the file is named .xls it does in fact contain html, so it's warning us about this inconsistency. We might bypass this by actually changing the file extension to htm or, perhaps saving the data as comma separated values (csv) which Excel also supports, but both options would be opened directly in the browser rather than passed on to Excel, so this is a design consideration we have to take into account.&lt;/p&gt;  &lt;p&gt;There is really no way of bypassing this security feature other than manually disabling it, client-side, using a registry hack. (The key is &lt;span class="InlineCode"&gt;HKCU\Software\Microsoft\Office\12.0\Excel\Security\&lt;/span&gt; Add a DWORD named &lt;span class="InlineCode"&gt;xtensionHardening&lt;/span&gt; and set it to 0.) For obvious reasons this is not something that is generally recommended.&lt;/p&gt;  &lt;h2&gt;Other options&lt;/h2&gt;  &lt;p&gt;There are also third-party products available for generating MS Office-compatible documents, but there are also some articles in the knowledge base on the subject. For example this little gem which can easily be adopted to ASP.NET as well:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://support.microsoft.com/kb/270906/en-us"&gt;How to use ASP to generate a Rich Text Format (RTF) document to stream to Microsoft Word&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8999436" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/ASP-NET/">ASP.NET</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Automation/">Automation</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Office/">Office</category></item><item><title>PowerShell - Advanced configuration editing in IIS7</title><link>http://blogs.msdn.com/b/johan/archive/2008/10/02/powershell-advanced-configuration-editing-in-iis7.aspx</link><pubDate>Thu, 02 Oct 2008 16:28:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8973569</guid><dc:creator>JohanSt</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8973569</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/10/02/powershell-advanced-configuration-editing-in-iis7.aspx#comments</comments><description>&lt;p&gt;I've written a lot of PowerShell posts lately and here's another one. :-)&lt;/p&gt;  &lt;p&gt;I got a question from one of the account managers if it was possible to alter the FTP Authorization Rules for a specific folder on his IIS.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johan/images/8973271/original.aspx" /&gt; &lt;/p&gt;  &lt;p&gt;The appcmd for the operation was&lt;/p&gt;  &lt;p&gt;&lt;span class="InlineCode"&gt;appcmd.exe set config &amp;quot;FTPFolder&amp;quot; -section:system.ftpServer/security/authorization /+&amp;quot;[accessType='Allow',users='*',roles='*',permissions='Read, Write']&amp;quot; /commit:apphost&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span class="InlineCode"&gt;&lt;/span&gt;He wanted to know if there was a PowerShell equivalent. Sure, you could use the appcmd directly from powershell, but if you're going to use the command line for everything, then what's the use of PowerShell?&lt;/p&gt;  &lt;p&gt;The section in applicationhost.config that we want to edit is the following:&lt;/p&gt;  &lt;div class="DebugSample"&gt;&amp;lt;location path=&amp;quot;FTPFolder&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;system.ftpServer&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;security&amp;gt;     &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;lt;authorization&amp;gt;     &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;lt;add accessType=&amp;quot;Allow&amp;quot; users=&amp;quot;?&amp;quot; permissions=&amp;quot;Read, Write&amp;quot; /&amp;gt;     &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;lt;/authorization&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/security&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/system.ftpServer&amp;gt;     &lt;br /&gt;&amp;lt;/location&amp;gt;&lt;/div&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;System Specs&lt;/h2&gt;  &lt;p&gt;As you might have noticed from the screenshots already he was Running Windows 2008 with &lt;a href="http://learn.iis.net/page.aspx/263/installing-and-troubleshooting-ftp7/"&gt;FTP 7&lt;/a&gt; installed. He also had the &lt;a href="http://learn.iis.net/page.aspx/429/installing-the-iis-70-powershell-provider/"&gt;IIS 7.0 PowerShell Provider&lt;/a&gt; installed.&lt;/p&gt;  &lt;h1&gt;Troubleshooting&lt;/h1&gt;  &lt;p&gt;There are a lot of cool things you can do with the WebSites using the IIS7 PowerShell provider. Below is a sample copied from &lt;a href="http://learn.iis.net/page.aspx/436/changing-simple-configuration-settings-in-configuration-sections/"&gt;iis.net&lt;/a&gt;. To use it properly, go to an IIS directory such as IIS:\DemoSite\DemoApp:&lt;/p&gt;  &lt;div class="SampleCode"&gt;$winAuth = Get-WebConfiguration -filter /system.webServer/security/authentication/windowsAuthentication    &lt;br /&gt;$winAuth.enabled = $false     &lt;br /&gt;$winAuth | set-Webconfiguration -filter /system.webServer/security/authentication/windowsAuthentication -PSPath IIS:\ -location &amp;quot;DemoSite/DemoApp&amp;quot;     &lt;br /&gt;&lt;/div&gt;  &lt;p&gt;So judging from the sample above we should simply have to set anonymousAuthentication.enabled = $true or something like that. Unfortunately this isn't the case. If you try to access the section of applicationhost.config that we're attempting to edit (see above) you will see that we don't have any applicable properties for the object. &lt;span class="InlineCode"&gt;$ftpAuth = Get-WebConfiguration -filter /system.ftpServer/security/authorization&lt;/span&gt; will not throw any exceptions, but using TAB to cycle through the properties of $ftpAuth will show us no immediate properties or methods of use. &lt;/p&gt;  &lt;h1&gt;Solution&lt;/h1&gt;  &lt;p&gt;The solution in this scenario is to use the Add-WebConfiguration cmdlet. The applicationhost.config can easily be translated to a valid Add-WebConfiguration call:&lt;/p&gt;  &lt;div class="SampleCode"&gt;Add-WebConfiguration &amp;quot;/system.ftpServer/security/authorization&amp;quot;&amp;#160; -value @{accessType=&amp;quot;Allow&amp;quot;;users=&amp;quot;?&amp;quot;;permissions=3} -PSPath IIS:\ -location FTPFolder&lt;/div&gt;  &lt;p&gt;The only thing that sticks out as being out of the ordinary is the permissions=3 setting. Why isn't it &amp;quot;Read, Write&amp;quot;? Actually, passing &amp;quot;Read, Write&amp;quot; as a parameter will not work. It will leave the permissions setting blank. &amp;quot;Read&amp;quot; or &amp;quot;Write&amp;quot; &lt;em&gt;only&lt;/em&gt; will work, but not both together. I've tried figuring out if there's a valid way of passing both arguments, but so far I've drawn blanks. I've tried putting them in an array {&amp;quot;Read&amp;quot;;&amp;quot;Write&amp;quot;}, passing them as &amp;quot;ReadWrite&amp;quot;, &amp;quot;Read;Write&amp;quot;, &amp;quot;Read+Write&amp;quot; etc. but the only way I've found so far is to pass the value 3 which is the obvious sum of the two enum values for Read and Write.&lt;/p&gt;  &lt;p&gt;Later! / Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8973569" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/IIS7/">IIS7</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>PowerShell - Editing permissions on a file or folder</title><link>http://blogs.msdn.com/b/johan/archive/2008/10/01/powershell-editing-permissions-on-a-file-or-folder.aspx</link><pubDate>Wed, 01 Oct 2008 15:52:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8971522</guid><dc:creator>JohanSt</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8971522</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/10/01/powershell-editing-permissions-on-a-file-or-folder.aspx#comments</comments><description>&lt;p&gt;I got the following question from a reader the other day:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I've been trying to figure out how to change permissions on a folder in PowerShell. I've looked at the Get-Acl and Set-Acl, but I can only use them to copy the settings from a pre-existing object. How do I manually configure permissions?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This is actually a quite common question, so I thought I'd write a quick post on the subject.&lt;/p&gt;  &lt;h1&gt;Get-Acl and Set-Acl&lt;/h1&gt;  &lt;p&gt;To quote the PowerShell documentation &amp;quot;Get-Acl &lt;em&gt;gets&lt;/em&gt; the security descriptor for a resource, such as a file or registry key.&amp;quot; while &amp;quot;Set-Acl &lt;em&gt;changes&lt;/em&gt; the security descriptor of a specified resource, such as a file or a registry key.&amp;quot; In other words; if you want Folder_A to have the exact same permissions as Folder_B, then you simply copy the Access Control List (ACL) of Folder_B and &amp;quot;paste&amp;quot; it onto Folder_A.&lt;/p&gt;  &lt;div class="SampleCode"&gt;   &lt;pre&gt;$Acl = Get-Acl &amp;quot;C:\Folder_B&amp;quot;
Set-Acl &amp;quot;C:\Folder_A&amp;quot; $Acl&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So far, so good.&lt;/p&gt;

&lt;h1&gt;Changing the ACL&lt;/h1&gt;

&lt;p&gt;Okay, so you want to change the ACL. Here's some sample code for how to do that:&lt;/p&gt;

&lt;div class="SampleCode"&gt;
  &lt;pre&gt;New-Item -type directory -path C:\MyFolder
$Acl = Get-Acl &amp;quot;C:\MyFolder&amp;quot;
$Ar = New-Object  system.security.accesscontrol.filesystemaccessrule(&amp;quot;username&amp;quot;,&amp;quot;FullControl&amp;quot;,&amp;quot;Allow&amp;quot;)
$Acl.SetAccessRule($Ar)
Set-Acl &amp;quot;C:\MyFolder&amp;quot; $Acl&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, first we create a new folder. We then copy the ACL of that folder. We then create a new AccessRule that gives &amp;quot;username&amp;quot; full control. We then add this AccessRule to the ACL, and finally we reapply the new, altered ACL to the folder.&lt;/p&gt;

&lt;p&gt;If we wanted to we could also have used &lt;span class="InlineCode"&gt;$Acl.RemoveAccessRule($Ar)&lt;/span&gt; or possibly &lt;span class="InlineCode"&gt;$Acl.RemoveAccessRuleAll()&lt;/span&gt; as well.&lt;/p&gt;

&lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8971522" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Script/">Script</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>PowerShell - Automatically organizing your mp3-collection</title><link>http://blogs.msdn.com/b/johan/archive/2008/09/23/powershell-automatically-organizing-your-mp3-collection.aspx</link><pubDate>Tue, 23 Sep 2008 14:53:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8962147</guid><dc:creator>JohanSt</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8962147</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/09/23/powershell-automatically-organizing-your-mp3-collection.aspx#comments</comments><description>&lt;p&gt;Is your mp3-collection perfectly sorted? I know mine wasn't. I thought I'd address that while creating a pretty good demo-script to show some basic filtering, script structures, etc. Since I also wanted the script to extract the metadata from every file in my collection I had to use the Shell.Application Com-object as well. All in all I think it turned out pretty well.&lt;/p&gt;  &lt;p&gt;NOTE:&lt;/p&gt;  &lt;p&gt;This script is provided completely as is. It is not an official product in any way and I take no responsibility for any harm it may cause.&lt;/p&gt;  &lt;p&gt;Please note that certain metadata editors that integrate directly into the Shell may cause some severe confusion in the metadata, so I'd recommend disabling them before trying. Off course I would also recommend making a backup copy of the music library before surrendering it to the mercy of PowerShell.&lt;/p&gt;  &lt;p&gt;If you're new to PowerShell and haven't done so already I'd recommend looking at my earlier posts on the subject:    &lt;br /&gt;&lt;a href="http://blogs.msdn.com/johan/archive/2008/05/28/powershell-an-introduction-part-i.aspx"&gt;PowerShell - An introduction, Part I&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blogs.msdn.com/johan/archive/2008/08/25/powershell-an-introduction-part-ii.aspx"&gt;PowerShell - An introduction, Part II&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;The script    &lt;br /&gt;&lt;/h1&gt;  &lt;div class="SampleCode"&gt;   &lt;pre&gt;Param([String] $Folder)
$INVALIDCHARS = [System.IO.Path]::GetInvalidPathChars() + &amp;quot;/&amp;quot;, &amp;quot;\&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;?&amp;quot;, &amp;quot;:&amp;quot;
$MUSICATTRIBS = &amp;quot;*.m4a&amp;quot;, &amp;quot;*.m4b&amp;quot;, &amp;quot;*.mp3&amp;quot;, &amp;quot;*.mp4&amp;quot;, &amp;quot;*.wma&amp;quot;, &amp;quot;*.flc&amp;quot;
$PLAYLISTATTRIBS = &amp;quot;*.m3u&amp;quot;, &amp;quot;*.zpl&amp;quot;
$ALLATTRIBS = $MUSICATTRIBS + $PLAYLISTATTRIBS&lt;br /&gt;$PLAYLISTSFOLDER = &amp;quot;Playlists&amp;quot;
$objShell = New-Object -ComObject Shell.Application
$iTotalFiles = 0
$iCurrentFile = 0

function checkFolderName($FolderName)
{
	&lt;font color="#00ff00"&gt;&lt;font color="#008000"&gt;# Make sure the folder doesn't contain any invalid characters&lt;/font&gt;
&lt;/font&gt;
	if(!$FolderName) { $FolderName = &amp;quot;Unknown&amp;quot; }
	$INVALIDCHARS | % {$FolderName = $FolderName.replace($_, &amp;quot;&amp;quot;)}
	return $FolderName
}



function MoveFiles($startDir)
{
	Write-Host &amp;quot;Indexing playlists...&amp;quot;
	
	&lt;font color="#008000"&gt;# Do a recursive DIR in the starting directory, include everything with the attributes of a playlist.
	# Filter the result by excluding everything that is a Container (folder)
&lt;/font&gt;	$dirResult = get-childitem -force -path $startDir -recurse -include $PLAYLISTATTRIBS | where{! $_.PSIsContainer}
	if($dirResult)
	{
		Write-Host &amp;quot;Moving playlists...&amp;quot;

		foreach($dirItem in $dirResult)
		{
			move-item $dirItem.FullName ($PLAYLISTSFOLDER + &amp;quot;\&amp;quot; + $dirItem.Name)
		}
	}
	Write-Host &amp;quot;Indexing music...&amp;quot;

&lt;font color="#008000"&gt;	# Do a recursive DIR in the starting directory, include everything with the attributes of a music file.
	# Again we filter the result by excluding everything that is a Container.
&lt;/font&gt;	$dirResult = get-childitem -force -path $startDir -recurse -include $MUSICATTRIBS | where{! $_.PSIsContainer}
	
&lt;font color="#008000"&gt;	# Make a note of how many hits we got, so we can show the progress to the client.
&lt;/font&gt;	$iTotalFiles = $dirResult.Count
	if($dirResult)
	{
		foreach($dirItem in $dirResult)
		{
&lt;font color="#008000"&gt;			# Up the counter for how many files we've processed so that we can show progress
&lt;/font&gt;			$iCurrentFile +=1

&lt;font color="#008000"&gt;			# Get the metadata for the file
&lt;/font&gt;			$fileData = getMP3MetaData($dirItem.FullName)
			
&lt;font color="#008000"&gt;			# Find the path where we the song should be stored
&lt;/font&gt;			$ArtistPath = $fileData[&amp;quot;Album Artist&amp;quot;]
			if (!$ArtistPath) { $ArtistPath = $fileData[&amp;quot;Artists&amp;quot;] }
			if (!$ArtistPath) { $ArtistName = &amp;quot;Unknown&amp;quot; }

&lt;font color="#008000"&gt;			# Make shure it's a valid path
&lt;/font&gt;			$ArtistPath = checkFolderName($ArtistPath)
			$AlbumPath = checkFolderName($fileData.Album)
			$ArtistPath = join-path $startDir $ArtistPath 
			$AlbumPath = join-path $ArtistPath $AlbumPath

&lt;font color="#008000"&gt;			# Check if the file should be moved
&lt;/font&gt;			if($dirItem.DirectoryName -ne $AlbumPath)
			{
				if(!(test-path $ArtistPath)) &lt;font color="#008000"&gt;# If the Artist folder doesn't exist
&lt;/font&gt;				{
					MKDIR $ArtistPath | out-null
				}
				if(!(test-path $AlbumPath)) &lt;font color="#008000"&gt;# If the Album folder doesn't exist&lt;/font&gt;
				{
					MKDIR $AlbumPath | out-null
				}
				move-item $dirItem.FullName ($AlbumPath + &amp;quot;\&amp;quot; + $dirItem.Name)
			}

&lt;font color="#008000"&gt;			# Show progress
&lt;/font&gt;			$percentage = ([int](($iCurrentFile / $iTotalFiles)*100))
			cls
			Write-Host &amp;quot;$percentage% ($iCurrentFile files of $iTotalFiles) complete&amp;quot;
		}
	}
}


function removeEmptyFolders($startDir)
{
&lt;font color="#008000"&gt;	# Get all folders and subfolders
&lt;/font&gt;	$dirResult = Get-childitem $startDir -recurse | where{$_.PSIsContainer}
	if($dirResult)
	{
		foreach($dirItem in $dirResult)
		{
&lt;font color="#008000"&gt;			# If the folder is empty (Doesn't contain any music or playlists) it should be deleted
&lt;/font&gt;			if(isfolderempty($dirItem.FullName))
			{
&lt;font color="#008000"&gt;				# Check if the path is still valid, we may have deleted the folder already recursively.
&lt;/font&gt;				if(Test-Path $dirItem.FullName)
				{
					remove-item -path $dirItem.FullName -force -recurse
				}
			}
		}
	}
}

function removeOtherFiles($startDir)
{
&lt;font color="#008000"&gt;	# Get all non-music files (except *.jpg-files) and remove them 
&lt;/font&gt;	$dirResult = Get-childitem $startDir -recurse -exclude ($ALLATTRIBS + &amp;quot;*.jpg&amp;quot;) | where{! $_.PSIsContainer}
	if($dirResult)
	{
		foreach($dirItem in $dirResult)
		{
			if(Test-Path $dirItem.FullName)
			{
&lt;font color="#008000"&gt;				# Make sure the file still exists, and hasn't been deleted already
&lt;/font&gt;				remove-item -path $dirItem.FullName -force
			}
		}
	}
}

function isFolderEmpty($folderPath)
{
&lt;font color="#008000"&gt;	# Search for any remaining music items in the folder.&lt;/font&gt;
	if(Test-Path $folderPath)
	{
		$dirChildren = get-childitem -force -path $folderPath -recurse -include $ALLATTRIBS | where{! $_.PSIsContainer}
		if($dirChildren -ne $null)
		{
			return $false
		}
		else
		{
			return $true
		}
	}
	else
	{
&lt;font color="#008000"&gt;		# No use trying to delete the folder if it doesn't exist
&lt;/font&gt;		return $false
	}
}

function getMP3MetaData($path)
{
&lt;font color="#008000"&gt;	# Get the file name, and the folder it exists in
&lt;/font&gt;	$file = split-path $path -leaf
	$path = split-path $path
	$objFolder = $objShell.namespace($path)
	$objFile = $objFolder.parsename($file)
	$result = @{}
	0..266 | % {
		if ($objFolder.getDetailsOf($objFile, $_))
		{
			$result[$($objFolder.getDetailsOf($objFolder.items, $_))] = $objFolder.getDetailsOf($objFile, $_)
		}
	}
	return $result
}

&lt;font color="#008000"&gt;# MAIN FUNCTION&lt;/font&gt;

&lt;font color="#008000"&gt;# If no argument was passed, see if anything was piped to the function instead.&lt;/font&gt;
if (!$Folder)
{
	$input | % { $Folder = $_ }
}

&lt;font color="#008000"&gt;# Check if the path is valid, if not reset it to &amp;quot;&amp;quot;&lt;/font&gt;
if ($Folder) { if (!(Test-Path -path $Folder)) { $Folder = &amp;quot;&amp;quot; }}

&lt;font color="#008000"&gt;# Since no valid path was given, prompt the user for a proper path.&lt;/font&gt;
while (!$Folder)
{
	&amp;quot;Please enter the full path to the folder where you wish to rearrange your MP3's&amp;quot;
	$Folder = Read-Host
	if ($Folder) { if (!(Test-Path -path $Folder)) { $Folder = &amp;quot;&amp;quot; }}
}

&lt;font color="#008000"&gt;# Make sure we have a folder to store the playlists in.&lt;/font&gt;
$PLAYLISTSFOLDER = join-path $Folder $PLAYLISTSFOLDER
if(!(test-path $PLAYLISTSFOLDER)) # If the Playlists folder doesn't exist
{
	MKDIR $PLAYLISTSFOLDER | out-null
}

&lt;font color="#008000"&gt;# Now that everything is ready, begin rearranging the files.&lt;/font&gt;
MoveFiles($Folder)
removeEmptyFolders($Folder)
removeOtherFiles($Folder)&lt;/pre&gt;
&lt;/div&gt;

&lt;h1&gt;&amp;#160;&lt;/h1&gt;

&lt;h1&gt;&lt;/h1&gt;

&lt;h1&gt;Running the script&lt;/h1&gt;

&lt;p&gt;So, how do you run this script?&lt;/p&gt;

&lt;p&gt;It's quite easy. The first step would be to copy it into notepad save it with a .ps1 extension and open up PowerShell&lt;/p&gt;

&lt;h2&gt;Execution policy&lt;/h2&gt;

&lt;p&gt;If this is the first time you try to execute a script from PowerShell you will most likely have to change the execution policy for PowerShell. I'd recommend setting it to RemoteSigned. This (obviously) means that all remote scripts must be signed or PowerShell will refuse to execute them. To change the execution policy simply type:&lt;/p&gt;

&lt;div class="SampleCode"&gt;Set-ExecutionPolicy RemoteSigned&lt;/div&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;If you're uncertain what your execution policy setting is you simply type:&lt;/p&gt;

&lt;div class="SampleCode"&gt;Get-ExecutionPolicy&lt;/div&gt;

&lt;p&gt;Okay, having changed that we can now execute the script. If you saved the script in a folder that is in your system path you only need to type the filename of the .ps1 file. (The .ps1 is optional) So, if you saved it as RearrangeMP3s.ps1 you'd write &lt;span class="InlineCode"&gt;RearrangeMP3s&lt;/span&gt; and press enter &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h1&gt;Breakdown&lt;/h1&gt;

&lt;p&gt;Okay, so let's take a look at the separate parts of the script.&lt;/p&gt;

&lt;h2&gt;Initial variables and constants&lt;/h2&gt;

&lt;p&gt;First we declare the parameters we're going to use. In this case it's just one: $Folder.&lt;/p&gt;

&lt;p&gt;After that we have some constants. You may want to change $MUSICATTRIBS or $PLAYLISTATTRIBS to include, or remove, extensions based on your needs. $PLAYLISTSFOLDER is a constant which indicates in which subfolder you wish to store your playlists.&lt;/p&gt;

&lt;p&gt;Finally we have some variables. $objShell is used for file system operations, and rather than creating a new object all the time I'd rather have a global one. $iTotalFiles and $iCurrentFile are two integers used to create a progress indicator.&lt;/p&gt;

&lt;h2&gt;Functions&lt;/h2&gt;

&lt;p&gt;After the initial variables come the sub functions called by the main function. To see what each individual function does I'd recommend looking at the comments. I've prioritized readability over minimum number of keystrokes, so yes, instead of writing:&lt;/p&gt;

&lt;div class="SampleCode"&gt;
  &lt;pre&gt;foreach($dirItem in $dirResult)
{
	move-item $dirItem.FullName ($PLAYLISTSFOLDER + &amp;quot;\&amp;quot; + $dirItem.Name)
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I could have written&lt;/p&gt;

&lt;div class="SampleCode"&gt;
  &lt;pre&gt;$dirResult | % { mv $_.FullName ($PLAYLISTSFOLDER + &amp;quot;\&amp;quot; + $_.Name) }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;But in this case I think that would have been counterproductive.&lt;/p&gt;

&lt;h2&gt;The main function&lt;/h2&gt;

&lt;p&gt;Finally we have the main function. It is written last in the script. Why is that? Well, actually PowerShell is the most sequential language you'll ever come across. It will not bother to check the entire script for function declarations. Instead it will go through the script one line at a time. This means that the following script will not work:&lt;/p&gt;

&lt;div class="SampleCode"&gt;
  &lt;pre&gt;SayHello

function SayHello
{
	Write-Host &amp;quot;Hello World&amp;quot;
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When you call SayHello in the sample above the function has not yet been declared, so PowerShell will throw an exception in your face saying that SayHello is unrecognized.&lt;/p&gt;

&lt;h1&gt;&lt;/h1&gt;

&lt;h1&gt;Footnote&lt;/h1&gt;

&lt;p&gt;There is actually a &lt;em&gt;supported&lt;/em&gt; way of achieving the very same thing, but where's the fun in that?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open up Windows Media Player&lt;/li&gt;

  &lt;li&gt;Go to Options -&amp;gt; Library and tick the checkbox for &amp;quot;Rearrange music in rip folder&amp;quot;&lt;/li&gt;

  &lt;li&gt;Go to the &amp;quot;Rip Music&amp;quot;-tab&lt;/li&gt;

  &lt;li&gt;Make sure the path is correct in the &amp;quot;Rip music to this location&amp;quot;-section&lt;/li&gt;

  &lt;li&gt;Click OK&lt;/li&gt;

  &lt;li&gt;Select &lt;em&gt;all&lt;/em&gt; files in the library&lt;/li&gt;

  &lt;li&gt;Right-click and choose the &amp;quot;Advanced Tag Editor&amp;quot;-option&lt;/li&gt;

  &lt;li&gt;Do not change anything. Simply click Apply&lt;/li&gt;

  &lt;li&gt;Windows Media Player will now rearrange all the files using your Rip settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8962147" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Script/">Script</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Sample+Code/">Sample Code</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>PowerShell - An introduction, Part II</title><link>http://blogs.msdn.com/b/johan/archive/2008/08/25/powershell-an-introduction-part-ii.aspx</link><pubDate>Mon, 25 Aug 2008 14:22:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8893706</guid><dc:creator>JohanSt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8893706</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/08/25/powershell-an-introduction-part-ii.aspx#comments</comments><description>&lt;p&gt;This is a continuation of &lt;a href="http://blogs.msdn.com/johan/archive/2008/05/28/powershell-an-introduction-part-i.aspx"&gt;part I&lt;/a&gt;. If you haven't read it I suggest at least going through the summary at the end of the post.&lt;/p&gt;  &lt;h1&gt;Working with Drives&lt;/h1&gt;  &lt;p&gt;In your basic command prompt you have the normal file system drives that you use to access your hard-drive, floppy, DVD, USB-stick, network shares etc. PowerShell uses this established interface to access other data sources as well. The following providers are accessible by default through drives in PowerShell 1.0:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Registry (HKLM: or HKCU:) &lt;/li&gt;    &lt;li&gt;Certificate store (Cert:) &lt;/li&gt;    &lt;li&gt;Environment variables (Env:) &lt;/li&gt;    &lt;li&gt;Aliases (Alias:) &lt;/li&gt;    &lt;li&gt;Functions (Function:) &lt;/li&gt;    &lt;li&gt;Variables (Variable:) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;When you install extensions for like the one fore IIS, etc. you usually get another drive accessible where you can look at the current webapplications and check their properties.&lt;/p&gt;  &lt;h2&gt;Navigating&lt;/h2&gt;  &lt;p&gt;Selecting one of the PowerShell drives is easy. It is &lt;em&gt;almost&lt;/em&gt; like in MS-DOS.&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt;CD HKLM:    &lt;br /&gt;PS HKLM:\&amp;gt; DIR&lt;/div&gt;  &lt;p&gt;You can use the same commands as you'd do in MS-DOS, such as CD, DIR, MKDIR, etc.&lt;/p&gt;  &lt;p&gt;To get a certain property for a registry key, (or a regular folder for that matter) you use the Get-ItemProperty cmdlet.&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS HKLM:\&amp;gt; CD system    &lt;br /&gt;PS HKLM:\system&amp;gt; CD CurrentControlSet\Control     &lt;br /&gt;PS HKLM:\system\CurrentControlSet\Control&amp;gt; Get-ItemProperty CrashControl     &lt;br /&gt;&amp;#160; &lt;br /&gt;PSPath&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\system\CurrentControlSet\Control\CrashControl     &lt;br /&gt;PSParentPath&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\system\CurrentControlSet\Control     &lt;br /&gt;PSChildName&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : CrashControl     &lt;br /&gt;PSDrive&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : HKLM     &lt;br /&gt;PSProvider&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Microsoft.PowerShell.Core\Registry     &lt;br /&gt;AutoReboot&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : 1     &lt;br /&gt;CrashDumpEnabled : 2     &lt;br /&gt;Overwrite&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : 1     &lt;br /&gt;LogEvent&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : 1     &lt;br /&gt;DumpFile&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : C:\Windows\MEMORY.DMP     &lt;br /&gt;MinidumpDir&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : C:\Windows\Minidump&lt;/div&gt;  &lt;p&gt;All in all it's more or less the same working with Aliases or Environment variables. Note the following difference in output, though:&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS Env:\&amp;gt; Dir Env:PROCESSOR_ARCHITECTURE    &lt;br /&gt;&amp;#160; &lt;br /&gt;Name&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     &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; -----     &lt;br /&gt;PROCESSOR_ARCHITECTURE&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AMD64     &lt;br /&gt;&amp;#160; &lt;br /&gt;PS Env:\&amp;gt; $Env:PROCESSOR_ARCHITECTURE     &lt;br /&gt;AMD64     &lt;br /&gt;PS Env:\&amp;gt;&lt;/div&gt;  &lt;p&gt;Did you note how putting a $-sign before the variable name gave us the value of the variable instead of a complete object? This brings us quite nicely to the subject of variables.&lt;/p&gt;  &lt;h1&gt;Variables&lt;/h1&gt;  &lt;p&gt;Variables aren't that tricky to work with. They do not need to be pre-initiated. They do, however, require a $ to be identified as variables. Otherwise you get the following error message:&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $Name = &amp;quot;Johan&amp;quot;    &lt;br /&gt;PS C:\&amp;gt; Name = &amp;quot;Johan&amp;quot;     &lt;br /&gt;&lt;font color="#ff0000"&gt;The term 'Name' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.      &lt;br /&gt;At line:1 char:5       &lt;br /&gt;+ Name&amp;#160; &amp;lt;&amp;lt;&amp;lt;&amp;lt; = &amp;quot;Johan&amp;quot;&lt;/font&gt;     &lt;br /&gt;PS C:\&amp;gt;&lt;/div&gt;  &lt;p&gt;To display the value of a variable you simply type the name of the variable and PowerShell kindly returns the contents&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $Name    &lt;br /&gt;Johan&lt;/div&gt;  &lt;p&gt;When it comes to strings, you can choose for yourself if you want to use double quotes or single quotes, but there is one minor difference: &lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $str1 = &amp;quot;Hello&amp;quot;    &lt;br /&gt;PS C:\&amp;gt; $str2 = &amp;quot;World!&amp;quot;     &lt;br /&gt;PS C:\&amp;gt; $strCombo1 = &amp;quot;$str1 $str2&amp;quot;     &lt;br /&gt;PS C:\&amp;gt; $strCombo2 = '$str1 $str2'     &lt;br /&gt;PS C:\&amp;gt; $strCombo1     &lt;br /&gt;Hello World!     &lt;br /&gt;PS C:\&amp;gt; $strCombo2     &lt;br /&gt;$str1 $str2     &lt;br /&gt;PS C:\&amp;gt; &lt;/div&gt;  &lt;p&gt;As you can see, a variable within double quotes will be evaluated, while within single quotes it will be interpreted literally.&lt;/p&gt;  &lt;p&gt;Apart from strings you can also store integers and dates. Integers do not need delimiters and dates are most easily created using the Get-Date function&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $birthday = 11/15/1973&lt;/div&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;Arrays&lt;/h1&gt;  &lt;p&gt;Declaring Arrays is a breeze. PowerShell will automatically &lt;em&gt;Split&lt;/em&gt; any comma-separated sequence of values so creating a arrays is as easy as this:&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $Colors = &amp;quot;Red&amp;quot;, &amp;quot;Green&amp;quot;, &amp;quot;Blue&amp;quot;&lt;/div&gt;  &lt;p&gt;The arrays are also dynamic by default, so adding values to them is a simple matter as well.&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $Colors += &amp;quot;Cyan&amp;quot;, &amp;quot;Magenta&amp;quot;, &amp;quot;Yellow&amp;quot;&lt;/div&gt;  &lt;p&gt;Creating two-dimensional arrays are done by declaring each row of the array as a one-dimensional array and then adding them to &lt;em&gt;another&lt;/em&gt; array:&lt;/p&gt;  &lt;div class="SampleCode"&gt;PS C:\&amp;gt; $arr1 = 1, 2, 3    &lt;br /&gt;PS C:\&amp;gt; $arr2 = &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;     &lt;br /&gt;PS C:\&amp;gt; $arr3 = $arr1, $arr2     &lt;br /&gt;PS C:\&amp;gt; $arr3[0][0]     &lt;br /&gt;1     &lt;br /&gt;PS C:\&amp;gt; $arr3[1][1]     &lt;br /&gt;B     &lt;br /&gt;PS C:\&amp;gt;&lt;/div&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;User input &lt;/h1&gt;  &lt;p&gt;Finally, to get dynamic user input you can use the Read-Host cmdlet.&lt;/p&gt;  &lt;div class="SampleCode"&gt;$Name = Read-Host &amp;quot;What is your name?&amp;quot;&lt;/div&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;Summary&lt;/h1&gt;  &lt;p&gt;Okay, so to summarize we have now covered the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;PowerShell uses system drives to access the registry, environment variables, etc.&lt;/li&gt;    &lt;li&gt;Variables are preceded with a $&lt;/li&gt;    &lt;li&gt;To access the value of a variable, simply type it's name.&lt;/li&gt;    &lt;li&gt;Arrays are comma-separated lists of variables&lt;/li&gt;    &lt;li&gt;User input can be handled by the Read-Host cmdlet&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Next post will probably cover some script logic such as if-clauses, looping, etc. After that I think it will be time to post some sample scripts.&lt;/p&gt;  &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8893706" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>Back in business</title><link>http://blogs.msdn.com/b/johan/archive/2008/08/22/back-in-business.aspx</link><pubDate>Fri, 22 Aug 2008 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8887957</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8887957</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/08/22/back-in-business.aspx#comments</comments><description>&lt;P&gt;Okay, after a summer break that no doubt got a little longer than expected I am now I'm now back in the saddle again.&lt;/P&gt;
&lt;P&gt;Next post will most likely be a follow-up on the PowerShell post I wrote a while back. Stay tuned.&lt;/P&gt;
&lt;P&gt;/ Johan&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8887957" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Off+topic/">Off topic</category></item><item><title>The first thing you should do after setting up an IIS7-server</title><link>http://blogs.msdn.com/b/johan/archive/2008/05/29/the-first-thing-you-should-do-after-setting-up-an-iis7-server.aspx</link><pubDate>Thu, 29 May 2008 15:14:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8557977</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8557977</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/05/29/the-first-thing-you-should-do-after-setting-up-an-iis7-server.aspx#comments</comments><description>&lt;p&gt;As you're probably well aware IIS7 relies heavily on a master configuration file named ApplicationHost.config. Now, instead of using a history file like IIS6 did, IIS7 will check this file every 2 minutes to see if it's changed. If the file has been updated, then a backup copy of the old .config will be stored in the inetpub\history-directory.&lt;/p&gt; &lt;h1&gt;Configuration history&lt;/h1&gt; &lt;p&gt;This is really cool and a very useful feature. There's only one little caveat in my opinion and that's the fact that by default IIS7 will only save up to 10 backups. All the other backups will be discarded. This means that if you're spending 20 minutes fiddling with the settings in ApplicationHost.config you will quite likely have overwritten all your old backups. Now, if something goes wrong at that point and you decide to spend another 20 minutes trying to fix this problem by &lt;em&gt;further &lt;/em&gt;editing the ApplicationHost.config you will &lt;em&gt;surely&lt;/em&gt; have overwritten the backups.&lt;/p&gt; &lt;p&gt;In a worst case scenario you might even have gone from &lt;em&gt;Healthy Server &lt;/em&gt;to &lt;em&gt;Unstable Server &lt;/em&gt;to &lt;em&gt;Server Down &lt;/em&gt;and you now find that you aren't even able to restore it to the &lt;em&gt;Unstable &lt;/em&gt;state.&lt;/p&gt; &lt;p&gt;My suggestion is to increase the default number of backups to 100, or why not 1000? You can then feel certain that any backups taken aren't overwritten when you try to undo the very same changes. Here's how you do it:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Go to %windir%\system32\inetsrv\config\  &lt;li&gt;Open applicationHost.config in notepad  &lt;li&gt;Locate the system.applicationHost section group  &lt;li&gt;Add the following item to the section group:&lt;br&gt;&lt;span class="InlineCode"&gt;&amp;lt;configHistory maxHistories="100" period="00:02:00" /&amp;gt;&lt;/span&gt;&lt;br&gt;(Naturally the maxHistories value can be whichever value you prefer)  &lt;li&gt;Save&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;To restore one of the previous configurations, simply go to inetpub\history\cfgHistory_[nnnnnnnnnn] and copy the config from there, or use appcmd. (See below) &lt;/p&gt; &lt;h1&gt;Backup using appcmd&lt;/h1&gt; &lt;p&gt;Now that we've done this there is one more thing I'd strongly recommend doing:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Open up a command-line with administrative priviliges  &lt;li&gt;Go to %windir%\system32\inetsrv  &lt;li&gt;Run "&lt;span class="InlineCode"&gt;appcmd add backup "[Name of your backup]"&lt;/span&gt;"&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;What you've done now is to create a manual backup of your current config. It's always good to have a decent (and persistent) restore point to return to.&lt;/p&gt; &lt;p&gt;If you wish to restore this backup you simply use the following syntax: "&lt;span class="InlineCode"&gt;appcmd restore backup "[Name of your backup]"&lt;/span&gt;". You can also delete a backup using the "delete" keyword, or you can list all backups, including the ones generated by the Configuration history, like this: "&lt;span class="InlineCode"&gt;appcmd list backup&lt;/span&gt;"&lt;/p&gt; &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johan/images/8557875/original.aspx"&gt; &lt;/p&gt; &lt;p&gt;Okay, so now we have made sure we have some extensive automatic backups in place which might save us a lot of headaches later on.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Later! / Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8557977" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/IIS7/">IIS7</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Did+you+know_3F00_/">Did you know?</category></item><item><title>PowerShell – An introduction, Part I</title><link>http://blogs.msdn.com/b/johan/archive/2008/05/28/powershell-an-introduction-part-i.aspx</link><pubDate>Wed, 28 May 2008 14:53:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8556478</guid><dc:creator>JohanSt</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8556478</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/05/28/powershell-an-introduction-part-i.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;Over the past months I’ve been holding a couple of workshops on PowerShell. It’s quite an interesting topic, but not something I originally thought would be suitable for this blog and its web-development theme. Still, having given this a bit more thought I decided that there are so many useful features and cmdlets that could be of great value when hosting a web site or two that I should reconsider.&lt;/p&gt; &lt;p&gt;This first post will be a brief introduction for those who’ve never touched PowerShell before. Later posts will probably be more hands-on and less theoretical. I’ll gladly receive any thoughts or comments you may have.&lt;/p&gt; &lt;h1&gt;Installing&lt;/h1&gt; &lt;p&gt;PowerShell can be downloaded from the Microsoft web site. Simply point your browser to &lt;a href="http://www.microsoft.com/powershell"&gt;http://www.microsoft.com/powershell&lt;/a&gt; and you’ll be set in no time. Apart from the executables you’ll find a lot of useful links, like the one to the &lt;a href="http://blogs.msdn.com/PowerShell/"&gt;PowerShell team blog&lt;/a&gt; and the &lt;a href="http://learn.iis.net/Themes/IIS/Pages/search.aspx?q=powershell"&gt;IIS 7.0 PowerShell Provider&lt;/a&gt;.&lt;/p&gt; &lt;h1&gt;Basic syntax&lt;/h1&gt; &lt;p&gt;Okay, having installed PowerShell we’re now ready to try some basic commands.&lt;/p&gt; &lt;h2&gt;Echoing text&lt;/h2&gt; &lt;p&gt;Any object not used in an assignment or operation will be echoed to the screen. This means that if we simply type a string like this:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\&amp;gt;“Hello World”&lt;br&gt;Hello World&lt;/div&gt; &lt;p&gt;It will be displayed on the screen. (Without the quotes.) The same goes for numbers, so by typing an equation you’ll be given the result:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\&amp;gt;1 + 1&lt;br&gt;2&lt;/div&gt; &lt;p&gt;If you type in an array PowerShell will echo it one line at a time:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\&amp;gt;“foo”, “bar”, “bletch”, “fum”&lt;br&gt;foo&lt;br&gt;bar&lt;br&gt;bletch&lt;br&gt;fum&lt;/div&gt; &lt;p&gt;Basically you could say that any object will, unless told otherwise, be displayed on screen using its default formatting. The default formatting is defined by the object itself.&lt;/p&gt; &lt;h2&gt;Calling executables&lt;/h2&gt; &lt;p&gt;Running an executable is more or less as easy as in the regular command shell. At least if the .exe is in the PATH. For any executable &lt;em&gt;not&lt;/em&gt; in the PATH you'll need to write the full path of the .exe for it to successfully execute. This may seem like a hassle, but this behavior is by design and was implemented in order to prevent you from accidentally executing an .exe.&lt;/p&gt; &lt;h1&gt;Cmdlets&lt;/h1&gt; &lt;p&gt;Cmdlets (pronounced "command-lets") are PowerShell-specific commands. They follow a strict naming standard of &lt;em&gt;verb-noun&lt;/em&gt;, (for example "get-date" or "set-location").&lt;/p&gt; &lt;h2&gt;Get-Help&lt;/h2&gt; &lt;p&gt;This a command that you'll use quite a lot. &lt;span class="InlineCode"&gt;Get-Help &amp;lt;cmdlet&amp;gt;&lt;/span&gt; will display some generic information about the cmdlet in question. Using various switches such as "-detailed", "-examples" or "-full" you can then get more detailed information on the cmdlet in question. For example:&lt;/p&gt; &lt;div class="SampleCode"&gt;Get-Help Get-Date -examples&lt;/div&gt; &lt;p&gt;This will show you the generic information on get-date as well as some sample code.&lt;/p&gt; &lt;h2&gt;Set-Location&lt;/h2&gt; &lt;p&gt;Set-Location is the PowerShell equivalent to the old MS-DOS command "CD". Some examples are:&lt;/p&gt; &lt;div class="SampleCode"&gt;Set-Location ..&lt;br&gt;Set-Location C:\Windows\&lt;br&gt;Set-Location D:&lt;/div&gt; &lt;h2&gt;&lt;/h2&gt; &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; &lt;h2&gt;Aliases&lt;/h2&gt; &lt;p&gt;Actually you can write CD in PowerShell too. By default PowerShell will set up an alias for you that points to the Set-Location cmdlet. This means that CD is just another name for Set-Location. If you want you can create your own aliases using the New-Alias cmdlet:&lt;/p&gt; &lt;div class="SampleCode"&gt;New-Alias gh Get-Help&lt;/div&gt; &lt;p&gt;This creates an alias named gh that points at Get-Help. If you type &lt;span class="InlineCode"&gt;Get-Help gh&lt;/span&gt; PowerShell will be smart enough to show you the documentation for the Get-Help cmdlet.&lt;/p&gt; &lt;h1&gt;Object orientation&lt;/h1&gt; &lt;p&gt;One of the cool things about PowerShell is that it is object oriented. This means that all the cmdlets return objects, which can, in turn, be passed on to another cmdlet. To illustrate this, let’s look at the DIR-command.&lt;/p&gt; &lt;h2&gt;Using DIR&lt;/h2&gt; &lt;p&gt;You can use DIR in PowerShell, but it is actually an alias for the get-childitem cmdlet. How can you tell? Use the get-command cmdlet:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\&amp;gt; get-command dir&lt;br&gt;&amp;nbsp;&lt;br&gt;CommandType&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Definition&lt;br&gt;-----------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----------&lt;br&gt;Alias&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dir&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Get-ChildItem&lt;/div&gt; &lt;p&gt;Since DIR in PowerShell is not the same thing as DIR in MS-DOS that means you can’t use all the switches you might be used to, for example DIR /w will not work.&lt;/p&gt; &lt;p&gt;So, what happens when you type DIR and press enter?&lt;/p&gt; &lt;p&gt;Well, first of all the get-childitem cmdlet is run. It looks in your present working directory, creates a collection of all the items there, and returns it. You can think of this collection as a big Excel Spreadsheet if you like.&lt;/p&gt; &lt;p&gt;Once the collection is returned to PowerShell it will be displayed on screen. This is because the default behavior for PowerShell when it comes to &lt;em&gt;any&lt;/em&gt; object is to display it on screen. We saw this earlier with strings, integers and arrays.&lt;/p&gt; &lt;p&gt;The collection will be displayed using a default presentation. This does not mean you will see all the information the object contains. If I run Get-ChildItem (DIR) on a folder I’ll get the standard information. Like so:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\Test&amp;gt; dir &lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Directory: Microsoft.PowerShell.Core\FileSystem::C:\Test &lt;br&gt;&amp;nbsp;&lt;br&gt;Mode&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LastWriteTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Length Name&lt;br&gt;----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -------------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ------ ----&lt;br&gt;-a---&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2008-05-28&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11:25&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 45568 Document.doc&lt;br&gt;-a---&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2008-05-26&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10:00&amp;nbsp;&amp;nbsp;&amp;nbsp; 8993629 Satisfaction.mp3&lt;br&gt;-a---&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2008-05-28&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11:25&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1599 Text.txt&lt;/div&gt; &lt;p&gt;Even though I get only text on screen the actual object returned is much more complex. I can demonstrate this by piping the object into another cmdlet.&lt;/p&gt; &lt;h1&gt;Piping&lt;/h1&gt; &lt;p&gt;A simple MS-DOS piping example would be &lt;span class="InlineCode"&gt;type file.txt | more&lt;/span&gt;. Actually you can use &lt;span class="InlineCode"&gt;more&lt;/span&gt; in PowerShell as well, but let’s look at another, more interesting cmdlet that we could pipe the object into; &lt;span class="InlineCode"&gt;Format-List&lt;/span&gt;.&lt;/p&gt; &lt;h2&gt;Format-List&lt;/h2&gt; &lt;p&gt;By default the output of Get-ChildItem is formatted in a table, but let’s say we want it as a list instead? No problem. Simply use the following syntax:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\Test&amp;gt; dir | format-list &lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Directory: Microsoft.PowerShell.Core\FileSystem::C:\Test &lt;br&gt;&amp;nbsp;&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Document.doc&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 45568&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp; : 2008-05-28 11:22:53&lt;br&gt;LastWriteTime&amp;nbsp; : 2008-05-28 11:25:26&lt;br&gt;LastAccessTime : 2008-05-28 11:25:26&lt;br&gt;VersionInfo&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;br&gt;&amp;nbsp;&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Satisfaction.mp3&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 8993629&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp; : 2008-05-28 11:24:33&lt;br&gt;LastWriteTime&amp;nbsp; : 2008-05-26 10:00:46&lt;br&gt;LastAccessTime : 2008-05-28 11:24:33&lt;br&gt;VersionInfo&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;br&gt;&amp;nbsp;&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Text.txt&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1599&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp; : 2008-05-28 11:22:53&lt;br&gt;LastWriteTime&amp;nbsp; : 2008-05-28 11:25:35&lt;br&gt;LastAccessTime : 2008-05-28 11:22:53&lt;br&gt;VersionInfo&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/div&gt; &lt;p&gt;We still have the default information, only presented in a different manner. Still, there is a lot more information we could get, by using the &lt;span class="InlineCode"&gt;–property&lt;/span&gt; switch. By simply using the following syntax: &lt;span class="InlineCode"&gt;dir | format-list –property *&lt;/span&gt; we get &lt;em&gt;all&lt;/em&gt; the properties of each and every item in the directory. The output is quite extensive:&lt;/p&gt; &lt;div class="SampleCode"&gt;PS C:\Test&amp;gt; dir | format-list -property * &lt;br&gt;&amp;nbsp;&lt;br&gt;PSPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test\Document.doc&lt;br&gt;PSParentPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test&lt;br&gt;PSChildName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Document.doc&lt;br&gt;PSDrive&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C&lt;br&gt;PSProvider&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem&lt;br&gt;PSIsContainer&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Mode&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : -a---&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Document.doc&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 45568&lt;br&gt;DirectoryName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;Directory&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;IsReadOnly&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Exists&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;br&gt;FullName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test\Document.doc&lt;br&gt;Extension&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : .doc&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:22:53&lt;br&gt;CreationTimeUtc&amp;nbsp;&amp;nbsp; : 2008-05-28 09:22:53&lt;br&gt;LastAccessTime&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:25:26&lt;br&gt;LastAccessTimeUtc : 2008-05-28 09:25:26&lt;br&gt;LastWriteTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:25:26&lt;br&gt;LastWriteTimeUtc&amp;nbsp; : 2008-05-28 09:25:26&lt;br&gt;Attributes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Archive &lt;br&gt;&amp;nbsp;&lt;br&gt;PSPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test\Satisfaction.mp3&lt;br&gt;PSParentPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test&lt;br&gt;PSChildName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Satisfaction.mp3&lt;br&gt;PSDrive&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C&lt;br&gt;PSProvider&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem&lt;br&gt;PSIsContainer&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Mode&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : -a---&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Satisfaction.mp3&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 8993629&lt;br&gt;DirectoryName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;Directory&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;IsReadOnly&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Exists&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;br&gt;FullName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test\Satisfaction.mp3&lt;br&gt;Extension&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : .mp3&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:24:33&lt;br&gt;CreationTimeUtc&amp;nbsp;&amp;nbsp; : 2008-05-28 09:24:33&lt;br&gt;LastAccessTime&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:24:33&lt;br&gt;LastAccessTimeUtc : 2008-05-28 09:24:33&lt;br&gt;LastWriteTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-26 10:00:46&lt;br&gt;LastWriteTimeUtc&amp;nbsp; : 2008-05-26 08:00:46&lt;br&gt;Attributes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Archive &lt;br&gt;&amp;nbsp;&lt;br&gt;PSPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test\Text.txt&lt;br&gt;PSParentPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem::C:\Test&lt;br&gt;PSChildName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Text.txt&lt;br&gt;PSDrive&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C&lt;br&gt;PSProvider&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\FileSystem&lt;br&gt;PSIsContainer&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Mode&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : -a---&lt;br&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Text.txt&lt;br&gt;Length&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1599&lt;br&gt;DirectoryName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;Directory&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test&lt;br&gt;IsReadOnly&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;br&gt;Exists&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;br&gt;FullName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : C:\Test\Text.txt&lt;br&gt;Extension&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : .txt&lt;br&gt;CreationTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:22:53&lt;br&gt;CreationTimeUtc&amp;nbsp;&amp;nbsp; : 2008-05-28 09:22:53&lt;br&gt;LastAccessTime&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:22:53&lt;br&gt;LastAccessTimeUtc : 2008-05-28 09:22:53&lt;br&gt;LastWriteTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2008-05-28 11:25:35&lt;br&gt;LastWriteTimeUtc&amp;nbsp; : 2008-05-28 09:25:35&lt;br&gt;Attributes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Archive&lt;/div&gt; &lt;p&gt;As long as something is returned it is possible to daisy-chain additional cmdlets onto the previous one. We could, for example, add &lt;span class="InlineCode"&gt;| more&lt;/span&gt; to the command above to divide it into smaller chunks. We could use the Out-File cmdlet to save the result to a textfile, etc.&lt;/p&gt; &lt;h1&gt;Summary&lt;/h1&gt; &lt;p&gt;What have we covered so far?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;PowerShell is object-oriented  &lt;li&gt;By default any object will be displayed on screen, so if you want to know what 2+2 equals, simply type &lt;span class="InlineCode"&gt;2+2&lt;/span&gt;.  &lt;li&gt;You can call standard .exe applications, etc from PowerShell, but they either need to be in the PATH, or you need to write the full path to them.  &lt;li&gt;PowerShell-specific applications are called cmdlets (“&lt;em&gt;Command-lets&lt;/em&gt;”)  &lt;li&gt;Most MS-DOS commands work, but they’re usually aliases to their PowerShell equivalent, so you might not be able to use all the switches you’re used to.  &lt;li&gt;You can use the | to daisy-chain cmdlets together, such as dir | format-list | more&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We still haven’t covered things like functions, variables, creating .NET objects, etc. I also plan to write a few samples showing how to use the cool cmdlets to get information from computers on the network, looking for specific files, exporting to Excel, printing, etc. As always I’d be happy to receive feedback and suggestions on things to cover.&lt;/p&gt; &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8556478" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/PowerShell/">PowerShell</category></item><item><title>Why doesn’t the GC kick in when the worker process is inactive?</title><link>http://blogs.msdn.com/b/johan/archive/2008/05/13/why-doesn-t-the-gc-kick-in-when-the-worker-process-is-inactive.aspx</link><pubDate>Tue, 13 May 2008 16:39:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8500269</guid><dc:creator>JohanSt</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8500269</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/05/13/why-doesn-t-the-gc-kick-in-when-the-worker-process-is-inactive.aspx#comments</comments><description>&lt;p&gt; &lt;p&gt;I got the following question in my &lt;a href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx"&gt;Getting started with windbg&lt;/a&gt; – post and I thought it might be worth posting the replies in a separate article:&lt;/p&gt; &lt;p&gt;&lt;em&gt;Hi Johan,&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;about those threads with an ID of XXXX, should they go away after certain amount of idle time like 2 minutes? I am trouble shooting an application while the application should sit idle (because of no stimulation), however it is still using quite some CPU time and and threadpool threads, where it should not. So I created an adplus dump when it is sitting idle, and I found that there are many threads with ID XXXX, and I created a dump file again after 15 minutes, again, it still have the exact same XXXX threads. All those threads are completion port threads, and I wonder why they did not get recycled?&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Also, when doing a '~*e !clrstack', most of the worker threads and completion port threads are showing "Failed to start stack walk: 80004005". Is there a way to show the stack for those threads, because those are the threads I am interested in.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Thank you!&lt;/em&gt;&lt;/p&gt; &lt;hr&gt;  &lt;p&gt;The GC will be triggered when you’re allocating memory. If your application is inactive, then so is the Garbage Collector. Even if you’re making a few, random allocations they still may not be enough to trigger a GC, so this is not at all unexpected.&lt;/p&gt; &lt;p&gt;The “Failed to start stack walk: 80004005”-error is displayed when the thread &lt;em&gt;did &lt;/em&gt;contain a managed stack, but no longer does.&lt;/p&gt; &lt;p&gt;/ Johan &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8500269" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Performance/">Performance</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/WinDbg/">WinDbg</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Managed+Heap/">Managed Heap</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/GC/">GC</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Worker+Process/">Worker Process</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/ASP-NET/">ASP.NET</category></item><item><title>What to do about the slow startup of web services</title><link>http://blogs.msdn.com/b/johan/archive/2008/04/02/what-to-do-about-the-slow-startup-of-web-services.aspx</link><pubDate>Wed, 02 Apr 2008 18:05:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8351640</guid><dc:creator>JohanSt</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/johan/rsscomments.aspx?WeblogPostID=8351640</wfw:commentRss><comments>http://blogs.msdn.com/b/johan/archive/2008/04/02/what-to-do-about-the-slow-startup-of-web-services.aspx#comments</comments><description>&lt;p&gt;Due to the architecture of web services and web applications they can be quite slow to start. For example on my Windows 2003-box the initial localhost-call to a simple “Hello World!”-web service takes approximately 8 seconds, while the next request is more or less immediate.&lt;/p&gt; &lt;h1&gt;Why is this?&lt;/h1&gt; &lt;p&gt;This isn’t news, really. One of the first things we learned in the early beta stages of ASP.NET was that the first request would take a little extra time due to the &lt;em&gt;Just In Time Compilation &lt;/em&gt;(JIT). This was a major change from the classic ASP architecture where everything was interpreted rather than compiled. Upon the first request the .aspx / .asmx file will be compiled (JIT’ed) into Microsoft Immediate Language (MSIL) and the resulting .dll will be moved to it’s proper location.&lt;/p&gt; &lt;p&gt;This compilation will occur every time the application pool starts causing a significantly longer response time on the first request compared to the following requests.&lt;/p&gt; &lt;h2&gt;Run-time performance over startup performance&lt;/h2&gt; &lt;p&gt;It all comes down to prioritizing run-time performance over a quick startup. Which, in my humble opinion, is a sound choice. There are, however, situations where you may feel that this is to your disadvantage. The other day I got a question from a customer who had a web service that was called quite infrequently and to him this meant that with every other request response times would be horrendous, simply because the application got recompiled.&lt;/p&gt; &lt;p&gt;For each case I get I usually do a quick search on the problem description. I don’t really expect to find the solution this way, since I can only assume that the customer has tried this as well. Instead it will likely present me with a list of troubleshooting steps that the customer has already tried as well as possible solutions that &lt;em&gt;didn’t &lt;/em&gt;fit. (Off course I still need to verify this with the customer).&lt;/p&gt; &lt;p&gt;This time I didn’t really need to do this since I was pretty sure what the cause was. Still, I was curious to see how &lt;em&gt;common&lt;/em&gt; this problem was. I honestly didn’t think this was a very common scenario, but my quick search on the web revealed the contrary. The few hits that I quickly browsed through suggested writing an application that would ping the web service in order to keep it alive. I must admit I find this quite inventive, but I really don’t think it’s the best approach. :)&lt;/p&gt; &lt;h1&gt;What to do&lt;/h1&gt; &lt;p&gt;So, what is to be done about this? Well, I’ve already mentioned that there are better solutions than pinging the web service. As I told my customer there are basically two good options:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Precompile the assemblies  &lt;li&gt;Change the settings for automatic recycling on the worker process&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;Precompiling the assemblies&lt;/h2&gt; &lt;p&gt;There is a nice little tool called Native Image Generator. (ngen.exe) It will compile the assembly into native images and installs them into the native image cache. The syntax is pretty straight-forward: &lt;span class="InlineCode"&gt;ngen.exe install [assembly]&lt;/span&gt; The problem is that once you’ve changed the assembly you’d have to precompile it again making updates a bit tedious.&lt;/p&gt; &lt;p&gt;There is also a service-version of the ngen called the Native Image Service. More information about ngen can be found at &lt;a title="http://msdn2.microsoft.com/sv-se/magazine/cc163808(en-us).aspx" href="http://msdn2.microsoft.com/sv-se/magazine/cc163808(en-us).aspx"&gt;http://msdn2.microsoft.com/sv-se/magazine/cc163808(en-us).aspx&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;Changing the recycling settings&lt;/h2&gt; &lt;p&gt;The reason why my customer was experiencing this problem was because his application pool would time out and recycle itself due to the default settings in the IIS manager. By default the worker process will recycle after 20 minutes of inactivity, so if no one has pinged your application in that time the next request will cause the application to recompile, resulting in a longer response time. By tweaking this setting in the IIS manager to something more suitable to the current rate of requests, like 40 minutes or maybe even 60 he should also be able to find a nice balance. Actually, considering the low load it would probably be a good idea to turn this setting off completely. Here’s how:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open up IIS Manager&lt;/li&gt; &lt;li&gt;Locate the Application Pool in question&lt;/li&gt; &lt;li&gt;Right-click it and select “Properties”&lt;/li&gt; &lt;li&gt;Go to the “Performance”-tab&lt;/li&gt; &lt;li&gt;Change, or disable the “Idle timeout” setting&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;img src="http://blogs.msdn.com/photos/johan/images/8351583/original.aspx"&gt; &lt;/p&gt; &lt;p&gt;/ Johan&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8351640" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/johan/archive/tags/Performance/">Performance</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Misc/">Misc</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/ASP-NET/">ASP.NET</category><category domain="http://blogs.msdn.com/b/johan/archive/tags/Web+Services/">Web Services</category></item></channel></rss>