<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Robert McMurray</title><subtitle type="html">Discussing IIS, FTP, WebDAV, FPSE, WMI, ADSI, ISAPI, ASP, FastCGI, etc. ;-)</subtitle><id>http://blogs.iis.net/robert_mcmurray/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.iis.net/robert_mcmurray/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2011-10-18T03:05:10Z</updated><entry><title>Configuring FTP Client Certificate Authentication in FTP 7</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/04/26/configuring-ftp-client-certificate-authentication-in-ftp-7.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/04/26/configuring-ftp-client-certificate-authentication-in-ftp-7.aspx</id><published>2012-04-26T11:36:30Z</published><updated>2012-04-26T11:36:30Z</updated><content type="html">&lt;p&gt;We had a customer question the other day about configuring FTP Client Certificate Authentication in FTP 7.0 and&amp;nbsp; in FTP 7.5. It had been a while since the last time that I had configured those settings on an FTP server, so I thought that it would be great to re-familiarize myself with that feature. To my initial dismay, it was a little more difficult than I had remembered, because there are a lot of parts to be configured.&lt;/p&gt;
&lt;p&gt;That being said, there are a few primary activities that you need to know about and configure correctly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="#001"&gt;Configuring the FTP Service&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="#002"&gt;Configuring Active Directory Mapping&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="#003"&gt;Configuring your FTP Client&lt;/a&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will explain each of those in this blog, although I will defer some of the details for Active Directory mapping to an excellent blog series that I discovered by &lt;a href="http://www.dotnetscraps.com/dotnetscraps/author/Vivek.aspx" target="_blank"&gt;Vivek Kumbhar&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;a name="001"&gt;&lt;/a&gt;Configuring the FTP Service&lt;/h3&gt;
&lt;p&gt;There are several settings that you need to configure for the FTP server; unfortunately there is no user interface for those settings, so you might want to familiarize yourself with the following settings:&lt;/p&gt;
&lt;ul style="line-height: 200%;"&gt;
&lt;li&gt;&lt;a href="http://www.iis.net/ConfigReference/system.applicationHost/sites/site/ftpServer/security/authentication/clientCertAuthentication" target="_blank"&gt;FTP Client Certificate Authentication &amp;lt;clientCertAuthentication&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.iis.net/ConfigReference/system.applicationHost/sites/site/ftpServer/security/ssl" target="_blank"&gt;FTP over SSL &amp;lt;ssl&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.iis.net/ConfigReference/system.applicationHost/sites/site/ftpServer/security/sslClientCertificates" target="_blank"&gt;FTP SSL Client Certificates &amp;lt;sslClientCertificates&amp;gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At first I had made a batch file that was configuring these settings by using AppCmd, but I eventually abandoned that script and wrote the following VBScript code to configure all of the settings at one time - the only parts that you need to change is your site name and the hash value your SSL certificate, which are highlighted in yellow:&lt;/p&gt;
&lt;pre style="margin-left: 20px; color: black; background-color: #ffffff;"&gt;&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; adminManager = CreateObject(&lt;span style="color: #800000;"&gt;"Microsoft.ApplicationHost.WritableAdminManager"&lt;/span&gt;)
adminManager.CommitPath = &lt;span style="color: #800000;"&gt;"MACHINE/WEBROOT/APPHOST"&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; sitesSection = adminManager.GetAdminSection(&lt;span style="color: #800000;"&gt;"system.applicationHost/sites"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"MACHINE/WEBROOT/APPHOST"&lt;/span&gt;)
&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; sitesCollection = sitesSection.Collection

siteElementPos = FindElement(sitesCollection, &lt;span style="color: #800000;"&gt;"site"&lt;/span&gt;, Array(&lt;span style="color: #800000;"&gt;"name"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;span style="background-color: #ffff00;"&gt;ftp.contoso.com&lt;/span&gt;"&lt;/span&gt;))
&lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; (addElementPos = -1) &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
   WScript.Echo &lt;span style="color: #800000;"&gt;"Element not found!"&lt;/span&gt;
   WScript.Quit
&lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; siteElement = sitesCollection.Item(siteElementPos)

&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; ftpServerElement = siteElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"ftpServer"&lt;/span&gt;)
&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; securityElement = ftpServerElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"security"&lt;/span&gt;)

&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; sslClientCertificatesElement = securityElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"sslClientCertificates"&lt;/span&gt;)
sslClientCertificatesElement.Properties.Item(&lt;span style="color: #800000;"&gt;"clientCertificatePolicy"&lt;/span&gt;).Value = &lt;span style="color: #800000;"&gt;"CertRequire"&lt;/span&gt;
sslClientCertificatesElement.Properties.Item(&lt;span style="color: #800000;"&gt;"useActiveDirectoryMapping"&lt;/span&gt;).Value = &lt;span style="color: #0000ff;"&gt;True&lt;/span&gt;

&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; authenticationElement = securityElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"authentication"&lt;/span&gt;)
&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; clientCertAuthenticationElement = authenticationElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"clientCertAuthentication"&lt;/span&gt;)
clientCertAuthenticationElement.Properties.Item(&lt;span style="color: #800000;"&gt;"enabled"&lt;/span&gt;).Value = &lt;span style="color: #0000ff;"&gt;True&lt;/span&gt;

&lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; sslElement = securityElement.ChildElements.Item(&lt;span style="color: #800000;"&gt;"ssl"&lt;/span&gt;)
sslElement.Properties.Item(&lt;span style="color: #800000;"&gt;"serverCertHash"&lt;/span&gt;).Value = &lt;span style="color: #800000;"&gt;"&lt;span style="background-color: #ffff00;"&gt;57686f6120447564652c2049495320526f636b73&lt;/span&gt;"&lt;/span&gt;
sslElement.Properties.Item(&lt;span style="color: #800000;"&gt;"controlChannelPolicy"&lt;/span&gt;).Value = &lt;span style="color: #800000;"&gt;"SslRequire"&lt;/span&gt;
sslElement.Properties.Item(&lt;span style="color: #800000;"&gt;"dataChannelPolicy"&lt;/span&gt;).Value = &lt;span style="color: #800000;"&gt;"SslRequire"&lt;/span&gt;

adminManager.CommitChanges

&lt;span style="color: #0000ff;"&gt;Function&lt;/span&gt; FindElement(collection, elementTagName, valuesToMatch)
   &lt;span style="color: #0000ff;"&gt;For&lt;/span&gt; i = 0 &lt;span style="color: #0000ff;"&gt;To&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;CInt&lt;/span&gt;(collection.Count) - 1
      &lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; element = collection.Item(i)
      &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; element.Name = elementTagName &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
         matches = &lt;span style="color: #0000ff;"&gt;True&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;For&lt;/span&gt; iVal = 0 &lt;span style="color: #0000ff;"&gt;To&lt;/span&gt; UBound(valuesToMatch) &lt;span style="color: #0000ff;"&gt;Step&lt;/span&gt; 2
            &lt;span style="color: #0000ff;"&gt;Set&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;property&lt;/span&gt; = element.GetPropertyByName(valuesToMatch(iVal))
            value = &lt;span style="color: #0000ff;"&gt;property&lt;/span&gt;.Value
            &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;Not&lt;/span&gt; IsNull(value) &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
               value = &lt;span style="color: #0000ff;"&gt;CStr&lt;/span&gt;(value)
            &lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;Not&lt;/span&gt; value = &lt;span style="color: #0000ff;"&gt;CStr&lt;/span&gt;(valuesToMatch(iVal + 1)) &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
               matches = &lt;span style="color: #0000ff;"&gt;False&lt;/span&gt;
               &lt;span style="color: #0000ff;"&gt;Exit&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;For&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;Next&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; matches &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;Exit&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;For&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
      &lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;Next&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt; matches &lt;span style="color: #0000ff;"&gt;Then&lt;/span&gt;
      FindElement = i
   &lt;span style="color: #0000ff;"&gt;Else&lt;/span&gt;
      FindElement = -1
   &lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;p&gt;Once you have configured your FTP settings, you should have an FTP site that resembles the following in your ApplicationHost.config file:&lt;/p&gt;
&lt;pre style="margin-left: 20px; color: black; background-color: #ffffff;"&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;site&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="ftp.contoso.com"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="2"&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;application&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;path&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="/"&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;virtualDirectory&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;path&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="/"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;physicalPath&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="c:\inetpub\ftproot"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;application&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;bindings&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;binding&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;protocol&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="ftp"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;bindingInformation&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="*:21:"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;bindings&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ftpServer&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;security&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ssl&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;serverCertHash&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="57686f6120447564652c2049495320526f636b73" &lt;/span&gt; &lt;span style="color: #ff0000;"&gt;ssl128&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="false" &lt;/span&gt; &lt;span style="color: #ff0000;"&gt;controlChannelPolicy&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="SslRequire" &lt;/span&gt; &lt;span style="color: #ff0000;"&gt;dataChannelPolicy&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="SslRequire"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;authentication&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;basicAuthentication&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;enabled&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="false"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;anonymousAuthentication&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;enabled&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="false"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;clientCertAuthentication&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;enabled&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="true"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;authentication&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
         &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;sslClientCertificates &lt;/span&gt; &lt;span style="color: #ff0000;"&gt;clientCertificatePolicy&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="CertRequire" &lt;/span&gt; &lt;span style="color: #ff0000;"&gt;useActiveDirectoryMapping&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="true"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;security&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ftpServer&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;site&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;More details about these settings can be found in the configuration reference articles that I mentioned in the beginning of this blog post, and additional information about configuring FTP over SSL can be found in the following walkthrough:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://learn.iis.net/page.aspx/304/using-ftp-over-ssl-in-iis-7/" target="_blank"&gt;Using FTP Over SSL in IIS 7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name="002"&gt;&lt;/a&gt;Configuring Active Directory Mapping&lt;/h3&gt;
&lt;p&gt;The next part of this process is kind of tricky; you need to accomplish all of the following:&lt;/p&gt;
&lt;ul style="line-height: 200%;"&gt;
&lt;li&gt;Obtain and install a client certificate on the system where your FTP client is installed. Hare some additional notes to consider:
&lt;ul&gt;
&lt;li&gt;This may involve setting up your client system to trust the CA that issued your client certificate.&lt;/li&gt;
&lt;li&gt;This may &lt;i&gt;also &lt;/i&gt;involve setting up your FTP server to trust the CA that issued both your client certificate and the server certificate that you are using for your FTP site.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Configure Active Directory to map the client certificate to an Active Directory account.&lt;/li&gt;
&lt;li&gt;Configure your FTP client to use a client certificate when connecting to your FTP server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That makes it all sound so easy, but it can be very tricky. That being said, as I mentioned earlier, as I was putting together my notes to write this blog, I stumbled across a great blog series by &lt;a href="http://www.dotnetscraps.com/dotnetscraps/author/Vivek.aspx" target="_blank"&gt;Vivek Kumbhar&lt;/a&gt;, where he goes into great detail when describing all of the steps to set up the Active Directory mapping. With that in mind, instead of trying to rewrite what Vivek has already documented, I will include links to his blog series:&lt;/p&gt;
&lt;ul style="line-height: 200%;"&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.dotnetscraps.com/dotnetscraps/post/Did-you-know-Configure-Client-Certificate-Mapping-in-FTP-75-Part-1.aspx" target="_blank"&gt;Configure Client Certificate Mapping in FTP 7.5 - Part 1&lt;/a&gt;&lt;/b&gt;&lt;br /&gt; &lt;i&gt;Describes how to set up your Active Directory server, IIS server, and FTP client systems.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.dotnetscraps.com/dotnetscraps/post/Did-you-know-Configure-Client-Certificate-Mapping-in-FTP-7-FTP-75-Part-2.aspx" target="_blank"&gt;Configure Client Certificate Mapping in FTP 7.5 - Part 2&lt;/a&gt;&lt;/b&gt;&lt;br /&gt; &lt;i&gt;Walks you through obtaining and installing a server certificate, which you will use later for your FTP site.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.dotnetscraps.com/dotnetscraps/post/Did-you-know-Configure-Client-Certificate-Mapping-in-FTP-7-FTP-75-Part-3.aspx" target="_blank"&gt;Configure Client Certificate Mapping in FTP 7.5 - Part 3&lt;/a&gt;&lt;/b&gt;&lt;br /&gt; &lt;i&gt;Walks you through setting up an FTP site with SSL.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.dotnetscraps.com/dotnetscraps/post/Did-you-know-Configure-Client-Certificate-Mapping-in-FTP-7-FTP-75-Part-4.aspx" target="_blank"&gt;Configure Client Certificate Mapping in FTP 7.5 - Part 4&lt;/a&gt;&lt;/b&gt;&lt;br /&gt; &lt;i&gt;Describes how to configure Active Directory mapping for a user account.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have to give Vivek full credit where it's due - he wrote a truly great blog series, and he included a lot more detail in his blog series than I had originally planned to include in this blog. (In my humble opinion, Vivek's blog series is the best documentation that I have seen for this feature.)&lt;/p&gt;
&lt;h3&gt;&lt;a name="003"&gt;&lt;/a&gt;Configuring your FTP Client&lt;/h3&gt;
&lt;p&gt;To test out client certificates, I used both the SmartFTP GUI-based FTP client and the MOVEit-Freely command-line FTP client; both of which I discussed in my &lt;i&gt;FTP Clients &lt;/i&gt;blog series some time ago.&lt;/p&gt;
&lt;h4&gt;Using the SmartFTP Client&lt;/h4&gt;
&lt;p&gt;To configure the SmartFTP client, I just needed to enable and specify the correct client certificate in the properties for my connection:&lt;/p&gt;
&lt;p style="margin-left: 20px;"&gt;&lt;a href="https://public.sn2.livefilestore.com/y1pzUP_BeuBmR6mgaai4ghuMvkGUcTobcYmPWcL6zokNKtE-U1oTiYGuc-9EbNuLV67-bnkHPYgtEBwl50pBGDu3w/SmartFTP_9.png" target="_blank"&gt;&lt;img border="2" src="https://public.sn2.livefilestore.com/y1pzUP_BeuBmR6mgaai4ghuMvkGUcTobcYmPWcL6zokNKtE-U1oTiYGuc-9EbNuLV67-bnkHPYgtEBwl50pBGDu3w/SmartFTP_9.png" width="400" height="368" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Using the MOVEit-Freely FTP Client&lt;/h4&gt;
&lt;p&gt;For the MOVEit-Freely FTP client, I just needed to specify the correct parameters on the command line:&lt;/p&gt;
&lt;pre style="margin-left: 20px;"&gt;ftps.exe -z -e:on -pfxfile:administrator.pfx -pfxpw:"P@ssw0rd" -user:anonymous -password:"someone@contoso.com"&lt;/pre&gt;
&lt;p&gt;The important settings are the &lt;code&gt;pfxfile&lt;/code&gt; and &lt;code&gt;pfxpw&lt;/code&gt; values, where &lt;code&gt;pfxfile&lt;/code&gt; is the name of the PFX file that holds your client certificate, and &lt;code&gt;pfxpw&lt;/code&gt; is the password for the PFX file. (The &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; values will be ignored for the most part, because you will actually be logged in through your client certificate, so you can leave those as anonymous.)&lt;/p&gt;
&lt;h4&gt;Client Recap&lt;/h4&gt;
&lt;p&gt;For more information about these two FTP clients, see the following blog posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2010/05/07/ftp-clients-part-8-smartftp-client.aspx" target="_blank"&gt;FTP Clients - Part 8: SmartFTP Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2009/01/07/ftp-clients-part-5-moveit-freely-command-line-secure-ftp-client.aspx" target="_blank"&gt;FTP Clients - Part 5: MOVEit Freely Command-Line Secure FTP Client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;FTP client certificates are definitely a bit of a challenge to configure correctly, but it's not an impossible task to get this feature working.&lt;/p&gt;
(Cross-posted from http://blogs.msdn.com/robert_mcmurray/)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4952759" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>Extensibility Updates in the FTP 8.0 Service</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/04/20/extensibility-updates-in-the-ftp-8-0-service.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/04/20/extensibility-updates-in-the-ftp-8-0-service.aspx</id><published>2012-04-20T10:49:00Z</published><updated>2012-04-20T10:49:00Z</updated><content type="html">&lt;p&gt;A few years ago I wrote a blog that was titled "&lt;i&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2009/04/23/blog-ftp-7-5-service-extensibility-references.aspx" target="_blank"&gt;FTP 7.5 Service Extensibility References&lt;/a&gt;&lt;/i&gt;", in which I discussed the extensibility APIs that we added in FTP 7.5. Over the next couple of years I followed that initial blog with a series of &lt;a href="http://learn.iis.net/page.aspx/590/" target="_blank"&gt;walkthroughs on IIS.net&lt;/a&gt; and several related blog posts. Here are just a few examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2011/11/02/how-to-use-managed-code-c-to-create-an-ftp-home-directory-provider-that-is-based-on-the-remote-client-ip-address.aspx" target="_blank"&gt;How to use Managed Code (C#) to create an FTP Home Directory Provider that is based on the Remote Client IP Address&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2011/09/29/how-to-use-managed-code-csharp-to-create-an-ftp-home-directory-provider-for-the-days-of-the-week.aspx" target="_blank"&gt;How to Use Managed Code (C#) to Create an FTP Home Directory Provider for the Days of the Week&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2011/09/16/ftp-and-ldap-part-1-how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-that-uses-an-ldap-server.aspx" target="_blank"&gt;FTP and LDAP - How to Use Managed Code (C#) to Create an FTP Authentication Provider that uses an LDAP Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2011/06/30/how-to-create-an-authentication-provider-for-ftp-7-5-using-blogengine-net-s-xml-membership-files.aspx" target="_blank"&gt;How to Create an Authentication Provider for FTP 7.5 using BlogEngine.NET's XML Membership Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2009/07/23/merging-ftp-extensibility-walkthroughs.aspx" target="_blank"&gt;Merging FTP Extensibility Walkthroughs - Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2009/08/19/merging-ftp-extensibility-walkthroughs-part-2.aspx" target="_blank"&gt;Merging FTP Extensibility Walkthroughs - Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2009/07/30/automatically-creating-checksum-files-for-ftp-uploads.aspx" target="_blank"&gt;Automatically Creating Checksum Files for FTP Uploads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.iis.net/b/robert_mcmurray/archive/2011/12/01/changing-the-identity-of-the-ftp-extensibility-process.aspx" target="_blank"&gt;Changing the Identity of the FTP 7 Extensibility Process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In today's blog I'd like to discuss some of the extensibility features that we added in FTP 8.0, and show you how you can use those in your FTP providers.&lt;/p&gt;
&lt;h4&gt;Custom FTP Authorization&lt;/h4&gt;
&lt;p&gt;In FTP 7.5 we provided interfaces for &lt;code&gt;IFtpAuthenticationProvider&lt;/code&gt; and &lt;code&gt;IFtpRoleProvider&lt;/code&gt;, which respectively allowed developers to create FTP providers that performed user and role lookups. In FTP 8.0 we added a logical extension to that API set with &lt;code&gt;IFtpAuthorizationProvider&lt;/code&gt; interface, which allows developers to create FTP providers that perform authorization tasks.&lt;/p&gt;
&lt;p&gt;With that in mind, I wrote the following walkthrough on the IIS.net web site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://learn.iis.net/page.aspx/945/how-to-use-managed-code-c-to-create-an-ftp-authentication-and-authorization-provider-using-an-xml-database/" target="_blank"&gt;How to Use Managed Code (C#) to Create an FTP Authentication and Authorization Provider using an XML Database&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The title pretty much says it all: the provider that I describe in that walkthrough will walk you through the steps that are required to create an FTP provider that provides custom user authentication, verification of role memberships, and authorization lookups on a per-path basis.&lt;/p&gt;
&lt;h4&gt;Custom FTP Event Handling&lt;/h4&gt;
&lt;p&gt;In FTP 7.5 if you wanted your provider to respond to specific user activity, the best way to do so was to implement the &lt;code&gt;IFtpLogProvider.Log()&lt;/code&gt; interface and use that to provide a form of pseudo-event handling. In FTP 8.0 we add two event handling interfaces, &lt;code&gt;IFtpPreprocessProvider&lt;/code&gt; and &lt;code&gt;IFtpPostprocessProvider&lt;/code&gt;, which respectively allow developers to write providers that implement functionality before or after events have occurred.&lt;/p&gt;
&lt;p&gt;With that in mind, I wrote the following walkthrough on the IIS.net web site:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://learn.iis.net/page.aspx/1285/how-to-use-managed-code-c-to-create-an-ftp-provider-that-prevents-leeching/" target="_blank"&gt;How to Use Managed Code (C#) to Create an FTP Provider that Prevents Leeching&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once again, the title says it all: the provider that I describe in that walkthrough will walk you through the steps that are required to create an FTP provider that prevents FTP clients from downloading more files per-session than you have allowed in your configuration settings.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;
(Cross-posted from http://blogs.msdn.com/robert_mcmurray/)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4942714" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>IIS.net is running on IIS 8.0 Beta!</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/03/21/iis-net-is-running-on-iis-8-0-beta.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/03/21/iis-net-is-running-on-iis-8-0-beta.aspx</id><published>2012-03-22T00:36:00Z</published><updated>2012-03-22T00:36:00Z</updated><content type="html">&lt;P&gt;Here at Microsoft we're pretty passionate about testing our own software.&lt;/P&gt;
&lt;P&gt;We often ask our customers to test the pre-release versions of our new software products, and we wouldn't ask our customers to try something that we're unwilling to do. To that end, we are pleased to announce that IIS.net is fully running on IIS 8.0 Beta.&lt;/P&gt;
&lt;P&gt;Some of you may have noticed the "Running on IIS8" button above the IIS.net menu bar; this message lets you know that you're browsing to a server that is hosted on IIS 8.0 Beta:&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 30px"&gt;&lt;IMG border=2 src="http://blogs.iis.net/blogs/robert_mcmurray/IIS.NET%20on%20IIS%208.png" width=400 height=200 mce_src="http://blogs.iis.net/blogs/robert_mcmurray/IIS.NET%20on%20IIS%208.png"&gt;&lt;/P&gt;
&lt;P&gt;(Note: If you click that button, it will take you to the "What's New in IIS 8.0 for Windows 8?" section of IIS.net.)&lt;/P&gt;
&lt;P&gt;I hope you are discovering the new features of IIS 8.0 beta, and please provide feedback. We would love to hear your thoughts!&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4892506" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>FTP Logon Restrictions in IIS 8</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/03/19/ftp-logon-restrictions-in-iis-8.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/03/19/ftp-logon-restrictions-in-iis-8.aspx</id><published>2012-03-20T06:31:26Z</published><updated>2012-03-20T06:31:26Z</updated><content type="html">&lt;p&gt;One of the biggest asks from our customers over the years was to provide a way to prevent brute-force password attacks on the FTP service. On several of the FTP sites that I host, I used to see a large number of fraudulent logon requests from hackers that were trying to guess a username/password combination. My first step in trying to prevent these kinds of attacks, like most good administrators, was to implement strong password requirements and password lockout policies. This was a good first step, but there is an unfortunate downside to password lockout policies - once a hacker locks out a user account, that means that a valid user is locked out of their account. What's more, a hacker can continue your server.&lt;/p&gt;
&lt;p&gt;The FTP service has had a feature to block IP addresses, but this required something of a manual process to discover malicious behavior. To accomplish this, you had to query your log files for excessive activity, and then added the IP addresses from potential hackers to your blacklist of banned IP addresses. Besides the manual nature of this process, another big drawback to this approach is the fact that it isn't real-time, so a malicious client could be attacking your system for some time before you discover their activity.&lt;/p&gt;
&lt;p&gt;With that in mind, my next step was to go after the hackers and block their IP addresses from accessing my server. To that end, I created the custom authentication provider for the FTP 7.5 service that I documented in the following walkthrough:&lt;/p&gt;
&lt;p style="margin-left: 30px;"&gt;&lt;a href="http://learn.iis.net/page.aspx/673/how-to-use-managed-code-c-to-create-an-ftp-authentication-provider-with-dynamic-ip-restrictions/" target="_blank"&gt;How to Use Managed Code (C#) to Create an FTP Authentication Provider with Dynamic IP Restrictions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That was pretty effective, but it was really intended to be a stop-gap measure while we were working on a built-in feature for the FTP service that ships with IIS 8, which allows you to block malicious logon attempts.&lt;/p&gt;
&lt;p style="margin-left: 30px;"&gt;&lt;a href="https://public.blu.livefilestore.com/y1prMp3uVC3CVxKoCM03HY5oxx44FUr1Dik4_TRHA39s43OIBAmBk0nUr3YFP1d-M-Xz2EfZ4I1NAqXuEyIXbKRJQ/FTP%208%20Logon%20Restrictions%201.png" target="_blank"&gt;&lt;img src="https://public.blu.livefilestore.com/y1prMp3uVC3CVxKoCM03HY5oxx44FUr1Dik4_TRHA39s43OIBAmBk0nUr3YFP1d-M-Xz2EfZ4I1NAqXuEyIXbKRJQ/FTP%208%20Logon%20Restrictions%201.png" width="500" height="356" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here's the way this feature works - at the server level, you configure the maximum number of failed logon attempts that you will allow within a given time period; if someone fails to logon within that time frame, the FTP service will drop the connection, and the client will be blocked from accessing your server until the time frame has passed.&lt;/p&gt;
&lt;p style="margin-left: 30px;"&gt;&lt;a href="https://public.blu.livefilestore.com/y1pKz-sRc8TzsWfqeP1D2wWUrpuUFNO6tI9vZi9lL1S7TPoFnpOoBvQXuyTmc59EMDurUJ2s7VMCSBeaesIrbwyjQ/FTP%208%20Logon%20Restrictions%202.png" target="_blank"&gt;&lt;img src="https://public.blu.livefilestore.com/y1pKz-sRc8TzsWfqeP1D2wWUrpuUFNO6tI9vZi9lL1S7TPoFnpOoBvQXuyTmc59EMDurUJ2s7VMCSBeaesIrbwyjQ/FTP%208%20Logon%20Restrictions%202.png" width="500" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Additional details are available in the walkthrough that I wrote at the following URL:&lt;/p&gt;
&lt;p style="margin-left: 30px;"&gt;&lt;a href="http://learn.iis.net/page.aspx/1094/iis-80-ftp-logon-attempt-restrictions/" target="_blank"&gt;IIS 8.0 FTP Logon Attempt Restrictions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you'd like to try out the new FTP Logon Restrictions feature, you can download the Windows Server 8 Beta from the following URL:&lt;/p&gt;
&lt;p style="margin-left: 30px;"&gt;&lt;a href="http://www.microsoft.com/en-us/server-cloud/windows-server/v8-default.aspx" target="_blank"&gt;http://www.microsoft.com/en-us/server-cloud/windows-server/v8-default.aspx&lt;/a&gt;&lt;/p&gt;
(Cross-posted from blogs.msdn.com)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4888758" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Microsoft IIS 8.0 Express Beta is Released!</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/03/06/microsoft-iis-8-0-express-beta-is-released.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/03/06/microsoft-iis-8-0-express-beta-is-released.aspx</id><published>2012-03-06T15:12:00Z</published><updated>2012-03-06T15:12:00Z</updated><content type="html">&lt;p&gt;Earlier today the IIS Express team released the &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=29055"&gt;IIS 8.0 Express Beta&lt;/a&gt;, and there are some great new features in this release! Here are just a few of the highlights:&lt;/p&gt; &lt;dl style="line-height: 200%; margin-left: 20px"&gt;&lt;dt style="margin-left: 40px"&gt;&lt;b&gt;64-bit Support&lt;/b&gt;&lt;/dt&gt;&lt;dd style="margin-left: 60px"&gt;IIS 8.0 Express now fully supports 64-bit application development. When you install IIS Express on a 64-bit system, you actually get both 32-bit and 64-bit versions of IIS 8.0 Express installed, which allows you to use the version that matches your project's needs.&lt;/dd&gt;&lt;dt style="margin-left: 40px"&gt;&lt;b&gt;Customizable Home Directory&lt;/b&gt;&lt;/dt&gt;&lt;dd style="margin-left: 60px"&gt;The default home directory for IIS Express is &amp;quot;%UserProfile%\Documents\IISExpress&amp;quot;, but with IIS 8.0 Express you can start the iisexpress.exe process with the &amp;quot;/userhome&amp;quot; parameter to specify the home directory for your projects; this makes it easier for you to use IIS 8.0 Express with multiple development applications.&lt;/dd&gt;&lt;dt style="margin-left: 40px"&gt;&lt;b&gt;AppCmd Support for Multiple ApplicationHost.config Files&lt;/b&gt;&lt;/dt&gt;&lt;dd style="margin-left: 60px"&gt;As a complement to allowing users to customize their IIS Express home directory, IIS 8.0 Express contains a new version of AppCmd.exe that supports a new &amp;quot;/AppHostConfig&amp;quot; parameter, which makes it possible to use AppCmd.exe to edit multiple ApplicationHost.config files. By default AppCmd.exe for IIS 7 or IIS 7.5 Express will only edit the ApplicationHost.config file in your &amp;quot;%WinDir%\System32\InetSrv\Config&amp;quot; or &amp;quot;%UserProfile%\Documents\IISExpress&amp;quot; folder, but the AppCmd.exe command-line utility that ships with IIS 8.0 Express allows you to edit ApplicationHost.config files anywhere on your system.&lt;/dd&gt;&lt;/dl&gt;  &lt;p&gt;You can read more about this release at the following URL:&lt;/p&gt;  &lt;p style="line-height: 200%; margin-left: 20px"&gt;&lt;a href="http://learn.iis.net/page.aspx/1266/iis-80-express-beta-readme/"&gt;http://learn.iis.net/page.aspx/1266/iis-80-express-beta-readme/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4872474" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="IIS Express" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS+Express/default.aspx" /></entry><entry><title>Programmatically Flushing FTP Logs</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/02/04/programmatically-flushing-ftp-logs.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/02/04/programmatically-flushing-ftp-logs.aspx</id><published>2012-02-04T10:21:00Z</published><updated>2012-02-04T10:21:00Z</updated><content type="html">&lt;p&gt;I had a great question from &lt;a href="http://weblogs.asp.net/owscott/" target="_blank"&gt;Scott Forsyth&lt;/a&gt; earlier today about programmatically flushing the logs for an FTP site. Scott had noticed that there was a FlushLog method listed on the following page in the IIS Configuration Reference:&lt;/p&gt;  &lt;p style="margin-left: 20px"&gt;&lt;a href="http://www.iis.net/ConfigReference/system.applicationHost/sites/site/ftpServer" target="_blank"&gt;http://www.iis.net/ConfigReference/system.applicationHost/sites/site/ftpServer&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Unfortunately there wasn't a code sample for that method; but as luck would have it, I had already written some code to do just that. (I love synchronicity...) With that in mind, I though that I'd post the code in a blog. In keeping with the cross-language samples that I wrote for the topics in the Configuration Reference, I thought that's I'd include several languages in this blog to make it easier for someone else to copy and paste.&lt;/p&gt;  &lt;h3&gt;C#&lt;/h3&gt;  &lt;pre style="background-color: #ffffff; color: black; margin-left: 20px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; Microsoft.Web.Administration;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Sample&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main()&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (ServerManager serverManager = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServerManager())&lt;br /&gt;      {&lt;br /&gt;         Configuration config = serverManager.GetApplicationHostConfiguration();&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Retrieve the sites collection.&lt;/span&gt;&lt;br /&gt;         ConfigurationSection sitesSection = config.GetSection(&lt;span style="color: #800000"&gt;&amp;quot;system.applicationHost/sites&amp;quot;&lt;/span&gt;);&lt;br /&gt;         ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();&lt;br /&gt;&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Locate a specific site.&lt;/span&gt;&lt;br /&gt;         ConfigurationElement siteElement = FindElement(sitesCollection,&lt;span style="color: #800000"&gt;&amp;quot;site&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;@&amp;quot;ftp.contoso.com&amp;quot;&lt;/span&gt;);&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (siteElement == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000"&gt;&amp;quot;Element not found!&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Create an object for the ftpServer element.&lt;/span&gt;&lt;br /&gt;         ConfigurationElement ftpServerElement = siteElement.GetChildElement(&lt;span style="color: #800000"&gt;&amp;quot;ftpServer&amp;quot;&lt;/span&gt;);&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Create an instance of the FlushLog method.&lt;/span&gt;&lt;br /&gt;         ConfigurationMethodInstance FlushLog = ftpServerElement.Methods[&lt;span style="color: #800000"&gt;&amp;quot;FlushLog&amp;quot;&lt;/span&gt;].CreateInstance();&lt;br /&gt;         &lt;span style="color: #008000"&gt;// Execute the method to flush the logs for the FTP site.&lt;/span&gt;&lt;br /&gt;         FlushLog.Execute();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: #008000"&gt;// Locate and return the index for a specific element in a collection.&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ConfigurationElement FindElement(ConfigurationElementCollection collection, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; elementTagName, &lt;span style="color: #0000ff"&gt;params&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] keyValues)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (ConfigurationElement element &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; collection)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; matches = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; keyValues.Length; i += 2)&lt;br /&gt;            {&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; o = element.GetAttributeValue(keyValues[i]);&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (o != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;               {&lt;br /&gt;                  &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; = o.ToString();&lt;br /&gt;               }&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!String.Equals(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))&lt;br /&gt;               {         matches = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;                  &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;               }&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (matches)&lt;br /&gt;            {&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; element;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;

&lt;h3&gt;VB.NET&lt;/h3&gt;

&lt;pre style="background-color: #ffffff; color: black; margin-left: 20px"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Text&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; Microsoft.Web.Administration&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Module&lt;/span&gt; Sample&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Main()&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; serverManager &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ServerManager = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; ServerManager&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; config &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Configuration = serverManager.GetApplicationHostConfiguration&lt;br /&gt;      &lt;span style="color: #008000"&gt;' Retrieve the sites collection.&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; sitesSection &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationSection = config.GetSection(&lt;span style="color: #800000"&gt;&amp;quot;system.applicationHost/sites&amp;quot;&lt;/span&gt;)&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; sitesCollection &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElementCollection = sitesSection.GetCollection&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: #008000"&gt;' Locate a specific site.&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; siteElement &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElement = FindElement(sitesCollection,&lt;span style="color: #800000"&gt;&amp;quot;site&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;ftp.contoso.com&amp;quot;&lt;/span&gt;)&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; (siteElement &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;Throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; InvalidOperationException(&lt;span style="color: #800000"&gt;&amp;quot;Element not found!&amp;quot;&lt;/span&gt;)&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: #008000"&gt;' Create an object for the ftpServer element.&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; ftpServerElement &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElement = siteElement.GetChildElement(&lt;span style="color: #800000"&gt;&amp;quot;ftpServer&amp;quot;&lt;/span&gt;)&lt;br /&gt;      &lt;span style="color: #008000"&gt;' Create an instance of the FlushLog method.&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; FlushLog &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationMethodInstance = ftpServerElement.Methods(&lt;span style="color: #800000"&gt;&amp;quot;FlushLog&amp;quot;&lt;/span&gt;).CreateInstance()&lt;br /&gt;      &lt;span style="color: #008000"&gt;' Execute the method to flush the logs for the FTP site.&lt;/span&gt;&lt;br /&gt;      FlushLog.Execute()&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: #008000"&gt;' Locate and return the index for a specific element in a collection.&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; FindElement(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; collection &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElementCollection, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; elementTagName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ParamArray&lt;/span&gt; keyValues() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElement&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; element &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ConfigurationElement &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; collection&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; matches &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; keyValues.Length - 1 &lt;span style="color: #0000ff"&gt;Step&lt;/span&gt; 2&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; o &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt; = element.GetAttributeValue(keyValues(i))&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; (o) &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;                  value = o.ToString&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Equals(value, keyValues((i + 1)), StringComparison.OrdinalIgnoreCase) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;                  matches = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;br /&gt;                  &lt;span style="color: #0000ff"&gt;Exit&lt;/span&gt; &lt;span style="color: #0000ff"&gt;For&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; matches &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; element&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Module&lt;/pre&gt;

&lt;h3&gt;JavaScript&lt;/h3&gt;

&lt;pre style="background-color: #ffffff; color: black; margin-left: 20px"&gt;&lt;span style="color: #008000"&gt;// Create a Writable Admin Manager object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; adminManager = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color: #800000"&gt;'Microsoft.ApplicationHost.WritableAdminManager'&lt;/span&gt;);&lt;br /&gt;adminManager.CommitPath = &lt;span style="color: #800000"&gt;&amp;quot;MACHINE/WEBROOT/APPHOST&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// Retrieve the sites collection.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sitesSection = adminManager.GetAdminSection(&lt;span style="color: #800000"&gt;&amp;quot;system.applicationHost/sites&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;MACHINE/WEBROOT/APPHOST&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; sitesCollection = sitesSection.Collection;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// Locate a specific site.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; siteElementPos = FindElement(sitesCollection,&lt;span style="color: #800000"&gt;&amp;quot;site&amp;quot;&lt;/span&gt;,[&lt;span style="color: #800000"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;ftp.contoso.com&amp;quot;&lt;/span&gt;]);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (siteElementPos == -1) &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #800000"&gt;&amp;quot;Element not found!&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// Retrieve the site element.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; siteElement = sitesCollection.Item(siteElementPos);&lt;br /&gt;&lt;span style="color: #008000"&gt;// Create an object for the ftpServer element.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; ftpServerElement = siteElement.ChildElements.Item(&lt;span style="color: #800000"&gt;&amp;quot;ftpServer&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008000"&gt;// Create an instance of the FlushLog method.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; FlushLog = ftpServerElement.Methods.Item(&lt;span style="color: #800000"&gt;&amp;quot;FlushLog&amp;quot;&lt;/span&gt;).CreateInstance();&lt;br /&gt;&lt;span style="color: #008000"&gt;// Execute the method to flush the logs for the FTP site.&lt;/span&gt;&lt;br /&gt;FlushLog.Execute();&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// Locate and return the index for a specific element in a collection.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; FindElement(collection, elementTagName, valuesToMatch) {&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; i = 0; i &amp;lt; collection.Count; i++) {&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; element = collection.Item(i);&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (element.Name == elementTagName) {&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; matches = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; iVal = 0; iVal &amp;lt; valuesToMatch.length; iVal += 2) {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; property = element.GetPropertyByName(valuesToMatch[iVal]);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; value = property.Value;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (value != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) {&lt;br /&gt;               value = value.toString();&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (value != valuesToMatch[iVal + 1]) {&lt;br /&gt;               matches = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (matches) {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; i;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; -1;&lt;br /&gt;}&lt;/pre&gt;

&lt;h3&gt;VBScript&lt;/h3&gt;

&lt;pre style="background-color: #ffffff; color: black; margin-left: 20px"&gt;&lt;span style="color: #008000"&gt;' Create a Writable Admin Manager object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; adminManager = CreateObject(&lt;span style="color: #800000"&gt;&amp;quot;Microsoft.ApplicationHost.WritableAdminManager&amp;quot;&lt;/span&gt;)&lt;br /&gt;adminManager.CommitPath = &lt;span style="color: #800000"&gt;&amp;quot;MACHINE/WEBROOT/APPHOST&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;' Retrieve the sites collection.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; sitesSection = adminManager.GetAdminSection(&lt;span style="color: #800000"&gt;&amp;quot;system.applicationHost/sites&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;MACHINE/WEBROOT/APPHOST&amp;quot;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; sitesCollection = sitesSection.Collection&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;' Locate a specific site.&lt;/span&gt;&lt;br /&gt;siteElementPos = FindElement(sitesCollection,&lt;span style="color: #800000"&gt;&amp;quot;site&amp;quot;&lt;/span&gt;,Array(&lt;span style="color: #800000"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;,&lt;span style="color: #800000"&gt;&amp;quot;ftp.contoso.com&amp;quot;&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #0000ff"&gt;If&lt;/span&gt; siteElementPos = -1 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;   WScript.Echo &lt;span style="color: #800000"&gt;&amp;quot;Element not found!&amp;quot;&lt;/span&gt;&lt;br /&gt;   WScript.Quit&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;' Retrieve the site element.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; siteElement = sitesCollection.Item(siteElementPos)&lt;br /&gt;&lt;span style="color: #008000"&gt;' Create an object for the ftpServer element.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; ftpServerElement = siteElement.ChildElements.Item(&lt;span style="color: #800000"&gt;&amp;quot;ftpServer&amp;quot;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008000"&gt;' Create an instance of the FlushLog method.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; FlushLog = ftpServerElement.Methods.Item(&lt;span style="color: #800000"&gt;&amp;quot;FlushLog&amp;quot;&lt;/span&gt;).CreateInstance()&lt;br /&gt;&lt;span style="color: #008000"&gt;' Execute the method to flush the logs for the FTP site.&lt;/span&gt;&lt;br /&gt;FlushLog.Execute()&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;' Locate and return the index for a specific element in a collection.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; FindElement(collection, elementTagName, valuesToMatch)&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CInt&lt;/span&gt;(collection.Count) - 1&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; element = collection.Item(i)&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; element.Name = elementTagName &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;         matches = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; iVal = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; UBound(valuesToMatch) &lt;span style="color: #0000ff"&gt;Step&lt;/span&gt; 2&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt; &lt;span style="color: #0000ff"&gt;property&lt;/span&gt; = element.GetPropertyByName(valuesToMatch(iVal))&lt;br /&gt;            value = &lt;span style="color: #0000ff"&gt;property&lt;/span&gt;.Value&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; IsNull(value) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;               value = &lt;span style="color: #0000ff"&gt;CStr&lt;/span&gt;(value)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; value = &lt;span style="color: #0000ff"&gt;CStr&lt;/span&gt;(valuesToMatch(iVal + 1)) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;               matches = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: #0000ff"&gt;Exit&lt;/span&gt; &lt;span style="color: #0000ff"&gt;For&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; matches &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Exit&lt;/span&gt; &lt;span style="color: #0000ff"&gt;For&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; matches &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;      FindElement = i&lt;br /&gt;   &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;&lt;br /&gt;      FindElement = -1   &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Function&lt;/pre&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Hopefully this gives you an idea of how to call the FlushLog method. You can also use these examples to call the Start and Stop methods for FTP sites; you just need to substitute the correct method in place of the FlushLog method.&lt;/p&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4872470" width="1" height="1"&gt;</content><author><name>robmcm</name><uri>http://blogs.iis.net/members/robmcm.aspx</uri></author><category term="Scripting" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/Scripting/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Using URL Rewrite to Insert Different Scripts Based on Browser Type</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/02/03/using-url-rewrite-to-insert-different-scripts-based-on-browser-type.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/02/03/using-url-rewrite-to-insert-different-scripts-based-on-browser-type.aspx</id><published>2012-02-03T13:14:11Z</published><updated>2012-02-03T13:14:11Z</updated><content type="html">I just stumbled across a piece of sample code that I had written several months ago for a coworker, and I thought that I'd share it with everyone. Here's the scenario: my coworker asked me if it was possible to have different client-side scripts inserted dynamically depending on the type of web browser that is being used. If the application was written in ASP.NET or some other dynamic language, then it would be trivial to determine the browser type and return the correct HTML &amp;lt;script&amp;gt; block...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2012/02/03/using-url-rewrite-to-insert-different-scripts-based-on-browser-type.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4814815" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="Scripting" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/Scripting/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Advanced Log Parser Charts Part 2 - Using Gradient Colors for Area Charts</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/01/30/advanced-log-parser-charts-part-2-using-gradient-colors-for-area-charts.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/01/30/advanced-log-parser-charts-part-2-using-gradient-colors-for-area-charts.aspx</id><published>2012-01-30T08:30:46Z</published><updated>2012-01-30T08:30:46Z</updated><content type="html">In Part 2 of this series, I'll show you how to customize the area chart from Part 1 to show the chart area with a gradient. More specifically, there are three different chart gradient methods that we'll take a look at in this blog post: SetOneColorGradient SetTwoColorGradient SetPresetGradient Before I continue, there is one quick Log Parser convention that you should realize: there are two objects that Log Parser will create and pass to your script. As you look at the sample scripts in this post...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2012/01/30/advanced-log-parser-charts-part-2-using-gradient-colors-for-area-charts.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4806200" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="Scripting" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/Scripting/default.aspx" /><category term="LogParser" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/LogParser/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Advanced Log Parser Charts Part 1 - Working With Configuration Scripts</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2012/01/29/advanced-log-parser-charts-part-1-working-with-configuration-scripts.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2012/01/29/advanced-log-parser-charts-part-1-working-with-configuration-scripts.aspx</id><published>2012-01-29T06:13:52Z</published><updated>2012-01-29T06:13:52Z</updated><content type="html">I recently had a situation where I wanted to customize the chart output from Log Parser, and after a bunch of research I eventually arrived at the conclusion that configuration scripts for create customized charts are probably the least-documented feature of Log Parser. After a lot of experimentation, (and a bit of frustration), I finally managed to achieve the results that I wanted. With that in mind, I thought that it would make a great blog series if I documented some of the settings that I used...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2012/01/29/advanced-log-parser-charts-part-1-working-with-configuration-scripts.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4805083" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="Scripting" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/Scripting/default.aspx" /><category term="LogParser" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/LogParser/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Storing IIS 7.5 WebDAV Properties in NTFS Alternate Data Streams</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/12/31/storing-iis-7-5-webdav-properties-in-ntfs-alternate-data-streams.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/12/31/storing-iis-7-5-webdav-properties-in-ntfs-alternate-data-streams.aspx</id><published>2011-12-31T07:39:26Z</published><updated>2011-12-31T07:39:26Z</updated><content type="html">Two months ago Microsoft published an update for the WebDAV module that shipped with IIS 7.5 in Windows 7 and Windows Server 2008 R2, and this update is documented in the Microsoft Knowledge Base article ID 2593591: FIX: A hotfix is available that enables WebDAV to store the properties of file resources by using NTFS alternate data streams in IIS 7.5 This update enables administrators to configure the IIS 7.5 WebDAV module to store WebDAV-based properties in NTFS alternate data streams instead of...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/12/31/storing-iis-7-5-webdav-properties-in-ntfs-alternate-data-streams.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4757854" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="Scripting" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/Scripting/default.aspx" /><category term="WebDAV" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/WebDAV/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>Changing the Identity of the FTP 7 Extensibility Process</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/12/01/changing-the-identity-of-the-ftp-extensibility-process.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/12/01/changing-the-identity-of-the-ftp-extensibility-process.aspx</id><published>2011-12-01T22:22:00Z</published><updated>2011-12-01T22:22:00Z</updated><content type="html">Many IIS 7 FTP developers may not have noticed, but all custom FTP 7 extensibility providers execute through COM+ in a DLLHOST.exe process, which runs as NETWORK SERVICE by default. That being said, NETWORK SERVICE does not always have the right permissions to access some of the areas on your system where you may be attempt to implement custom functionality. What this means is, some of the custom features that you try to implement may not work as expected. For example, if you look at the custom FTP...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/12/01/changing-the-identity-of-the-ftp-extensibility-process.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4711137" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>FTP Clients - Recap</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/11/16/ftp-clients-recap.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/11/16/ftp-clients-recap.aspx</id><published>2011-11-16T20:55:07Z</published><updated>2011-11-16T20:55:07Z</updated><content type="html">Having written 10 blog posts in my series about FTP clients, I decided that it might be a good idea to recap some of the information that I have presented thus far. With that in mind, here is a quick recap of the entire series to date: Part 1: Web Browser Support Part 2: Explicit FTPS versus Implicit FTPS Part 3: Creating a Global Listener FTP Site Part 4: FileZilla Part 5: MOVEit Freely Command-Line Secure FTP Client Part 6: Core FTP LE Part 7: Kermit FTP Client Part 8: SmartFTP Client Part 9: Expression...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/11/16/ftp-clients-recap.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4686702" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>How to use Managed Code (C#) to create an FTP Home Directory Provider that is based on the Remote Client IP Address</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/11/02/how-to-use-managed-code-c-to-create-an-ftp-home-directory-provider-that-is-based-on-the-remote-client-ip-address.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/11/02/how-to-use-managed-code-c-to-create-an-ftp-home-directory-provider-that-is-based-on-the-remote-client-ip-address.aspx</id><published>2011-11-02T22:02:20Z</published><updated>2011-11-02T22:02:20Z</updated><content type="html">I recently had an interesting scenario that was presented to me by a customer: they had a business requirement where they needed to give the same username and password to a group of people, but they didn't want any two people to be able to see anyone else's files. This seemed like an unusual business requirement to me; the whole point of keeping users separate is one of the reasons why we added user isolation to the FTP service. With that in mind, my first suggestion was - of course - to rethink...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/11/02/how-to-use-managed-code-c-to-create-an-ftp-home-directory-provider-that-is-based-on-the-remote-client-ip-address.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4664985" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/IIS/default.aspx" /></entry><entry><title>FTP Clients - Part 10: FTP Voyager</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/10/21/ftp-clients-part-10-ftp-voyager.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/10/21/ftp-clients-part-10-ftp-voyager.aspx</id><published>2011-10-21T16:30:10Z</published><updated>2011-10-21T16:30:10Z</updated><content type="html">For this installment in my series about FTP Clients, I'd like to take a look at FTP Voyager from Rhino Software. For this blog I used FTP Voyager 15.2.0.17, and it is available from the following URL: http://www.ftpvoyager.com/ FTP Voyager is a great FTP client that supports a wide array of features and connection options, but I shouldn't get ahead of myself and talk about everything in my introduction. ;-] Fig. 1 - FTP Voyager Splash Screen At the time of this blog post, FTP Voyager is a for-retail...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/10/21/ftp-clients-part-10-ftp-voyager.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4649500" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="FTP" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/FTP/default.aspx" /></entry><entry><title>Sending WebDAV Requests in .NET Revisited</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/robert_mcmurray/archive/2011/10/18/sending-webdav-requests-in-net-revisited.aspx" /><id>http://blogs.iis.net/robert_mcmurray/archive/2011/10/18/sending-webdav-requests-in-net-revisited.aspx</id><published>2011-10-18T07:05:10Z</published><updated>2011-10-18T07:05:10Z</updated><content type="html">I recently spoke with a great customer in India, and he was experimenting with the code from my Sending WebDAV Requests in .NET blog post. He had a need to send the WebDAV LOCK/UNLOCK commands, so I wrote a quick addition to the code in my original blog post to send those commands, and I thought that I'd share that code in an updated blog post. Using WebDAV Locks First of all, you may need to enable WebDAV locks on your server. To do so, follow the instructions in the following walkthrough: How to...(&lt;a href="http://blogs.iis.net/robert_mcmurray/archive/2011/10/18/sending-webdav-requests-in-net-revisited.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=4643113" width="1" height="1"&gt;</content><author><name>Anonymous</name><uri>http://blogs.iis.net/members/Anonymous.aspx</uri></author><category term="WebDAV" scheme="http://blogs.iis.net/robert_mcmurray/archive/tags/WebDAV/default.aspx" /></entry></feed>
