<?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>Santiago Cánepa's Blog</title><link>http://blogs.msdn.com/b/santiagocanepa/</link><description>...de bueyes perdidos. (...about lost oxen.)</description><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.17018 (Build: 5.6.583.17018)</generator><item><title>Microsoft Small Basic</title><link>http://blogs.msdn.com/b/santiagocanepa/archive/2011/07/06/microsoft-small-basic.aspx</link><pubDate>Wed, 06 Jul 2011 22:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10183774</guid><dc:creator>Santi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/santiagocanepa/rsscomments.aspx?WeblogPostID=10183774</wfw:commentRss><comments>http://blogs.msdn.com/b/santiagocanepa/archive/2011/07/06/microsoft-small-basic.aspx#comments</comments><description>&lt;p&gt;Tomorrow, I&amp;rsquo;ll be helping at the San Diego DigiGirlz High Tech camp. This event is geared towards providing high school girls with an in-depth look at Microsoft and careers in technology (yes, I took that from the website). Information on the event can be found following this link: &lt;a title="http://www.microsoft.com/about/diversity/en/us/programs/digigirlz/default.aspx" href="http://www.microsoft.com/about/diversity/en/us/programs/digigirlz/default.aspx"&gt;http://www.microsoft.com/about/diversity/en/us/programs/digigirlz/default.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The class I&amp;rsquo;ll be helping with is an introduction to development. The interesting part is that it has a hands-on component using a tool I didn&amp;rsquo;t know about. It&amp;rsquo;s called Microsoft Small Basic, Besides being a very simple version of Basic, it is object oriented (although only built-in objects can be used; there&amp;rsquo;s no way to create custom classes), it has a promiscuous type system, and it includes functionality similar to a LOGO interpreter.&lt;/p&gt;
&lt;p&gt;In addition, it has a very basic IDE, that allows to open and save files and implements a nice-looking Intellisense UI (a bit glitchy, but great for beginners). When the application is executed, a small executable is created and run, so it does have an internal compiler.&lt;/p&gt;
&lt;p&gt;A great cool feature is that the programs can be &amp;ldquo;published&amp;rdquo; to somewhere in &amp;ldquo;the cloud&amp;rdquo; (being very lax with the term&amp;hellip; even using a hint of sarcasm). Once published, the application provides a link where the program can be seen online. The webpage shows the application and the source code.&lt;/p&gt;
&lt;p&gt;I found a paddle game sample, and I doctored up with some images, colors, and corrected a small bug. I published it here: &lt;a title="http://smallbasic.com/smallbasic.com/program/?NQB191" href="http://smallbasic.com/smallbasic.com/program/?NQB191"&gt;http://smallbasic.com/smallbasic.com/program/?NQB191&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The website looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-86-metablogapi/3005.Screen_5F00_0F831C66.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="Screen" border="0" alt="Screen" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-86-metablogapi/7026.Screen_5F00_thumb_5F00_0EAAB67C.jpg" width="403" height="545" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see on the webpage that the application is running! The application is converted to a SilverLight application that can be directly run in the browser! Kudos to the Microsoft Small Basic team!&lt;/p&gt;
&lt;p&gt;This tool is a great and fun way to introduce to programming concepts to kids or actually any person who is curious about programming, but can&amp;rsquo;t take the initial complexities that most of the modern languages introduce even to create the simplest working sample.&lt;/p&gt;
&lt;p&gt;Try it out&amp;hellip; it&amp;rsquo;s fun and it&amp;rsquo;s always good to be able to say that you learnt a whole new programming language in a couple of hours..!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10183774" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Small+Basic/">Small Basic</category></item><item><title>Mandatory parameters in PowerShell</title><link>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/mandatory-parameters-in-powershell.aspx</link><pubDate>Mon, 28 Feb 2011 23:56:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135156</guid><dc:creator>Santi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/santiagocanepa/rsscomments.aspx?WeblogPostID=10135156</wfw:commentRss><comments>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/mandatory-parameters-in-powershell.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One of the most frequently question I get when teaching parameters in PowerShell is regarding mandatory parameters.&lt;/p&gt;
&lt;p&gt;To answer that, let us back up a little bit and talk about parameters in general.&lt;/p&gt;
&lt;p&gt;We know that in a script (or function) we can use &lt;b&gt;$args&lt;/b&gt; to capture any argument that is passed and is not bound to any parameter:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8306.image9_5F00_4BD201F3.png"&gt;&lt;img height="101" width="571" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/7536.image9_5F00_thumb_5F00_593814F9.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;which presents the following output:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/5657.image_5F00_38B0D547.png"&gt;&lt;img height="156" width="706" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/4503.image_5F00_thumb_5F00_1BC7B072.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Additionally, even if we have a formal parameter definition, any unbound parameters will be found in &lt;b&gt;$args&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8132.image18_5F00_7AD43DCA.png"&gt;&lt;img height="126" width="578" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1856.image18_5F00_thumb_5F00_681F4413.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1263.image_5F00_19AAB1A9.png"&gt;&lt;img height="158" width="728" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8304.image_5F00_thumb_5F00_1F855542.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note, however, that if we do not pass any arguments, the &lt;b&gt;$StringParameter&lt;/b&gt; value is an empty string.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/4503.image_5F00_457B0598.png"&gt;&lt;img height="160" width="725" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1768.image_5F00_thumb_5F00_2BA6CF69.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This stems from the fact that the &lt;b&gt;PARAM&lt;/b&gt; section declares &lt;b&gt;$StringParameter&lt;/b&gt;&amp;rsquo;s type as &lt;b&gt;[string]&lt;/b&gt;, so it gets initialized to an empty string.&lt;/p&gt;
&lt;p&gt;We could assume a default value for the parameter for those cases in which the user does not provide an argument:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/2043.image31_5F00_6A985004.png"&gt;&lt;img height="135" width="557" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8625.image31_5F00_thumb_5F00_42F1D3DA.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8304.image_5F00_747D416F.png"&gt;&lt;img height="164" width="743" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/4503.image_5F00_thumb_5F00_2F647439.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, in many cases, we cannot assume any value for parameters. Take the case where we create a script to read a file that contains a bunch of server names on which to do some processing:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8304.image39_5F00_52B168DE.png"&gt;&lt;img height="242" width="476" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1856.image39_5F00_thumb_5F00_0E04CE9D.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this case, chances of finding a file &amp;ldquo;&lt;b&gt;Servers.txt&lt;/b&gt;&amp;rdquo; in a folder &amp;ldquo;&lt;b&gt;PSDemo&lt;/b&gt;&amp;rdquo; on the root of the drive &lt;b&gt;C:&lt;/b&gt; are very limited to the machine of the owner of the script.&lt;/p&gt;
&lt;p&gt;One easy way to force users to enter the parameter is by assigning an expression that throws an exception as the default value for the parameter. In this way, if an argument cannot be bound to the &lt;b&gt;$FileName&lt;/b&gt; parameter, the expression is evaluated, and an error is presented:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/3581.image_5F00_1F752F75.png"&gt;&lt;img height="223" width="547" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/2844.image_5F00_thumb_5F00_7EEDEFC2.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1351.image_5F00_57477398.png"&gt;&lt;img height="169" width="767" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/5657.image_5F00_thumb_5F00_442646EC.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, here is where mandatory parameters come into place. What if instead of a nasty error like the one above, we implement something more elegant? After all, when PowerShell is not given enough information, sometimes, it will politely ask for it like in the following example:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/7624.image_5F00_3C2EA48A.png"&gt;&lt;img height="248" width="774" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/7536.image_5F00_thumb_5F00_42757B18.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We told PowerShell that we want to remove an item, but we did not provide information on what item to remove. PowerShell did not raise an exception, nor did it assume any particular item (imagine what would happen if it did!). Instead, it presents us with a prompt to provide the argument for the parameter &lt;b&gt;$Path&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;We can implement the same functionality by adding some metadata to the parameter, thus fine-tuning the parameter definition. This metadata is provided via &lt;b&gt;Attributes&lt;/b&gt;. In this case, an attribute can be used to qualify the parameter &lt;b&gt;$FileName&lt;/b&gt;. &lt;b&gt;Parameter&lt;/b&gt; attributes have parameters themselves. We&amp;rsquo;ll provide values to this parameters to indicate that we want the parameter to be mandatory. Note the syntax in the &lt;b&gt;PARAM&lt;/b&gt; section:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/7711.image55_5F00_3A7DD8B6.png"&gt;&lt;img height="234" width="432" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/7120.image55_5F00_thumb_5F00_008E95CA.png" alt="image" border="0" title="image" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this case, the attribute called &lt;b&gt;Parameter&lt;/b&gt; can take a parameter called &lt;b&gt;Mandatory&lt;/b&gt;. We are passing the value &lt;b&gt;$true&lt;/b&gt; as its argument (a bit confusing, huh?). Note that the parameter definition is taking up two lines of code. This is done by convention, for readability. However, that is the same as:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/3021.image_5F00_71E3E9E4.png"&gt;&lt;img height="33" width="436" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/2018.image_5F00_thumb_5F00_1845CD30.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that we have indicated that the parameter is mandatory, notice that PowerShell is able to understand that it cannot do anything without that value, so it simply asks the user for it:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8713.image_5F00_50F0773D.png"&gt;&lt;img height="187" width="802" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/8206.image_5F00_thumb_5F00_57374DCB.png" alt="image" border="0" title="image" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Parameter&lt;/b&gt; attributes are not the only type of attributes used to provide metadata to a script or function. There are far more advanced scenarios that can be implemented via attributes, but they are subject matter for future posts.&lt;/p&gt;
&lt;p&gt;I hope this brings a bit nicer user experience to your scripts as well as extended functionality with very few changes.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135156" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Powershell/">Powershell</category><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Scripting/">Scripting</category><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Parameters/">Parameters</category></item><item><title>Creating non-user-specific printer mappings</title><link>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/creating-non-user-specific-printer-mappings.aspx</link><pubDate>Mon, 28 Feb 2011 23:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135149</guid><dc:creator>Santi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/santiagocanepa/rsscomments.aspx?WeblogPostID=10135149</wfw:commentRss><comments>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/creating-non-user-specific-printer-mappings.aspx#comments</comments><description>&lt;p&gt;Note that this is a re-post from my article at: &lt;a href="http://blogs.msdn.com/b/pfedev/archive/2009/11/25/creating-non-user-specific-printer-mappings.aspx" title="http://blogs.msdn.com/b/pfedev/archive/2009/11/25/creating-non-user-specific-printer-mappings.aspx"&gt;http://blogs.msdn.com/b/pfedev/archive/2009/11/25/creating-non-user-specific-printer-mappings.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I was delivering a PowerShell class, and the question of how to create a remote printer mapping came up.&lt;/p&gt;
&lt;p&gt;Turns out that enterprise administrators may have the need to help users with their printer connections, setting them up for them.&lt;/p&gt;
&lt;p&gt;As I started thinking about the problem, it dawned on me that drive and printer mappings are user specific. They are stored as part of a user&amp;rsquo;s profile, and since the user profile does not get loaded until the user is actually logged on, looks like little can be done.&lt;/p&gt;
&lt;p&gt;Domain user accounts do have a couple of properties that allow administrators to establish a &amp;ldquo;Home&amp;rdquo; share, and to assign it a drive letter. Beyond that, they are on their own.&lt;/p&gt;
&lt;p&gt;However, there is a solution!&lt;/p&gt;
&lt;p&gt;For printers, in particular, turns out that there is a feature that allows setting up a &amp;ldquo;global&amp;rdquo; printer mapping. This mapping will be created for the computer, and any user that logs on will be able to use it (provided (s)he has permissions).&lt;/p&gt;
&lt;p&gt;The regular Add Printer wizard only allows to create a printer mapping for the user running the wizard:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/Creatingnonuserspecificprintermappings_12629/clip_image002_2.jpg"&gt;&lt;img height="350" width="476" src="http://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/Creatingnonuserspecificprintermappings_12629/clip_image002_thumb.jpg" alt="clip_image002" border="0" title="clip_image002" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So that will not help. However, the PrintUI.dll library exposes the functionality to create a computer specific printer mappings!&lt;/p&gt;
&lt;p&gt;Simply run the PrintUIEntry (case sensitive) entry point for that library using rundll32 and pass the appropriate parameters&amp;hellip; and voil&amp;agrave;, the printer mapping is created.&lt;/p&gt;
&lt;p&gt;What? How do you do that? Thanks for asking!&lt;/p&gt;
&lt;p&gt;Open a PowerShell window (if you still are in the old days, go ahead, use CMD.exe instead) and type:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;RunDLL32 PrintUI.dll PrintUIEntry /?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;to get a help dialog with information on usage:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/Creatingnonuserspecificprintermappings_12629/clip_image004_2.jpg"&gt;&lt;img height="561" width="519" src="http://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/Creatingnonuserspecificprintermappings_12629/clip_image004_thumb.jpg" alt="clip_image004" border="0" title="clip_image004" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To create a global mapping, use the Global Add command with the /n parameter:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;RunDLL32 PrintUI.dll PrintUIEntry /ga /n\\SERVER\PRINTER_NAME&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;To delete the mapping, use the Global Delete command:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;RunDLL32 PrintUI.dll PrintUIEntry /gd /n\\SERVER\PRINTER_NAME&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;If you want to remotely do this on another computer, the usage indicates that you can specify the computer name with the /c parameter:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;RunDLL32 PrintUI.dll PrintUIEntry /gd /c\\Computer /n\\SERVER\PRINTER_NAME&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;However, this didn&amp;rsquo;t work for me, so I just used the first command but ran it remote&amp;rdquo;ly using PowerShell:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;$p = [WMICLASS]"//COMPUTER/root/CIMv2:WIN32_Process"&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style="font-family: Courier New; font-size: small;"&gt;$p.Create("RunDLL32 PrintUI.dll PrintUIEntry /ga /n\\SERVER\PRINTER_NAME")&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;Make sure that the Print Spooler service in the box where the new share was added is restarted after the addition/deletion of the mapping.&lt;/p&gt;
&lt;p&gt;I found this to be pretty handy, even in my home network.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Happy printer mapping!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Santiago&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135149" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Powershell/">Powershell</category></item><item><title>Memory Based Recycling in IIS 6.0</title><link>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/memory-based-recycling-in-iis-6-0.aspx</link><pubDate>Mon, 28 Feb 2011 23:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10135146</guid><dc:creator>Santi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/santiagocanepa/rsscomments.aspx?WeblogPostID=10135146</wfw:commentRss><comments>http://blogs.msdn.com/b/santiagocanepa/archive/2011/02/28/memory-based-recycling-in-iis-6-0.aspx#comments</comments><description>&lt;p&gt;Note that this is a re-post from my article at: &lt;a href="http://blogs.msdn.com/b/pfedev/archive/2009/01/22/memory-based-recycling-in-iis-6-0.aspx" title="http://blogs.msdn.com/b/pfedev/archive/2009/01/22/memory-based-recycling-in-iis-6-0.aspx"&gt;http://blogs.msdn.com/b/pfedev/archive/2009/01/22/memory-based-recycling-in-iis-6-0.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Customers frequently ask questions regarding the recycling options for Application Pools in IIS.&lt;/p&gt;
&lt;p&gt;Several of those options are self-explanatory, whereas others need a bit of analysis.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to focus on the Memory Recycling options, which allow IIS to monitor worker processes and recycle them based on configured memory limits.&lt;/p&gt;
&lt;p&gt;Recycling application pools is not necessarily a sign of problems in the application being served. Memory fragmentation and other natural degradation cannot be avoided and recycling ensures that the applications are periodically cleaned up for enhanced resilience and performance.&lt;/p&gt;
&lt;p&gt;However, recycling can also be a way to work around issues that cannot be easily tackled. For instance, consider the scenario in which an application uses a third party component, which has a memory leak. In this case, the solution is to obtain a new version of the component with the problem resolved. If this is not an option, and the component can run for a long period of time without compromising the stability of the server, then memory based recycling can be a mitigating solution for the memory leak.&lt;/p&gt;
&lt;p&gt;Even when a solution to a problem is identified, but might take time to implement, memory-based recycling can provide a temporary workaround, until a permanent solution is in place.&lt;/p&gt;
&lt;p&gt;As mentioned before, memory fragmentation is another problem that can affect the stability of an application, causing out-of-memory errors when there seems to be enough memory to satisfy the allocation requests.&lt;/p&gt;
&lt;p&gt;In any case, setting memory limits on application pools can be an effective way to contain any unforeseen situation in which an application that &amp;ldquo;behaves well&amp;rdquo; goes haywire. The advantage of setting memory limits on well behaved applications is that in the unlike case something goes wrong, there is a trace left in the event viewer, providing a first place where research of the issue can start.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;When to configure Memory Recycling&lt;/h1&gt;
&lt;p&gt;In most scenarios, recycling based on a schedule should be sufficient in order to &amp;ldquo;refresh&amp;rdquo; the worker processes at specific points in time. Note that the periodic recycle is the default, with a period of 29 hours (1740 minutes). This can be an inconvenience, since each recycle would occur at different times of a day, eventually occurring during peak times.&lt;/p&gt;
&lt;p&gt;If you have determined that you have to recycle your application pool based on memory threshold, it implies that you have established a baseline for your application and that you know your application&amp;rsquo;s memory usage patterns. This is a very important assumption, since in order to properly configure memory thresholds you need to understand how the application is using memory, and when it is appropriate to recycle the application based on that usage.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Configuration Options&lt;/h1&gt;
&lt;p&gt;There are two inclusive options that can be configured for application pool recycling:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/3755.clip_5F00_image001_5F00_22F044D3.png"&gt;&lt;img height="230" width="244" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1513.clip_5F00_image001_5F00_thumb_5F00_3AA77C39.png" alt="clip_image001" border="0" title="clip_image001" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Figure 1 - Application Pool properties to configure Memory Recycling&lt;/i&gt;&lt;/p&gt;
&lt;h5&gt;Maximum Virtual Memory&lt;/h5&gt;
&lt;p&gt;This setting sets a threshold limit on the Virtual Memory. This is the memory (Virtual Address Space) that the application has used plus the memory it has reserved but not committed. To understand how the application uses this type of memory, you can monitor it by means of the Process &amp;ndash; Virtual Bytes counter in Performance Monitor.&lt;/p&gt;
&lt;p&gt;For instance, if you receive out of memory errors, but less than 800MB are reported as consumed, it is often a sign of memory fragmentation.&lt;/p&gt;
&lt;h5&gt;Maximum Used Memory&lt;/h5&gt;
&lt;p&gt;This setting sets a threshold limit on the Used Memory. This is the application&amp;rsquo;s private memory, the non-shared portion of the application&amp;rsquo;s memory. You can use the Process &amp;ndash; Private Bytes counter in Performance Monitor to understand how the application uses this memory.&lt;/p&gt;
&lt;p&gt;In the scenarios mentioned before, this setting would be used when you have detected a memory leak which cannot avoid (or is not cost effective to correct). This setting would set a &amp;ldquo;cap&amp;rdquo; on how much memory the application is &amp;ldquo;allowed&amp;rdquo; to leak before the application is restarted&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Recycle Event Logging&lt;/h1&gt;
&lt;p&gt;Depending on the configuration of the web server and application pools, every time a process is recycled, an event may be logged in the System log.&lt;/p&gt;
&lt;p&gt;By default, only certain recycle events are logged, depending on the cause for the recycle. Timed and Memory based recycling events are logged, whereas all other events are not.&lt;/p&gt;
&lt;p sizset="0" sizcache="1"&gt;This setting is managed by the LogEventOnRecycle metabase property for application pools. This property is a byte flag. The each bit indicates a reason for a recycle. Turning on a bit instructs IIS that the particular recycle event should be logged. The following table indicates the available values for the flag: &lt;/p&gt;
&lt;table cellpadding="0" cellspacing="0" border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;Flag&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;Value&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleTime&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled after a specified elapsed time.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleRequests &lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled after a specified number of requests&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleSchedule&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled at specified times.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleMemory&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled once a specified amount of used or virtual memory, expressed in megabytes, is in use.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleIsapiUnhealthy&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled if IIS finds that an ISAPI is unhealthy.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;16&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleOnDemand&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled on demand by an administrator.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;32&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecycleConfigChange &lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled after configuration changes are made.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;64&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;
&lt;p&gt;&lt;b&gt;AppPoolRecyclePrivateMemory&lt;/b&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;The worker process is recycled when private memory reaches a specified amount.&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top"&gt;
&lt;p&gt;128&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As mentioned before, only some of the events are configured to be logged by default. This default value is 137 (1 + 8 + 128).&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s best to configure all the events to be logged. This will ensure that you understand the reasons why your application is being recycled. For information on how to configure the LogEventOnRecycle metabase property, see the support article at &lt;a href="http://support.microsoft.com/kb/332088"&gt;http://support.microsoft.com/kb/332088&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Below are the events logged because the memory limit thresholds have been reached:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1680.clip_5F00_image002_5F00_2BFCD054.png"&gt;&lt;img height="233" width="210" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/1018.clip_5F00_image002_5F00_thumb_5F00_3962E35A.png" alt="clip_image002" border="0" title="clip_image002" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Figure 2 - The application pool reached the Used Memory Threshold&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/4743.clip_5F00_image003_5F00_2AB83775.png"&gt;&lt;img height="233" width="210" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-86-metablogapi/6283.clip_5F00_image003_5F00_thumb_5F00_1F227A36.png" alt="clip_image003" border="0" title="clip_image003" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Figure 3 - The application reached the Virtual Memory threshold&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Note that the article lists the 1177 Event ID for Used (Private) Memory recycling, but in Event viewer it shows as Event ID 1117&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Determining a threshold&lt;/h1&gt;
&lt;p&gt;Unlike other settings, memory recycling is probably the setting that requires the most analysis, since the memory of a system may behave differently depending on various factors, such as the processor architecture, running applications, usage patterns, /3GB switch, implementation of Web Gardens, etc.&lt;/p&gt;
&lt;p&gt;In order to maximize service uptime, IIS 6.0 does Overlapped recycling by default. This means that when a worker process is due for a recycle, a new process is spawned and only when this new process is ready to start processing requests does the recycle of the old process actually occur. With overlapped mode, there will be two processes running at one point in time. This is one of the reasons why it is very important to understand the memory usage patterns of the application. If the application has a large memory footprint at startup, having two processes running concurrently could starve the system&amp;rsquo;s memory. For example, in a 32 bit Windows 2003 system with 4GB memory, Non-Paged Pool should remain over 285MB, Paged Pool over 330MB~360MB and System Free PTE should remain above 10,000. Additionally, Available Memory should not be lower than 50MB (these are approximate values and may be different for each system&lt;a name="_ftnref1_1438"&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/b/pfedev/archive/2009/01/22/memory-based-recycling-in-iis-6-0.aspx#_ftn1_1438"&gt;[1]&lt;/a&gt;). In a case in which recycling an application based on memory would cause these thresholds to be surpassed, Non-Overlapped Recycling Mode could help mitigate the situation, although it would impact the uptime of the application. In this type of recycling, the worker process is terminated first before spawning the new worker process.&lt;/p&gt;
&lt;p&gt;In general, if the application uses X MB of memory, and it&amp;rsquo;s configured to recycle when it reaches 50% over the normal consumption (1.5 * X MB), you will want to ensure that the system is able to support 2.5 * X MB during the recycle without suffering from system memory starvation. Consider also the need to determine what type of memory recycling option is needed. Applications that use large amounts of memory to store application data or allocate and de-allocate memory frequently might benefit from having Maximum Virtual Memory caps, whereas applications that have heavy memory requirements (e.g. a large application level cache), or suffer from memory leaks could benefit from Maximum Memory Used caps.&lt;/p&gt;
&lt;p&gt;The documentation suggests setting the Virtual Memory threshold as high as 70% of the system&amp;rsquo;s memory, and the Used Memory as high as 60% of the system&amp;rsquo;s memory. However, for recycling purposes, and considering that during the recycle two processes must run concurrently, these settings could prove to be a bit aggressive. As an estimate, for a 32 bit server with 4 GB of RAM, the Virtual Memory should be set to some value between 1.2 GB and 1.5 GB, whereas the Private bytes should be around 0.8 GB to 1 GB. These numbers assume that the application is the only one in the system. Of course, these numbers are quick rules of thumb and do not apply to every case. Different applications have very different memory usage patterns.&lt;/p&gt;
&lt;p&gt;For a more accurate estimation, you should monitor your application for a long enough period so as to capture the information about memory usage (private and virtual bytes) of the application during the most common scenarios and stress levels. For example, if your application is used consistently on an everyday basis, a couple of week&amp;rsquo;s worth of data should be enough. If your application has a monthly process and each week of the month has different usage (users enter information at the beginning of the month and heavy reporting activity occurs at the end of the month) then a longer period may be appropriate. In addition, it is important to remember that data may be skewed if we monitor the application during the Holidays (when traffic is only 10% of the expected), or during the release of that long-awaited product (when traffic is expected to go as high as 500% of the typical usage).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Problems associated with recycling&lt;/h1&gt;
&lt;p&gt;Although recycling is a mechanism that may enhance application stability and reliability, it comes with a price tag. Too little recycling can cause problems, but too much of a good thing is not good either.&lt;/p&gt;
&lt;h5&gt;Non-overlapped recycles&lt;/h5&gt;
&lt;p&gt;As discussed above, there are times when overlapped recycling may cause problems. Besides the memory conditions described above, if the application creates or instantiates objects for which only one instance can exist at a particular time for the whole system (like a named kernel object), or sets exclusive locks on files, then overlapped recycle may not be an option. It is very important to understand that non-overlapped recycles may cause users to see error messages during the recycling process. In situations like this, it is very important to limit recycles to a minimum.&lt;/p&gt;
&lt;p&gt;Moreover, if the time it takes for a process to terminate is too long, it may cause noticeably long outages of the application while it is recycling. In this case, it is very important to set an appropriate application pool shutdown timeout. This timeout defines the length of the period of time that IIS will wait for a worker process to terminate normally before it forces it to terminate. This is configured using the &lt;b&gt;ShutdownTimeLimit&lt;/b&gt; metabase property (&lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx?mfr=true&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To configure an application pool to use non-overlapped recycles, set the application pool&amp;rsquo;s metabase property &lt;b&gt;DisallowOverlappingRotation&lt;/b&gt; to &lt;b&gt;true&lt;/b&gt;. For more information on this property, see the metabase property reference at &lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx?mfr=true&lt;/a&gt;.&lt;/p&gt;
&lt;h5&gt;Session state&lt;/h5&gt;
&lt;p&gt;Stateful applications can be implemented using a variety of choices of were to store the session information. For ASP.Net, some of these are cookie-based, in-process, Session State Server, SQL Server. For classic ASP, this list is more limited. These implementation decisions have an impact on whether to use Web Gardens and how to implement Web Farms. Additionally, these may determine the effect that application pool recycling has on the application.&lt;/p&gt;
&lt;p&gt;In the case of in-memory sessions, the session information is kept in the worker process&amp;rsquo; memory space. When a recycle is requested, a new worker process is started and session information on the recycled process is lost. This effectively affects any active session that exists in that application. This is yet another reason why the amount of recycles should be minimized.&lt;/p&gt;
&lt;h5&gt;Application Startup&lt;/h5&gt;
&lt;p&gt;Recycling an application is an expensive task for the server. Process creation and termination are required to start the new worker process and bring down the old one. In addition, any application level cache and other data in memory are lost and need to be reloaded. Depending on the application, these activities can significantly reduce the performance of the application, providing a degraded user experience.&lt;/p&gt;
&lt;p&gt;Incidentally, another post in this blog discusses another of the reasons application startup may be slow. In many cases this information will help speed up the startup of your application. If you haven&amp;rsquo;t done it yet, check it out at &lt;a href="http://blogs.msdn.com/pfedev/archive/2008/11/26/best-practice-generatepublisherevidence-in-aspnet-config.aspx"&gt;http://blogs.msdn.com/pfedev/archive/2008/11/26/best-practice-generatepublisherevidence-in-aspnet-config.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Memory Usage checks&lt;/h1&gt;
&lt;p&gt;When an application is configured to recycle based on memory, it is up to the worker process to perform the checks. These checks are done every minute. If the application has surpassed the memory caps at the time of the check, then a recycle is requested.&lt;/p&gt;
&lt;p&gt;Bearing this behavior in mind, consider a case in which an application behaves well most of the times, but under certain conditions, it behaves really badly. By misbehavior I mean very aggressive memory consumption during a very short period of time. In this case, the application can cause other problems by exhausting the system&amp;rsquo;s memory before the worker process checks for memory consumption and any recycle can kick in. This could lead to problems that are difficult to troubleshoot and limit the effectiveness of memory based recycling. &lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The following points summarize good practices when using memory based recycling:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure IIS so it logs all recycle events in the System Log. &lt;/li&gt;
&lt;li&gt;Use memory recycling only if you understand the application&amp;rsquo;s memory usage patterns. &lt;/li&gt;
&lt;li&gt;Use memory based recycling as a temporary workaround until permanent fixes can be found. &lt;/li&gt;
&lt;li&gt;Remember that memory based recycling may not work as expected when the application consumes very large amounts of memory in a very short period of time (less than a minute). &lt;/li&gt;
&lt;li&gt;Closely monitor recycles and ensure that they are not too many (reducing the performance and/or availability of the application), or too few (allowing memory consumption of the application to create too much memory pressure on the server). &lt;/li&gt;
&lt;li&gt;Use overlapped recycling when possible. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Santiago&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10135146" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/Memory/">Memory</category><category domain="http://blogs.msdn.com/b/santiagocanepa/archive/tags/IIS/">IIS</category></item></channel></rss>