<?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>Robert McMurray's Blog [MSFT] : Scripting</title><link>http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx</link><description>Tags: Scripting</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Migrating FPSE Roles Between Servers</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/10/12/migrating-fpse-roles-between-servers.aspx</link><pubDate>Mon, 12 Oct 2009 17:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9906215</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9906215.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9906215</wfw:commentRss><description>&lt;P&gt;I ran into one of those strange situations the other day where you feel like you've been doing the same thing on your computer at some time in the distant past - kind of like déjà vu for geeks. In this specific case, I was moving some web sites that I am hosting for other people that still use FPSE from an older physical server to a new virtual server that is hosted through Hyper-V. (I'm also trying to convert them all to WebDAV, but that's another story.)&lt;/P&gt;
&lt;P&gt;Anyway, I had dozens of custom FPSE roles set up for each of those sites that I didn't want to manually replicate on the new server. Unfortunately, FPSE doesn't have a way to migrate the roles from one server to another. All of those FPSE-related roles are kept in local groups with cryptic names like &lt;B&gt;OWS_nnnnn_xxxxx&lt;/B&gt;, so I started thinking, "&lt;I&gt;If only I could write a script that could migrate the OWS_nnnnn_xxxxx groups between the two servers...&lt;/I&gt;"&lt;/P&gt;
&lt;P&gt;Then it dawned on me - I had written such a script several years ago! (Now if only I could find it...) Like many people that write code, I'm something of a code packrat - I tend to keep all of my old code around somewhere, just in case. Sparing you the details of my long search, I eventually found the script that I was looking for, and I thought that it would make a nice blog because I'm sure that someone else may need to migrate their FPSE roles.&lt;/P&gt;
&lt;P&gt;Here's the script and a brief description of what script it will do:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Create ADSI objects for the source and destination servers. &lt;/LI&gt;
&lt;LI&gt;Loop through the ADSI objects and only looks for groups. 
&lt;UL&gt;
&lt;LI&gt;Note: You could also use an &lt;CODE&gt;object.Filter&lt;/CODE&gt; statement for this. &lt;/LI&gt;
&lt;LI&gt;You will obviously need to update the server names for your source and destination servers. &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Compare each group name with the group stub and only process those groups that match the stub. 
&lt;UL&gt;
&lt;LI&gt;By way of explanation, FPSE role groups have names like &lt;B&gt;OWS_nnnnn_xxxxx&lt;/B&gt;, where &lt;B&gt;nnnnn&lt;/B&gt; is a simple numeric hash that identifies the site, and the &lt;B&gt;xxxxx&lt;/B&gt; denotes the individual FPSE role like &lt;I&gt;admin&lt;/I&gt;, &lt;I&gt;browser&lt;/I&gt;, &lt;I&gt;author&lt;/I&gt;, etc. &lt;/LI&gt;
&lt;LI&gt;The script uses the &lt;I&gt;OWS_nnnnn&lt;/I&gt; stub and will copy all of the role groups that it finds. For example: &lt;I&gt;OWS_12345_admin&lt;/I&gt;, &lt;I&gt;OWS_12345_author&lt;/I&gt;, &lt;I&gt;OWS_12345_browser&lt;/I&gt;, etc. &lt;/LI&gt;
&lt;LI&gt;In the code I used &lt;I&gt;OWS_nnnnn&lt;/I&gt; for the stub, so you would have to replace &lt;I&gt;nnnnn&lt;/I&gt; with the numbers that you see in the list of groups using Computer Management on the source computer. &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Determine if the group exists on the destination server, and creates it if it doesn't already exist. &lt;/LI&gt;
&lt;LI&gt;Loop through the list of users in the group on the source server and adds those same users to the group on the destination server. 
&lt;UL&gt;
&lt;LI&gt;Note: This will fail for any local users that were used on the source server that do not exist on the destination server. I only used domain accounts, so I didn't run into that problem. &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Some additional notes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The person that runs this code must be an administrator on each server. &lt;/LI&gt;
&lt;LI&gt;The two computers must be on the same network or the ADSI calls will fail. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;With that in mind, here's the script code:&lt;/P&gt;
&lt;HR&gt;
&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: black"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;Option&lt;/SPAN&gt; Explicit
&lt;SPAN style="COLOR: #0000ff"&gt;On&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Error&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Resume&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objComputer1, objGroup1
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objComputer2, objGroup2

&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objOBJECT
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objUSER
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; strGroupName
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; strGroupDesc

&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; ERROR_SUCCESS = 0

&lt;SPAN style="COLOR: #008000"&gt;' Note: update the following server names.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; strComputer1 = &lt;SPAN style="COLOR: #800000"&gt;"SERVER1"&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; strComputer2 = &lt;SPAN style="COLOR: #800000"&gt;"SERVER2"&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #008000"&gt;' Note: update the following group stub.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; strGroupStub = &lt;SPAN style="COLOR: #800000"&gt;"OWS_nnnnn"&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #008000"&gt;' ----------------------------------------------------------------------&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objComputer1 = GetObject(&lt;SPAN style="COLOR: #800000"&gt;"WinNT://"&lt;/SPAN&gt; &amp;amp; strComputer1 &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;",computer"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objComputer2 = GetObject(&lt;SPAN style="COLOR: #800000"&gt;"WinNT://"&lt;/SPAN&gt; &amp;amp; strComputer2 &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;",computer"&lt;/SPAN&gt;)
&lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError

&lt;SPAN style="COLOR: #0000ff"&gt;For&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Each&lt;/SPAN&gt; objOBJECT &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; objComputer1
  &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; UCase(objOBJECT.&lt;SPAN style="COLOR: #0000ff"&gt;Class&lt;/SPAN&gt;) = &lt;SPAN style="COLOR: #800000"&gt;"GROUP"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    strGroupName = objOBJECT.Name

    &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; UCase(Left(strGroupName,Len(strGroupStub))) = UCase(strGroupStub) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;

      Err.Clear : &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objGroup1 = GetObject(&lt;SPAN style="COLOR: #800000"&gt;"WinNT://"&lt;/SPAN&gt; &amp;amp; strComputer1 &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"/"&lt;/SPAN&gt; &amp;amp; strGroupName &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;",group"&lt;/SPAN&gt;)
      &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError

      strGroupDesc = objGroup1.Description
      WScript.Echo &lt;SPAN style="COLOR: #800000"&gt;"Copying "&lt;/SPAN&gt; &amp;amp; strGroupName &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"..."&lt;/SPAN&gt;

      Err.Clear : &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objGroup2 = GetObject(&lt;SPAN style="COLOR: #800000"&gt;"WinNT://"&lt;/SPAN&gt; &amp;amp; strComputer2 &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"/"&lt;/SPAN&gt; &amp;amp; strGroupName &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;",group"&lt;/SPAN&gt;)
      
      &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
        &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; -2147022676 &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
          HandleError
        &lt;SPAN style="COLOR: #0000ff"&gt;Else&lt;/SPAN&gt;
          Err.Clear : &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objGroup2 = objComputer2.Create(&lt;SPAN style="COLOR: #800000"&gt;"group"&lt;/SPAN&gt;,strGroupName)
          &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError

          Err.Clear : objGroup2.SetInfo
          &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError

          Err.Clear : objGroup2.Description = strGroupDesc
          &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError

          Err.Clear : objGroup2.SetInfo
          &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError
        &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;For&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Each&lt;/SPAN&gt; objUSER &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; objGroup1.Members
        WScript.Echo vbTab &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"Adding "&lt;/SPAN&gt; &amp;amp; objUSER.Name
        Err.Clear : objGroup2.Add objUSER.ADsPath 
        &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; -2147023518 &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError
        Err.Clear : objGroup2.SetInfo
        &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;lt;&amp;gt; ERROR_SUCCESS &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt; HandleError
      &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;

      &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objGroup1 = &lt;SPAN style="COLOR: #0000ff"&gt;Nothing&lt;/SPAN&gt;
      &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objGroup2 = &lt;SPAN style="COLOR: #0000ff"&gt;Nothing&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: #008000"&gt;' ----------------------------------------------------------------------&lt;/SPAN&gt;

&lt;SPAN style="COLOR: #0000ff"&gt;Sub&lt;/SPAN&gt; HandleError()
  WScript.Echo vbCrLf &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"FATAL ERROR:"&lt;/SPAN&gt;
  WScript.Echo vbTab &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"Number: "&lt;/SPAN&gt; &amp;amp; &lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number) &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;" (0x"&lt;/SPAN&gt; &amp;amp; Hex(&lt;SPAN style="COLOR: #0000ff"&gt;CLng&lt;/SPAN&gt;(Err.Number)) &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;")"&lt;/SPAN&gt;
  WScript.Echo vbTab &amp;amp; &lt;SPAN style="COLOR: #800000"&gt;"Description: "&lt;/SPAN&gt; &amp;amp; Err.Description
  WScript.Quit
&lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;HR&gt;

&lt;P&gt;As usual, all of the normal caveats like "&lt;I&gt;this code is totally unsupported&lt;/I&gt;" will apply, but I've used this code with great success on several severs over the years. The great thing about this code is that it's non-destructive because it doesn't delete anything on the source server - it only creates groups on the destination server.&lt;/P&gt;
&lt;P&gt;You can also use &lt;TT&gt;&lt;SPAN style="COLOR: #0000ff"&gt;Const&lt;/SPAN&gt; strGroupStub = &lt;SPAN style="COLOR: #800000"&gt;"OWS_"&lt;/SPAN&gt;&lt;/TT&gt; to migrate all FPSE role groups from one server to another, but that's a major operation. With that in mind, I'd try it out on a single FPSE site using "&lt;B&gt;OWS_nnnnn&lt;/B&gt;" as a stub before trying out a full server by using "&lt;B&gt;OWS_&lt;/B&gt;" as a stub; the latter is very time-consuming and CPU-intensive.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9906215" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FrontPage+Topics/default.aspx">FrontPage Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Creating Recursive Directory Listing Files for FTP Clients</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/09/05/creating-recursive-directory-listing-files-for-ftp-clients.aspx</link><pubDate>Sat, 05 Sep 2009 22:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9891823</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9891823.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9891823</wfw:commentRss><description>&lt;P&gt;One of the changes that we made in FTP 7.0 and FTP 7.5 was to remove recursive directory listings, which are commonly retrieved by typing "&lt;CODE&gt;ls -lR&lt;/CODE&gt;" from a command-line FTP client, which should send a command like "&lt;CODE&gt;NLST -lR&lt;/CODE&gt;" over FTP to the server. There were several reasons why we decided to remove recursive directory listings, but the main reason was simply to reduce CPU usage on the server; recursive directory listing requests take a lot of resources to fulfill. With that in mind, both FTP 7.0 and FTP 7.5 will ignore the recursive switch on directory requests.&lt;/P&gt;
&lt;P&gt;That being said - quite often it's pretty handy to have a full directory listing from an FTP server. From a client perspective you could probably write script to automate an FTP client to create a recursive listing, but that's a lot of work. Back in my younger days when I ran FTP sites on Unix servers, I would always create two types of list files on my FTP servers for FTP clients to retrieve:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;"&lt;STRONG&gt;ls-lr.txt&lt;/STRONG&gt;" - I would create only one file of this type for my entire FTP server, which would go in the root of my FTP site and it would contain a full recursive listing of all files in my FTP site. &lt;/LI&gt;
&lt;LI&gt;"&lt;STRONG&gt;00index.txt&lt;/STRONG&gt;" - I would create one file of this type in each folder of my FTP site, and each index file would contain a listing of files and their descriptions for that folder. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Of course, anyone that's been around the Internet since the days before we had HTTP and the world-wide-web should know that I didn't come up with this idea on my own - I learned it from other FTP site administrators. (And anyone who remembers those days should also recognize those two files with a strange sense of nostalgia. 00index.txt files of course led to index.htm files when WWW sites came along later, but that's another story.)&lt;/P&gt;
&lt;P&gt;In any event, as I continued to host FTP sites over the years I have written various scripts to create recursive directory listings, and I thought that one of my scripts might make a good blog post. With that in mind, here is a Windows Script Host file that I created, which I named "ls-lr.vbs", and this script will create a recursive directory listing for an FTP site. I choose the Unix directory listing style for this script since that's the format that I have used for years and the broader number of FTP clients and users should recognize it.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: #000000"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;Option&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Explicit&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;On&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Error&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Resume&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Next
&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;' Declare all variables.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objArguments
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; strBaseFolder
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objFSO
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objFile
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objFolder
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objSubFolder
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; objSubFile
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; lngFolderCount
&lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; lngBaseCount
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objArguments = WScript.Arguments

&lt;SPAN style="COLOR: #008000"&gt;' Determine the number of command-line arguments.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Select&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Case&lt;/SPAN&gt; objArguments.Count
  &lt;SPAN style="COLOR: #0000ff"&gt;Case&lt;/SPAN&gt; 0:
    strBaseFolder = WScript.ScriptFullName
    strBaseFolder = Left(strBaseFolder,InStrRev(strBaseFolder,"&lt;SPAN style="COLOR: #8b0000"&gt;\"))
&lt;/SPAN&gt;  &lt;SPAN style="COLOR: #0000ff"&gt;Case&lt;/SPAN&gt; 1:
    strBaseFolder = objArguments(0)
  &lt;SPAN style="COLOR: #0000ff"&gt;Case&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Else&lt;/SPAN&gt;:
    MsgBox "&lt;SPAN style="COLOR: #8b0000"&gt;This script takes a single argument for the&lt;/SPAN&gt;" &amp;amp; vbCrLf &amp;amp; _
      "&lt;SPAN style="COLOR: #8b0000"&gt;starting directory, or specify no arguments&lt;/SPAN&gt;" &amp;amp; vbCrLf &amp;amp; _
      "&lt;SPAN style="COLOR: #8b0000"&gt;to use the current directory.&lt;/SPAN&gt;", vbInformation
&lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Select
&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #008000"&gt;' Create a file system object.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objFSO = WScript.CreateObject("&lt;SPAN style="COLOR: #8b0000"&gt;Scripting.FileSystemObject&lt;/SPAN&gt;")

&lt;SPAN style="COLOR: #008000"&gt;' Test if the base folder exists.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; Right(strBaseFolder,1) &amp;lt;&amp;gt; "&lt;SPAN style="COLOR: #8b0000"&gt;\" Then strBaseFolder = strBaseFolder &amp;amp; &lt;/SPAN&gt;"\"&lt;SPAN style="COLOR: #8b0000"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; objFSO.FolderExists(strBaseFolder) = &lt;SPAN style="COLOR: #0000ff"&gt;False&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    MsgBox "&lt;SPAN style="COLOR: #8b0000"&gt;The specified folder does not exist.&lt;/SPAN&gt;", vbCritical
    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: #008000"&gt;' Open the output file for the directory listing.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objFile = objFSO.CreateTextFile(strBaseFolder &amp;amp; "&lt;SPAN style="COLOR: #8b0000"&gt;ls-lr.txt&lt;/SPAN&gt;")
     
&lt;SPAN style="COLOR: #008000"&gt;' Define the initial values for the folder counters.&lt;/SPAN&gt;
lngFolderCount = 1
lngBaseCount = 0
  
&lt;SPAN style="COLOR: #008000"&gt;' Dimension an array to hold the folder names.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;ReDim&lt;/SPAN&gt; strFolders(1)
  
&lt;SPAN style="COLOR: #008000"&gt;' Store the root folder in the array.&lt;/SPAN&gt;
strFolders(lngFolderCount) = strBaseFolder
    
&lt;SPAN style="COLOR: #008000"&gt;' Loop while we still have folders to process.&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;While&lt;/SPAN&gt; lngFolderCount &amp;lt;&amp;gt; lngBaseCount
  &lt;SPAN style="COLOR: #008000"&gt;' Set up a folder object to a base folder.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Set&lt;/SPAN&gt; objFolder = objFSO.GetFolder(strFolders(lngBaseCount+1))
  
  &lt;SPAN style="COLOR: #008000"&gt;' Output the folder name to the listing file.&lt;/SPAN&gt;
  objFile.WriteLine vbCrLf &amp;amp; _
    Replace(Mid(strFolders(lngBaseCount+1),Len(strBaseFolder)),"&lt;SPAN style="COLOR: #8b0000"&gt;\",&lt;/SPAN&gt;"/"&lt;SPAN style="COLOR: #8b0000"&gt;) &amp;amp; _
&lt;/SPAN&gt;    vbCrLf
  
  &lt;SPAN style="COLOR: #008000"&gt;' Loop through the collection of subfolders for the base folder.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;For&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Each&lt;/SPAN&gt; objSubFolder &lt;SPAN style="COLOR: #0000ff"&gt;In&lt;/SPAN&gt; objFolder.SubFolders
    &lt;SPAN style="COLOR: #008000"&gt;' Increment the folder count.&lt;/SPAN&gt;
    lngFolderCount = lngFolderCount + 1
    &lt;SPAN style="COLOR: #008000"&gt;' Increase the array size&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;ReDim&lt;/SPAN&gt; Preserve strFolders(lngFolderCount)
    &lt;SPAN style="COLOR: #008000"&gt;' Store the folder name in the array.&lt;/SPAN&gt;
    strFolders(lngFolderCount) = objSubFolder.Path
    &lt;SPAN style="COLOR: #008000"&gt;' Output the folder to the listing file.&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;Call&lt;/SPAN&gt; WriteEntry(objSubFolder)
  &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;
  
  &lt;SPAN style="COLOR: #008000"&gt;' Loop through the collection of subfolders for the base folder.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;For&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Each&lt;/SPAN&gt; objSubFile &lt;SPAN style="COLOR: #0000ff"&gt;In&lt;/SPAN&gt; objFolder.Files
    &lt;SPAN style="COLOR: #008000"&gt;' Output the file to the listing file.&lt;/SPAN&gt;
    &lt;SPAN style="COLOR: #0000ff"&gt;Call&lt;/SPAN&gt; WriteEntry(objSubFile)
  &lt;SPAN style="COLOR: #0000ff"&gt;Next&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;' Increment the base folder counter.&lt;/SPAN&gt;
  lngBaseCount = lngBaseCount + 1
&lt;SPAN style="COLOR: #0000ff"&gt;Wend
&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Sub&lt;/SPAN&gt; WriteEntry(tmpObject)
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; tmpAttributes
  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; tmpSize
  
  &lt;SPAN style="COLOR: #008000"&gt;' Test for a symbolic link.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 1024) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;lrwxrwxrwx&lt;/SPAN&gt;"
    tmpSize = 0
  &lt;SPAN style="COLOR: #008000"&gt;' Test for a directory.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;ElseIf&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 16) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;drwxrwxrwx&lt;/SPAN&gt;"
    tmpSize = 0
  &lt;SPAN style="COLOR: #008000"&gt;' Otherwise - it's a file.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Else&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;-rwxrwxrwx&lt;/SPAN&gt;"
    tmpSize = tmpObject.Size
  &lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt;
  
  &lt;SPAN style="COLOR: #008000"&gt;' Test for a read-only object.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 1) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpAttributes = Replace(tmpAttributes,"&lt;SPAN style="COLOR: #8b0000"&gt;w&lt;/SPAN&gt;","&lt;SPAN style="COLOR: #8b0000"&gt;-&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: #008000"&gt;' Write the list entry to the output file.&lt;/SPAN&gt;
  objFile.WriteLine tmpAttributes &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt;   1 owner    group &lt;/SPAN&gt;" &amp;amp; _
    Right(&lt;SPAN style="COLOR: #0000ff"&gt;String&lt;/SPAN&gt;(15,Chr(32)) &amp;amp; &lt;SPAN style="COLOR: #0000ff"&gt;CStr&lt;/SPAN&gt;(tmpSize),15) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt; &lt;/SPAN&gt;" &amp;amp; FormatDate(tmpObject.DateLastModified) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt; &lt;/SPAN&gt;" &amp;amp; tmpObject.Name
&lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Sub
&lt;/SPAN&gt;
&lt;SPAN style="COLOR: #0000ff"&gt;Function&lt;/SPAN&gt; FormatDate(tmpDate)
  FormatDate = &lt;SPAN style="COLOR: #0000ff"&gt;CStr&lt;/SPAN&gt;(Year(tmpDate)) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt;-&lt;/SPAN&gt;" &amp;amp; Right("&lt;SPAN style="COLOR: #8b0000"&gt;00&lt;/SPAN&gt;" &amp;amp; &lt;SPAN style="COLOR: #0000ff"&gt;CStr&lt;/SPAN&gt;(Month(tmpDate)),2) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt;-&lt;/SPAN&gt;" &amp;amp; Right("&lt;SPAN style="COLOR: #8b0000"&gt;00&lt;/SPAN&gt;" &amp;amp; &lt;SPAN style="COLOR: #0000ff"&gt;CStr&lt;/SPAN&gt;(Day(tmpDate)),2)
&lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;Function&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To use the script, copy the code into Windows Notepad and save it to your computer as "ls-lr.vbs." If you double-click the script it will use the current folder to create a recursive folder listing, and if you run this script from a command-line it can take a single argument of a folder path, or you can pass no arguments to the script in order to use the current folder. In either case it will create a file named "ls-lr.txt" in the root of the destination folder that contains the recursive directory listing in Unix format.&lt;/P&gt;
&lt;P&gt;For example, the following listing was created from a folder in my music collection on my desktop computer:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;/

drwxrwxrwx   1 owner    group               0 2009-07-30 Against the Silence
dr-xr-xr-x   1 owner    group               0 2009-07-30 Collective
drwxrwxrwx   1 owner    group               0 2009-07-30 Speakeasy
-rwxrwxrwx   1 owner    group            2741 2009-09-05 ls-lr.txt

/Against the Silence

-rwxrwxrwx   1 owner    group         9386309 2009-07-30 01-Against the Silence.wma
-rwxrwxrwx   1 owner    group         3974684 2009-07-30 02-Side-Stage Syndrome.wma
-rwxrwxrwx   1 owner    group         7539014 2009-07-30 03-The Dash on my Headstone.wma
-rwxrwxrwx   1 owner    group         7244819 2009-07-30 04-Teeth Like Knives.wma
-rwxrwxrwx   1 owner    group         9910687 2009-07-30 05-The Band Played on.wma

/Collective

-r-xr-xr-x   1 owner    group         2767821 2009-03-05 At the Moment.wma
-r-xr-xr-x   1 owner    group         5259473 2009-03-05 Colt . 45.wma
-r-xr-xr-x   1 owner    group         2572687 2009-03-05 El Mariachi.wma
-r-xr-xr-x   1 owner    group         2395577 2009-03-05 Gold and Silver.wma
-r-xr-xr-x   1 owner    group         2269487 2009-03-05 Keep Waiting.wma
-r-xr-xr-x   1 owner    group         2050335 2009-03-05 Nighttown.wma
-r-xr-xr-x   1 owner    group         1458931 2009-03-05 Rise.wma
-r-xr-xr-x   1 owner    group         3140077 2009-03-05 Rivers Underneath.wma
-r-xr-xr-x   1 owner    group         2278489 2009-03-05 Sad Parade.wma
-r-xr-xr-x   1 owner    group         1909249 2009-03-05 The Hungry Wolf.wma
-r-xr-xr-x   1 owner    group         2467613 2009-03-05 Threshold.wma
-r-xr-xr-x   1 owner    group          795501 2009-03-05 Tranewreck.wma
-r-xr-xr-x   1 owner    group          417239 2009-03-05 Zzyzx.wma

/Speakeasy

-rwxrwxrwx   1 owner    group         4004604 2009-03-05 01-Minuteman.wma
-rwxrwxrwx   1 owner    group         6309752 2009-03-05 02-Sundown Motel.wma
-rwxrwxrwx   1 owner    group         5504122 2009-03-05 03-Keep Waiting.wma
-rwxrwxrwx   1 owner    group         2766262 2009-03-05 04-You Know How It Is.wma
-rwxrwxrwx   1 owner    group         7495952 2009-03-05 05-Rivers Underneath.wma
-rwxrwxrwx   1 owner    group         6294888 2009-03-05 06-Gold and Silver.wma
-rwxrwxrwx   1 owner    group         8062882 2009-03-05 07-Freefall.wma
-rwxrwxrwx   1 owner    group         4437286 2009-03-05 08-[Untitled].wma
-rwxrwxrwx   1 owner    group         3355592 2009-03-05 09-St. Eriksplan.wma
-rwxrwxrwx   1 owner    group         4966942 2009-03-05 10-Disquiet.wma
-rwxrwxrwx   1 owner    group         4788302 2009-03-05 11-Fascination Street.wma
-rwxrwxrwx   1 owner    group         7950944 2009-03-05 12-This Love.wma&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;SMALL&gt;(&lt;B&gt;Note/Disclaimer/etc.&lt;/B&gt;: It may or may not be obvious that this listing is for music from the band &lt;A href="http://en.wikipedia.org/wiki/Stavesacre" target=_blank mce_href="http://en.wikipedia.org/wiki/Stavesacre"&gt;Stavesacre&lt;/A&gt;, but just to be clear and avoid any RIAA entanglements - these files aren't actually hosted on any of my FTP sites; I used the script on my desktop computer to create a listing as an example for this blog.)&lt;/SMALL&gt;&lt;/P&gt;
&lt;P&gt;&lt;SMALL&gt;&lt;IMG src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif" mce_src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/wink_smile.gif"&gt;&lt;/SMALL&gt;&lt;/P&gt;
&lt;H3&gt;Customizing the Script Output&lt;/H3&gt;
&lt;P&gt;There are several customizations that you can do with this script, each of which has it's own benefits and drawbacks.&lt;/P&gt;
&lt;H4&gt;Adding Directory Sizes&lt;/H4&gt;
&lt;P&gt;It is trivial from a coding perspective to have the code calculate directory sizes since the &lt;I&gt;Folder&lt;/I&gt; object that I use has as &lt;I&gt;Size &lt;/I&gt;property, but it slows down the script exponentially to calculate that. That being said, if you're willing to take the performance hit, you can modify the highlighted section of the &lt;CODE&gt;WriteEntry()&lt;/CODE&gt; function as follows:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: #000000"&gt;  &lt;SPAN style="COLOR: #008000"&gt;' Test for a symbolic link.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 1024) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;lrwxrwxrwx&lt;/SPAN&gt;"
    tmpSize = 0
  &lt;SPAN style="COLOR: #008000"&gt;' Test for a directory.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;ElseIf&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 16) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;drwxrwxrwx&lt;/SPAN&gt;"
    &lt;SPAN style="BACKGROUND-COLOR: #ffff99"&gt;tmpSize = tmpObject.Size&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #008000"&gt;' Otherwise - it's a file.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;Else&lt;/SPAN&gt;
    tmpAttributes = "&lt;SPAN style="COLOR: #8b0000"&gt;-rwxrwxrwx&lt;/SPAN&gt;"
    tmpSize = tmpObject.Size
  &lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This will insert the folder size into the output, but once again it will make the script much slower and take up considerably more CPU time to compute.&lt;/P&gt;
&lt;H4&gt;Uppercase Folder Names&amp;nbsp; and Lowercase File Names&lt;/H4&gt;
&lt;P&gt;Since Windows is a case-insensitive operating system, you can easily choose to display all of your folder names in all uppercase characters and your file names in all lowercase characters without causing any client confusion. This can be accomplished by adding the first highlighted section and modifying the second highlighted section of the &lt;CODE&gt;WriteEntry()&lt;/CODE&gt; function as follows:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffff99; COLOR: #000000"&gt;  &lt;SPAN style="COLOR: #0000ff"&gt;Dim&lt;/SPAN&gt; tmpName
  
  &lt;SPAN style="COLOR: #008000"&gt;' Test for a directory.&lt;/SPAN&gt;
  &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt; (tmpObject.Attributes &lt;SPAN style="COLOR: #0000ff"&gt;And&lt;/SPAN&gt; 16) &lt;SPAN style="COLOR: #0000ff"&gt;Then&lt;/SPAN&gt;
    tmpName = UCase(tmpObject.Name)
  &lt;SPAN style="COLOR: #0000ff"&gt;Else&lt;/SPAN&gt;
    tmpName = LCase(tmpObject.Name)
  &lt;SPAN style="COLOR: #0000ff"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;If&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; COLOR: #000000"&gt;  &lt;SPAN style="COLOR: #008000"&gt;' Write the list entry to the output file.&lt;/SPAN&gt;
  objFile.WriteLine tmpAttributes &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt;   1 owner    group &lt;/SPAN&gt;" &amp;amp; _
    Right(&lt;SPAN style="COLOR: #0000ff"&gt;String&lt;/SPAN&gt;(15,Chr(32)) &amp;amp; &lt;SPAN style="COLOR: #0000ff"&gt;CStr&lt;/SPAN&gt;(tmpSize),15) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt; &lt;/SPAN&gt;" &amp;amp; FormatDate(tmpObject.DateLastModified) &amp;amp; _
    "&lt;SPAN style="COLOR: #8b0000"&gt; &lt;/SPAN&gt;" &amp;amp; &lt;SPAN style="BACKGROUND-COLOR: #ffff99"&gt;tmpName&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Parting Thoughts&lt;/H3&gt;
&lt;P&gt;There are other customizations that you can easily make, such as creating a string array to sort the files and folders for each folder listing as a single list rather than listing folders first and files second as the currently script does. But that slows down the script way too much, and I prefer to see folders listed before files anyway. (Which is why I always use &lt;KBD&gt;SET DIRCMD=/OGN&lt;/KBD&gt; for my command prompt sessions as well.)&lt;/P&gt;
&lt;P&gt;Another easy customization would be to change the &lt;CODE&gt;FormatDate()&lt;/CODE&gt; function to change the date format for the output file, which is why I used a function to do my date formatting. For example, you could easily use the &lt;CODE&gt;FormatDate()&lt;/CODE&gt; function as a wrapper for VBScript's built-in &lt;CODE&gt;FormatDateTime()&lt;/CODE&gt; function, and then use any of the &lt;CODE&gt;vbGeneralDate&lt;/CODE&gt;, &lt;CODE&gt;vbLongDate&lt;/CODE&gt;, &lt;CODE&gt;vbShortDate&lt;/CODE&gt;, etc. options to specify the format. You can also use your own customized logic to return the date string, so you don't need to feel limited by my examples.&lt;/P&gt;
&lt;P&gt;Another useful customization would be to compute the actual size for the resulting "ls-lr.txt" file and modify the output file to contain the correct file size. Currently the script in this blog adds an entry to the listing for the "ls-lr.txt" file, but that contains the temporary size of the output file as the script is running so it will seldom be accurate. (I usually run my script and update the "ls-lr.txt" file manually, but in some versions of this script I have had it ignore the "ls-lr.txt" file and remove it from the output listings.)&lt;/P&gt;
&lt;P&gt;In closing, this script may be doing more than it might actually need to do by way of checking for symbolic links and read-only attributes, which our FTP service doesn’t actually do, but it was very easy to add that code and it runs just as fast either way.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9891823" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FTP/default.aspx">FTP</category></item><item><title>A Little Scripting Saved My Day (;-])</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2009/07/27/a-little-scripting-saved-my-day.aspx</link><pubDate>Mon, 27 Jul 2009 21:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9850238</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/9850238.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=9850238</wfw:commentRss><description>&lt;P&gt;I have mentioned in previous blog posts that I tend to write many of my blog posts and walkthroughs for &lt;A href="http://www.iis.net/" target=_blank mce_href="http://www.iis.net/"&gt;IIS.NET&lt;/A&gt; based on code that I’ve written for myself, and today’s blog post is the story of how one of my samples saved my rear over this past weekend.&lt;/P&gt;
&lt;P&gt;One of the servers that I manage is used to host web sites for several friends of mine. (It’s their hobby to have a web site and it’s my hobby to host it for them.) Anyway, sometime on Sunday someone let me know that one of my sites didn’t seem to be behaving correctly, so I browsed it with Internet Explorer and saw that I was getting an HTTP 503 error. I’ve seen this error when an application pool goes offline for some reason, so I didn’t panic – yet – because I knew that the web site was in a separate application pool. With that in mind, I browsed to a web site that is in a different application pool. Same thing – HTTP 503 error. This was beginning to concern me.&lt;/P&gt;
&lt;P&gt;I logged into the web server and ran iisreset from a command-line – this threw the following error - and now I was really starting to become agitated:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #000000" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" style="COLOR: #ffffff"&gt;
&lt;P style="COLOR: #ffffff"&gt;&lt;TT&gt;CMD&amp;gt;iisreset&lt;BR&gt;&lt;BR&gt;Attempting stop...&lt;BR&gt;Internet services successfully stopped&lt;BR&gt;Attempting start...&lt;BR&gt;Restart attempt failed.&lt;BR&gt;The IIS Admin Service or the World Wide Web Publishing Service, or a service dependent on them failed to start. The service, or dependent services, may had an error during its startup or may be disabled.&lt;BR&gt;&lt;BR&gt;CMD&amp;gt;&lt;/TT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I knew that the cause of the error should be in the Windows Event Viewer, so I opened the System log in Event Viewer and saw the following error:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;TABLE class="" style="BORDER-COLLAPSE: collapse" cellSpacing=1 cellPadding=2 width="100%" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Log Name:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;System&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Source:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Microsoft-Windows-WAS&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Date:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;7/26/2009 10:59:52 AM&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Event ID:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;5172&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Task Category:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;None&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Level:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Error&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Keywords:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;Classic&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;User:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;N/A&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Computer:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;MYSERVER&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left&gt;Description:&lt;/TH&gt;
&lt;TD class="" vAlign=top align=left&gt;The Windows Process Activation Service encountered an error trying to read configuration data from file '\\?\C:\Windows\system32\inetsrv\config\applicationHost.config', line number '308'. The error message is: 'Configuration file is not well-formed XML'. The data field contains the error number.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="" vAlign=top noWrap align=left colSpan=2&gt;Event Xml:&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left colSpan=2&gt;
&lt;P style="COLOR: black; BACKGROUND-COLOR: #ffffff"&gt;&lt;TT&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Event&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="http://schemas.microsoft.com/win/2004/08/events/event"&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;System&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Provider&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Microsoft-Windows-WAS"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt; Guid&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="{4E616D65-6F6E-6D65-6973-526F62657274}"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt; EventSourceName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="WAS"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventID&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Qualifiers&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="49152"&amp;gt;&lt;/SPAN&gt;5172&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Version&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Version&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Level&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;2&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Level&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Task&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Opcode&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Opcode&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Keywords&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0x80000000000000&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Keywords&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;TimeCreated&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;SystemTime&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="2009-07-26T17:59:52.000Z"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventRecordID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;32807&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventRecordID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Correlation&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Execution&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;ProcessID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="0"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;ThreadID&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="0"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Channel&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;System&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Channel&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Computer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;MYSERVER&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Computer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;System&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventData&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="File"&amp;gt;&lt;/SPAN&gt;\\?\C:\Windows\system32\inetsrv\config\applicationHost.config&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="LineNumber"&amp;gt;&lt;/SPAN&gt;308&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Error"&amp;gt;&lt;/SPAN&gt;Configuration file is not well-formed XML&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Data&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Binary&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;0D000780&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Binary&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;EventData&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Event&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/TT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now that I was armed with the file name and line number of the failure in my configuration settings, I was able to go straight to the source of the problem. (I love IIS 7's descriptive error messages - don't you?) Once I opened the file and jumped to the correct location, I saw several lines of unintelligible garbage. For reasons that are still unknown to me – my applicationHost.config file had become corrupted and IIS was dead in the water until I fixed the problem. I looked through the file and removed most of the garbage and saved the edited file&amp;nbsp;to IIS – this got the web sites working, but only partially. Some necessary settings had obviously been removed while I was clearing all of out the unintelligible garbage, and it might take me a long time to discover what those settings were.&lt;/P&gt;
&lt;P&gt;The next thing that I did was to take a look in my two readily-accessible backup drives; I have two external hard drives that keep a backup of the web server - one hard drive is directly plugged into the web server via a USB cable, and the other hard drive is plugged into a physically separate server that rotates drives with off-site storage on a monthly basis. The problem is, my weekly backups had just run, so the copy in each backup location had been overwritten with the corrupted version. (I’m going to have to rethink my backup strategy after this – but that’s another story.) The backup copy in my off-site storage location should be intact, but that copy would be a few weeks old so I would be missing some settings, and I would have to drive an hour or so round-trip in order to pick up the drive. This wasn’t an ideal solution – but it was definitely a feasible strategy.&lt;/P&gt;
&lt;P&gt;It was at this point that I remembered that I had written following blog post some time ago:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Automating IIS 7 Backups&lt;/STRONG&gt; &lt;BR&gt;&lt;A title=http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx"&gt;http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I wrote the script in that blog post for the server that I was currently managing, and because of this preventative measure I had dozens of backups going back several weeks to choose from. So I was able to quickly find a copy with no corruption and I restored that copy to my IIS config directory. At this point all of my web sites came online with all of their functionality. Having fixed the major issues, I used WinDiff to verify any settings that might have been changed between the restored copy and the corrupted copy.&lt;/P&gt;
&lt;P&gt;So in conclusion, this story had a happy ending, and it left me with a few lessons learned:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You can never have too many backups &lt;/LI&gt;
&lt;LI&gt;I need to rethink how I roll out my backup strategy with regard to using external hard drives &lt;/LI&gt;
&lt;LI&gt;Writing cool scripts to automate your backups can save your rear end &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;That sums it up for today’s post. ;-]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9850238" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Automating IIS 7 Backups</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2008/03/08/automating-iis-7-backups.aspx</link><pubDate>Sun, 09 Mar 2008 00:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8115147</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/8115147.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=8115147</wfw:commentRss><description>&lt;P&gt;Many years ago I wrote the following KB article:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://support.microsoft.com/kb/302888" target=_blank mce_href="http://support.microsoft.com/kb/302888"&gt;How To Schedule Metabase Backups Using WSH&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Truth be told, I wrote the script in that article to help me manage several servers that I controlled. Once I finished the script, I found myself routinely giving it out to customers in order for them to automate their backups, so I decided to turn it into a KB. When IIS 6 came out, Microsoft shipped the &lt;A class="" href="http://support.microsoft.com/kb/324277" target=_blank mce_href="http://support.microsoft.com/kb/324277"&gt;IIsBack.vbs&lt;/A&gt; script to help customers automate backups.&lt;/P&gt;
&lt;P&gt;One of the great things in IIS 7 is the deprecation of the metabase, which has been replaced by applicationHost.config, but the need for backing up your configuration settings is still there. With this in mind, I wrote a small batch file that I schedule to create backups of my configuration settings using the APPCMD utility. Since I've been giving this to customers at &lt;A class="" href="http://go.microsoft.com/?LinkID=1670043" target=_blank mce_href="http://go.microsoft.com/?LinkID=1670043"&gt;Microsoft TechEd&lt;/A&gt;, I thought it might make a nice blog post for everyone that can't make it to TechEd.&lt;/P&gt;
&lt;P&gt;To use the script, copy the code below into Windows Notepad, then save it to your computer as "BackupIIS.cmd". (I usually save it in "%WinDir%\System32\Inetsrv", but you could save it&amp;nbsp;to your executable search path as well.)&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT style="COLOR: #000099"&gt;@echo off&lt;BR&gt;cls

pushd "%WinDir%\System32\inetsrv"

echo.| date | find /i "current"&amp;gt;datetime1.tmp
echo.| time | find /i "current"&amp;gt;datetime2.tmp

for /f "tokens=1,2,3,4,5,6" %%i in (datetime1.tmp) do (
&amp;nbsp; echo %%n&amp;gt;datetime1.tmp
)
for /f "tokens=1,2,3,4,5,6" %%i in (datetime2.tmp) do (
&amp;nbsp; echo %%m&amp;gt;datetime2.tmp
)
for /f "delims=/ tokens=1,2,3" %%i in (datetime1.tmp) do (
&amp;nbsp; set TMPDATETIME=%%k%%i%%j
)
for /f "delims=:. tokens=1,2,3,4" %%i in (datetime2.tmp) do (
&amp;nbsp; set TMPDATETIME=D%TMPDATETIME%T%%i%%j%%k%%l
)

appcmd add backups %TMPDATETIME%

del datetime1.tmp
del datetime2.tmp

set TMPDATETIME=

popd
echo.&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You can use Task Scheduler in Windows Server 2008's Server Manager to schedule this script&amp;nbsp;to run at whatever interval you choose, although I usually schedule it to run once a week.&lt;/P&gt;
&lt;P&gt;Backups will be created in the following path:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;%WinDir%\System32\Inetsrv\Backups\&lt;STRONG&gt;D&lt;/STRONG&gt;yyyymmdd&lt;STRONG&gt;T&lt;/STRONG&gt;hhmmssii&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Where &lt;STRONG&gt;yyyymmdd&lt;/STRONG&gt; is the year, month, day, and &lt;STRONG&gt;hhmmssii&lt;/STRONG&gt; is the hour, minute, second, millisecond for the time of the backup.&lt;/P&gt;
&lt;P&gt;I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8115147" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Enabling WebDAV on IIS 6</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2008/03/04/enabling-webdav-on-iis-6.aspx</link><pubDate>Wed, 05 Mar 2008 01:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8037049</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/8037049.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=8037049</wfw:commentRss><description>&lt;P&gt;I had a great question from someone the other day about enabling WebDAV on IIS 6, so I wrote a simple Windows Script Host (WSH) utility that does the trick. Because I'm a firm believer that writing code for one person will ultimately benefit someone else, I'm making that script the subject of today's blog post. ;-)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: The following script makes use of several IIS 6 metabase properties, and you can see the following topics for more information:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/ms525087(VS.85).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms525087(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms525087(VS.85).aspx&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/ms525016(VS.85).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms525016(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms525016(VS.85).aspx&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/ms524576(VS.85).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms524576(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms524576(VS.85).aspx&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;To use this script, use the following steps:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Copy the WSH code listed below and paste it into a text editor, such as Windows Notepad: &lt;PRE&gt;&lt;CODE&gt;Option Explicit

' --------------------------------------------------
' Part 1: Enable the WebDAV Web Service Extension.
' --------------------------------------------------

' Retrieve an object for the W3SVC root.
Dim objIIsWebService
Set objIIsWebService = GetObject("IIS://localhost/W3SVC")
' Enable the WebDAV Web Service Extension.
objIIsWebService.EnableWebServiceExtension "WEBDAV"
' Save the changes to the metabase.
objIIsWebService.SetInfo

' --------------------------------------------------
' Part 2: Enable the WebDAV-related attributes for the Default Web Site.
' --------------------------------------------------

' Retrieve an object for the web site root.
Dim objIIsWebSite
Set objIIsWebSite = GetObject("IIS://localhost/W3SVC/1/ROOT")
' Enable the WebDAV-related access flags.
objIIsWebSite.AccessRead = True
objIIsWebSite.AccessSource = True
objIIsWebSite.AccessWrite = True
' Enable the directory browsing - required for file listings.
objIIsWebSite.EnableDirBrowsing = True
' Save the changes to the metabase.
objIIsWebSite.SetInfo
&lt;/CODE&gt;&lt;/PRE&gt;&lt;/LI&gt;
&lt;LI&gt;Update the metabase path&amp;nbsp;for your web site to &lt;STRONG&gt;IIS://localhost/W3SVC/&lt;EM&gt;nnn&lt;/EM&gt;/ROOT&lt;/STRONG&gt;, where &lt;EM&gt;nnn&lt;/EM&gt;&amp;nbsp;is the identifier for the web site where you want to enable WebDAV. &lt;STRONG&gt;Note&lt;/STRONG&gt;: The web site&amp;nbsp;identifier can be found in the IIS Manager using the following steps: 
&lt;UL&gt;
&lt;LI&gt;Open the IIS manager.&lt;/LI&gt;
&lt;LI&gt;Expand the local computer node.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;Highlight the Web Sites node.&lt;/LI&gt;
&lt;LI&gt;Notice the site ID in the "Identifier" column.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Save the file as &lt;B&gt;EnableWebDav.vbs&lt;/B&gt; to your desktop and close your text editor.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: This script is not designed the new WebDAV module for IIS 7. To manage the WebDAV module in IIS 7, see the following topics:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=105146"&gt;Installing and Configuring WebDAV on IIS 7.0&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://go.microsoft.com/fwlink/?LinkId=108319"&gt;How to manage WebDAV using APPCMD&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8037049" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/WebDAV/default.aspx">WebDAV</category></item><item><title>Creating XML Reports for FSRM Quota Usage</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2007/10/25/creating-xml-reports-from-fsrm-quota-usage.aspx</link><pubDate>Fri, 26 Oct 2007 00:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5679788</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/5679788.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=5679788</wfw:commentRss><description>&lt;P&gt;I had a great question in follow up to the "&lt;A href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032352158" target=_blank mce_href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032352158"&gt;Secure, Simplified Web Publishing using Microsoft Internet Information Services 7.0&lt;/A&gt;" webcast that I delivered the other day, "How you can you programmatically access the quota usage information from the File Server Resource Manager (FSRM)?"&lt;/P&gt;
&lt;P&gt;First of all, there is a native API for writing code to access FSRM data detailed at the following URL:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/bb625489.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb625489.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That's a bit of overkill if you're just looking to script something.&lt;/P&gt;
&lt;P&gt;There is a WMI interface as well, but it’s only for FSRM events.&lt;/P&gt;
&lt;P&gt;So that leaves you with a pair of command-line tools that you can&amp;nbsp;script in order&amp;nbsp;to list your quota usage information:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;storrept.exe&lt;/STRONG&gt; - Used to manage storage reports&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;dirquota.exe&lt;/STRONG&gt; - Used to manage quota usage&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Right out of the box the first command-line tool, &lt;STRONG&gt;storrept.exe&lt;/STRONG&gt;, can generate a detailed&amp;nbsp;XML&amp;nbsp;report using a user-definable scope. To see this in action, take the following example syntax and modify the scope parameter to your desired paths:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#333333&gt;storrept.exe reports generate /Report:QuotaUsage /Format:XML /Scope:"C:\"&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;You can also specify mutiple paths in your scope using a pipe-delimited format like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#333333&gt;/Scope:"C:\Inetpub|D:\Inetpub"&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;When the command has finished, it will tell you the path to your report like the following example:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#333333&gt;Storage reports generated successfully in "C:\StorageReports\Interactive".&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;The XML-based information in the report can then be consumed with whatever method you usually use to parse XML. It should be noted that &lt;STRONG&gt;storrept.exe&lt;/STRONG&gt; also supports the following formats: CSV, DHTML, HTML, and TXT.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;This XML might be okay for most applications, but for some reason I wanted to customize the information that I received, so I experimented with the second command-line tool, &lt;STRONG&gt;dirquota.exe&lt;/STRONG&gt;, to get the result that I was looking for.&lt;/P&gt;
&lt;P mce_keep="true"&gt;First of all, using &lt;STRONG&gt;dirquota.exe quota list&lt;/STRONG&gt; returns information in the following format:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#333333&gt;Quotas on machine SERVER:

Quota Path:             C:\inetpub\ftproot
Source Template:        100 MB Limit (Matches template)
Quota Status:           Enabled
Limit:                  100.00 MB (Hard)
Used:                   1.00 KB (0%)
Available:              100.00 MB
Peak Usage:             1.00 KB (10/25/2007 2:15 PM)
Thresholds:
   Warning ( 85%):      E-mail
   Warning ( 95%):      E-mail, Event Log
   Limit (100%):        E-mail, Event Log&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;This information is formatted nicely and is therefore easily parsed, so I wrote the following batch file called "dirquota.cmd" to start things off:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#000099&gt;@echo off
echo Processing the report...
dirquota.exe quota list &amp;gt; dirquota.txt
cscript.exe //nologo dirquota.vbs&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;Next, I wrote the following vbscript application called "dirquota.vbs" to parse the output into some easily-usable XML code:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#000099&gt;Option Explicit

Dim objFSO, objFile1, objFile2
Dim strLine, strArray(2)
Dim blnQuota,blnThreshold

' create objects
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile1 = objFSO.OpenTextFile("dirquota.txt")
Set objFile2 = objFSO.CreateTextFile("dirquota.xml")

' start the XML output file
objFile2.WriteLine "&amp;lt;?xml version=""1.0""?&amp;gt;"
objFile2.WriteLine "&amp;lt;Quotas&amp;gt;"

' set the runtime statuses to off
blnQuota = False
blnThreshold = False

' loop through the text file
Do While Not objFile1.AtEndOfStream

&amp;nbsp; ' get a line from the file
&amp;nbsp; strLine = objFile1.ReadLine

&amp;nbsp; ' only process lines with a colon character
&amp;nbsp; If InStr(strLine,":") Then
&amp;nbsp;&amp;nbsp;&amp;nbsp; ' split the string manually at the colon character
&amp;nbsp;&amp;nbsp;&amp;nbsp; strArray(1) = Trim(Left(strLine,InStr(strLine,":")-1))
&amp;nbsp;&amp;nbsp;&amp;nbsp; strArray(2) = Trim(Mid(strLine,InStr(strLine,":")+1))

&amp;nbsp;&amp;nbsp;&amp;nbsp; ' filter on strings with parentheses
&amp;nbsp;&amp;nbsp;&amp;nbsp; strLine = strArray(1)
&amp;nbsp;&amp;nbsp;&amp;nbsp; If InStr(strLine,"(") Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strLine = Trim(Left(strLine,InStr(strLine,"(")-1)) &amp;amp; "*"
&amp;nbsp;&amp;nbsp;&amp;nbsp; End If

&amp;nbsp;&amp;nbsp;&amp;nbsp; ' process the inidivdual entries
&amp;nbsp;&amp;nbsp;&amp;nbsp; Select Case UCase(strLine)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' a quota path signifies a new record
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case UCase("Quota Path")

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' close any open threshold collections
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If blnThreshold = True Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine "&amp;lt;/Thresholds&amp;gt;"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' close an open quota element
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If blnQuota= True Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine "&amp;lt;/Quota&amp;gt;"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' signify a new quota element
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine "&amp;lt;Quota&amp;gt;"

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' output the relelvant information
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine FormatElement(strArray(1),strArray(2))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' set the runtime statuses
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnQuota= True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnThreshold = False

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' these bits of informaiton are parts of a quota
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case UCase("Source Template"), UCase("Quota Status"), _
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCase("Limit"), UCase("Used"), _
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCase("Available"), UCase("Peak Usage")

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' close any open threshold collections
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If blnThreshold = True Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine "&amp;lt;/Thresholds&amp;gt;"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' set the runtime status
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnThreshold = False

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' output the relelvant information
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine FormatElement(strArray(1),strArray(2))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' these bits of informaiton are thresholds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case UCase("Warning*"), UCase("Limit*")

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' open a threshold collection if not already open
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If blnThreshold = False Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine "&amp;lt;Thresholds&amp;gt;"
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' output the relelvant information
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile2.WriteLine FormatElement( _
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Left(strLine,Len(strLine)-1), _
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Replace(Mid(strArray(1), _
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Len(strLine))," ","") &amp;amp; " " &amp;amp; strArray(2))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' set the runtime status
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnThreshold = True

&amp;nbsp;&amp;nbsp;&amp;nbsp; End Select
&amp;nbsp; End If
Loop

' close any open threshold collections
If blnThreshold = True Then
&amp;nbsp; objFile2.WriteLine "&amp;lt;/Thresholds&amp;gt;"
End If

' close an open quota element
If blnQuota= True Then
&amp;nbsp; objFile2.WriteLine "&amp;lt;/Quota&amp;gt;"
End If

' end the XML output file
objFile2.WriteLine "&amp;lt;/Quotas&amp;gt;"

objFile1.Close
objFile2.Close
Set objFSO = Nothing

' format data into an XML element
Function FormatElement(tmpName,tmpValue)
&amp;nbsp; FormatElement = "&amp;lt;" &amp;amp; Replace(tmpName," ","") &amp;amp; _
&amp;nbsp; "&amp;gt;" &amp;amp; tmpValue &amp;amp; "&amp;lt;/" &amp;amp; Replace(tmpName,Chr(32),"") &amp;amp; "&amp;gt;"
End Function&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;When the batch file and vbscript are run, they will create a file named "dirquota.xml" which will resemble the following example XML:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;TT&gt;&lt;FONT color=#000099&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;Quotas&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;Quota&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;QuotaPath&amp;gt;C:\inetpub\ftproot&amp;lt;/QuotaPath&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;SourceTemplate&amp;gt;100 MB Limit (Matches template)&amp;lt;/SourceTemplate&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;QuotaStatus&amp;gt;Enabled&amp;lt;/QuotaStatus&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Limit&amp;gt;100.00 MB (Hard)&amp;lt;/Limit&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Used&amp;gt;1.00 KB (0%)&amp;lt;/Used&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Available&amp;gt;100.00 MB&amp;lt;/Available&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;PeakUsage&amp;gt;1.00 KB (10/25/2007 2:15 PM)&amp;lt;/PeakUsage&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Thresholds&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Warning&amp;gt;(85%) E-mail&amp;lt;/Warning&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Warning&amp;gt;(95%) E-mail, Event Log&amp;lt;/Warning&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Limit&amp;gt;(100%) E-mail, Event Log&amp;lt;/Limit&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Thresholds&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/Quota&amp;gt;
&amp;lt;/Quotas&amp;gt;&lt;/FONT&gt;&lt;/TT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;I found the above XML much easier to use than the XML that came from the &lt;STRONG&gt;storrept.exe&lt;/STRONG&gt;&amp;nbsp;report, but I'm probably comparing apples to oranges. In any event, I hope this helps someone with questions about FSRM reporting.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Have fun!&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5679788" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Scripting MIDI Events in Sibelius</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2007/05/11/scripting-midi-events-in-sibelius.aspx</link><pubDate>Fri, 11 May 2007 11:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2543204</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/2543204.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=2543204</wfw:commentRss><description>&lt;P&gt;OK - I have to admit, when you realize that you are making software choices based on scripting language support you start to get the feeling that there are times when you just have to accept the fact that you are a geek.&lt;/P&gt;
&lt;P&gt;Here's a case in point: I write music as a hobby, and when shopping for a program to write sheet music with, I chose &lt;A class="" href="http://www.sibelius.com/" target=_blank mce_href="http://www.sibelius.com/"&gt;Sibelius&lt;/A&gt; because I discovered that they have a really cool scripting language called "&lt;A class="" href="http://mook.sibelius.com/download/software/win/ManuScriptLanguage.pdf" target=_blank mce_href="http://mook.sibelius.com/download/software/win/ManuScriptLanguage.pdf"&gt;ManuScript&lt;/A&gt;". OK - so the name is kind of silly, but it's pretty cool to write code with.&lt;/P&gt;
&lt;P&gt;The way it works is that you create what Silbelius calls a "plug-in", and you assign it to a category that will be used as the menu under which your plug-in will be displayed. Once you've done all that, you can start writing code.&lt;/P&gt;
&lt;P&gt;For example, I needed to add sustain pedal MIDI events to an entire piano score, and doing so manually would have been a&amp;nbsp;tedious exercise. So I made my life easier and created a quick plug-in that adds the MIDI events to apply the sustain pedal at full level to the beginning of every measure, and then adds the MIDI events to&amp;nbsp;lift the sustain pedal at the end of every measure:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;// Verify that a score is open.&lt;BR&gt;if (Sibelius.ScoreCount=0)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; Sibelius.MessageBox("Please open a score.");&lt;BR&gt;&amp;nbsp;&amp;nbsp; return false;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;// Retrieve a score object for the active score.&lt;BR&gt;score = Sibelius.ActiveScore;&lt;BR&gt;// Retrieve an&amp;nbsp;object for the current selection.&lt;BR&gt;selection = score.Selection;&lt;BR&gt;&lt;BR&gt;if (selection.IsPassage)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; // Loop through the highlighted measures.&lt;BR&gt;&amp;nbsp;&amp;nbsp; for each Bar b in selection&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Add MIDI sustain pedal events.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.AddText(1,"~C64,127",TechniqueTextStyle);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b.AddText(b.Length,"~C64,0",TechniqueTextStyle);&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp; // Return a status message.&lt;BR&gt;&amp;nbsp;&amp;nbsp; Sibelius.MessageBox("Finished.");&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I should point out, however, that this is meant to be a brief example of what you can do. Running this same plug-in on the same selection will re-add the sustain pedal events to your score; I didn't add any advanced logic to check for the existance of any prior sustain pedal events. If anyone wants to take on that challenge, have fun and don't forget to share your results!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2543204" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Converting W3C log files to NCSA format</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2006/11/06/converting-w3c-log-files-to-ncsa-format.aspx</link><pubDate>Tue, 07 Nov 2006 05:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1008351</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/1008351.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=1008351</wfw:commentRss><description>&lt;P&gt;Around a year ago I wrote a blog entry titled "&lt;A class="" title="Converting NCSA log files to W3C format" href="http://blogs.msdn.com/robert_mcmurray/archive/2005/11/30/498658.aspx" target=_blank mce_href="http://blogs.msdn.com/robert_mcmurray/archive/2005/11/30/498658.aspx"&gt;Converting NCSA log files to W3C format&lt;/A&gt;", which showed how to use the MSWC.IISLog object to convert log files in the NCSA format back to W3C format. I wrote that blog entry to make up for the fact that the CONVLOG.EXE utility only converts log files to NCSA format, which some older log analysis software packages require. So what happens if you have a bunch of log files in W3C format and you don't have a copy of CONVLOG.EXE on your computer?&lt;/P&gt;
&lt;P&gt;This blog entry is something of a reverse direction on my previous post, and&amp;nbsp;shows you how to use the MSUtil.LogQuery object to convert W3C log files to NCSA format. The MSUtil.LogQuery object&amp;nbsp;is shipped with LogParser,&amp;nbsp;which you can download from one of the following URLs:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Version 2.2 and 2.0: &lt;A href="http://www.microsoft.com/download" target=_blank&gt;http://www.microsoft.com/download&lt;/A&gt;, search for "Log Parser"&lt;/LI&gt;
&lt;LI&gt;Version 2.1: &lt;A href="http://www.microsoft.com/download" target=_blank&gt;http://www.microsoft.com/download&lt;/A&gt;, search for "IIS 6.0 Resource Kit Tools"&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Once you've downloaded and installed the LogParser package, you will need to manually register the LogParser.dll file in order to use the MSUtil.LogQuery object. Having done so, you can use the Windows Script Host (WSH) code in this blog article to convert a folder filled with W3C log files to NCSA format.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To use this code, just copy the code into notepad, and save it with a ".vbs" file extension on your system. To run it, copy the script to a folder that contains your W3C log files, (named "ex*.log"), then double-click it.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Option Explicit&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Dim objFSO&lt;BR&gt;Dim objFolder&lt;BR&gt;Dim objInputFile&lt;BR&gt;Dim objOutputFile&lt;BR&gt;Dim objLogQuery&lt;BR&gt;Dim objLogRecordSet&lt;BR&gt;Dim objLogRecord&lt;BR&gt;Dim strInputPath&lt;BR&gt;Dim strOutputPath&lt;BR&gt;Dim strLogRecord&lt;BR&gt;Dim strLogTemp&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objFolder = objFSO.GetFolder(".")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;For Each objInputFile In objFolder.Files&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;strInputPath = LCase(objInputFile.Name)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;If Left(strInputPath,2) = "ex" And Right(strInputPath,4) = ".log" Then&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp; strOutputPath = objFolder.Path &amp;amp; "\" &amp;amp; "nc" &amp;amp; Mid(strInputPath,3)&lt;BR&gt;&amp;nbsp; strInputPath = objFolder.Path &amp;amp; "\" &amp;amp; strInputPath&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp; Set objLogQuery = CreateObject("MSUtil.LogQuery")&lt;BR&gt;&amp;nbsp; Set objLogRecordSet = objLogQuery.Execute("SELECT * FROM " &amp;amp; strInputPath)&lt;BR&gt;&amp;nbsp; Set objOutputFile = objFSO.CreateTextFile(strOutputPath)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp; Do While Not objLogRecordSet.atEnd&lt;BR&gt;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; Set objLogRecord = objLogRecordSet.getRecord&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp; strLogRecord = FormatField(objLogRecord.getValue("c-ip"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField("")&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objLogRecord.getValue("cs-username"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogTemp = BuildDateTime(objLogRecord.getValue("date"),objLogRecord.getValue("time"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(strLogTemp)&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " """ &amp;amp; FormatField(objLogRecord.getValue("cs-method"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objLogRecord.getValue("cs-uri-stem"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogTemp = FormatField(objLogRecord.getValue("cs-version"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; If strLogTemp = "-" Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " HTTP/1.0"""&lt;BR&gt;&amp;nbsp;&amp;nbsp; Else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; strLogTemp &amp;amp; """"&lt;BR&gt;&amp;nbsp;&amp;nbsp; End If&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objLogRecord.getValue("sc-status"))&lt;BR&gt;&amp;nbsp;&amp;nbsp; strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objLogRecord.getValue("sc-bytes"))&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; objOutputFile.WriteLine strLogRecord&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp; objLogRecordSet.moveNext&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp; Loop&lt;BR&gt;&amp;nbsp; &lt;BR&gt;&amp;nbsp; Set objLogQuery = Nothing&lt;BR&gt;&amp;nbsp; objOutputFile.Close&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;End If&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Function FormatField(tmpField)&lt;BR&gt;&amp;nbsp;On Error Resume Next&lt;BR&gt;&amp;nbsp;FormatField = "-"&lt;BR&gt;&amp;nbsp;If Len(tmpField) &amp;gt; 0 Then FormatField = Trim(tmpField)&lt;BR&gt;End Function&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Function BuildDateTime(tmpDate,tmpTime)&lt;BR&gt;&amp;nbsp;On Error Resume Next&lt;BR&gt;&amp;nbsp;BuildDateTime = "[" &amp;amp; _&lt;BR&gt;&amp;nbsp; Right("0" &amp;amp; Day(tmpDate),2) &amp;amp; "/" &amp;amp; _&lt;BR&gt;&amp;nbsp; Left(MonthName(Month(tmpDate)),3) &amp;amp; "/" &amp;amp; _&lt;BR&gt;&amp;nbsp; Year(tmpDate) &amp;amp; ":" &amp;amp; _&lt;BR&gt;&amp;nbsp; Right("0" &amp;amp; Hour(tmpTime),2) &amp;amp; ":" &amp;amp; _&lt;BR&gt;&amp;nbsp; Right("0" &amp;amp; Minute(tmpTime),2) &amp;amp; ":" &amp;amp; _&lt;BR&gt;&amp;nbsp; Right("0" &amp;amp; Second(tmpTime),2) &amp;amp; _&lt;BR&gt;&amp;nbsp; " +0000]"&lt;BR&gt;End Function&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1008351" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Programmatically Enumerating Installations of the FrontPage Server Extensions</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2006/07/11/programmatically-enumerating-installations-of-the-frontpage-server-extensions.aspx</link><pubDate>Wed, 12 Jul 2006 04:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:662891</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/662891.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=662891</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Arial&gt;I had a great question from a customer the other day: "&lt;EM&gt;How do&amp;nbsp;you programmatically enumerate how many web sites on a server have the FrontPage Server Extensions installed?&lt;/EM&gt;" &lt;/FONT&gt;&lt;FONT face=Arial&gt;Of course, that's one of those questions that sounds so simple at first, and then you start to think about how to actually go about it and it gets a little more complicated.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;The first thought that came to mind was to just look for all the "&lt;FONT face="Courier New"&gt;W3SVCnnnn&lt;/FONT&gt;" subfolders&amp;nbsp;that are located in&amp;nbsp;the &lt;FONT face="Courier New"&gt;"%ALLUSERSPROFILE%\Application Data\Microsoft\Web Server Extensions\50&lt;/FONT&gt;" folder. (These folders contain the "&lt;FONT face="Courier New"&gt;ROLES.INI&lt;/FONT&gt;" files for each installation.) The trouble with this solution is that some folders and files do not get cleaned up when the server extensions are uninstalled, so you'd get erroneous results.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;The next thought that came to mind was to check the registry, because each installation of the server extensions will create a string value and subkey named "&lt;FONT face="Courier New"&gt;Port /LM/W3SVC/nnnn:&lt;/FONT&gt;"&amp;nbsp;under the "&lt;FONT face="Courier New"&gt;[HKLM\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\Ports]&lt;/FONT&gt;" key. Enumerating these keys will give you the list of web sites that have the server extensions or SharePoint installed. &lt;/FONT&gt;&lt;FONT face=Arial&gt;The string values that are located&amp;nbsp;under&amp;nbsp;the subkey contain some additional useful information, so I thought that as long as I was enumerating the keys, I might as well enumerate those values.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;The resulting script is listed below, and when run it will create a log file that lists all of the web sites that have the server extensions or SharePoint installed on&amp;nbsp;the server that is specified by the "&lt;FONT face="Courier New"&gt;strComputer&lt;/FONT&gt;"&amp;nbsp;constant.&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Option Explicit&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Const strComputer = "localhost"&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Dim objFSO, objFile&lt;BR&gt;Dim objRegistry&lt;BR&gt;Dim strRootKeyPath, strSubKeyPath, strValue&lt;BR&gt;Dim arrRootValueTypes, arrRootValueNames&lt;BR&gt;Dim arrSubValueTypes, arrSubValueNames&lt;BR&gt;Dim intLoopA, intLoopB&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Const HKEY_LOCAL_MACHINE = &amp;amp;H80000002&lt;BR&gt;Const REG_SZ = 1&lt;BR&gt;&lt;BR&gt;strRootKeyPath = "Software\Microsoft\" &amp;amp; _&lt;BR&gt;&amp;nbsp; "Shared Tools\Web Server Extensions\Ports"&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")&lt;BR&gt;Set objFile = objFSO.CreateTextFile("ServerExtensions.Log")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;objFile.WriteLine String(40,"-")&lt;BR&gt;objFile.WriteLine "Report for server: " &amp;amp; UCase(strComputer)&lt;BR&gt;objFile.WriteLine String(40,"-")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objRegistry = GetObject(_&lt;BR&gt;&amp;nbsp; "winmgmts:{impersonationLevel=impersonate}!\\" &amp;amp; _&lt;BR&gt;&amp;nbsp; strComputer &amp;amp; "\root\default:StdRegProv")&lt;BR&gt;objRegistry.EnumValues HKEY_LOCAL_MACHINE, strRootKeyPath, _&lt;BR&gt;&amp;nbsp; arrRootValueNames, arrRootValueTypes&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;For intLoopA = 0 To UBound(arrRootValueTypes)&lt;BR&gt;&amp;nbsp; If arrRootValueTypes(intLoopA) = REG_SZ Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile.WriteLine arrRootValueNames(intLoopA)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strSubKeyPath = strRootKeyPath &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "\" &amp;amp; arrRootValueNames(intLoopA)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; objRegistry.EnumValues HKEY_LOCAL_MACHINE, _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strSubKeyPath, arrSubValueNames, arrSubValueTypes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; For intLoopB = 0 To UBound(arrSubValueTypes)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If arrSubValueTypes(intLoopB) = REG_SZ Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objRegistry.GetStringValue HKEY_LOCAL_MACHINE, _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strSubKeyPath, arrSubValueNames(intLoopB), strValue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile.WriteLine vbTab &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arrSubValueNames(intLoopB) &amp;amp; "=" &amp;amp; strValue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; objFile.WriteLine String(40,"-")&lt;BR&gt;&amp;nbsp; End If&lt;BR&gt;Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;objFile.Close&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;The script should be fairly easy to understand, and you can customize it to suit your needs. For example, you could change the "&lt;FONT face="Courier New"&gt;strComputer&lt;/FONT&gt;"&amp;nbsp;constant to a string&amp;nbsp;array and loop through an array of servers.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: More information about the WMI objects used in the script can be found on the following pages:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/stdregprov.asp" target=_blank mce_href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/stdregprov.asp"&gt;&lt;FONT face=Arial&gt;The StdRegProv Class&lt;/FONT&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/enumvalues_method_in_class_stdregprov.asp" target=_blank mce_href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/enumvalues_method_in_class_stdregprov.asp"&gt;&lt;FONT face=Arial&gt;EnumValues Method of the StdRegProv Class&lt;/FONT&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/getstringvalue_method_in_class_stdregprov.asp" target=_blank mce_href="http://msdn.microsoft.com/library/en-us/wmisdk/wmi/getstringvalue_method_in_class_stdregprov.asp"&gt;&lt;FONT face=Arial&gt;GetStringValue Method of the StdRegProv Class&lt;/FONT&gt;&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Hope this helps!&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=662891" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/FrontPage+Topics/default.aspx">FrontPage Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Reverting log files back to the default W3C fields</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2006/03/27/reverting-log-files-back-to-the-default-w3c-fields.aspx</link><pubDate>Mon, 27 Mar 2006 19:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:562127</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/562127.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=562127</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Verdana&gt;Recently I had to work with a customer that was trying to use a 3rd-party utility that read W3C log files and it was failing to complete processing. I had the customer send me his log files, and upon examination I discovered that t&lt;/FONT&gt;&lt;FONT face=Verdana&gt;he trouble was occuring because&amp;nbsp;the customer &lt;/FONT&gt;&lt;FONT face=Verdana&gt;had been experimenting with adding and removing the different fields from their log files and this was causing the log parsing utility to crash.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;As luck would have it, IIS provides a useful logging utility object that you can read more about at the following URL:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;&lt;A href="http://www.microsoft.com/windows2000/en/server/iis/htm/asp/comp6ant.htm" target=_blank&gt;http://www.microsoft.com/windows2000/en/server/iis/htm/asp/comp6ant.htm&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;I had used this logging utility object for an earlier project, so I was familiar with how it worked. With that knowledge in mind, I wrote the following script that loops through all of the log files in a folder and creates new log files in a subfolder that contain only the default W3C fields. (BTW - I sent this script to the customer and he was able to parse all of his log files successfully. ;-] )&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Option Explicit&lt;BR&gt;Randomize Timer&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Declare variables.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Dim objIISLog&lt;BR&gt;Dim objFSO, objFolder, objFile&lt;BR&gt;Dim objOutputFile, strInputFile&lt;BR&gt;Dim strOutputFile, strOutputPath&lt;BR&gt;Dim strLogRecord&lt;BR&gt;Dim blnExists&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Create file system object.&lt;BR&gt;Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")&lt;BR&gt;' Retrieve an object For the current folder.&lt;BR&gt;Set objFolder = objFSO.GetFolder(".")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Create a subfolder with a random name.&lt;BR&gt;blnExists = True&lt;BR&gt;Do While blnExists = True&lt;BR&gt;&amp;nbsp;strOutputPath = objFolder.Path &amp;amp; "\" &amp;amp; CreateRandomName(20)&lt;BR&gt;&amp;nbsp;blnExists = objFSO.FolderExists(strOutputPath)&lt;BR&gt;Loop&lt;BR&gt;objFSO.CreateFolder strOutputPath&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Loop through the log files in the current folder.&lt;BR&gt;For Each objFile In objFolder.Files&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;' Test for a log file.&lt;BR&gt;&amp;nbsp;If Right(LCase(objFile.Name),4) = ".log" Then&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Format the file names/paths.&lt;BR&gt;&amp;nbsp;&amp;nbsp;strInputFile = objFolder.Path &amp;amp; "\" &amp;amp; objFile.Name&lt;BR&gt;&amp;nbsp;&amp;nbsp;strOutputFile = strOutputPath &amp;amp; "\" &amp;amp; objFile.Name&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Create and open an IIS logging object.&lt;BR&gt;&amp;nbsp;&amp;nbsp;Set objIISLog = CreateObject("MSWC.IISLog")&lt;BR&gt;&amp;nbsp;&amp;nbsp;' Open the input log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;objIISLog.OpenLogFile strInputFile, 1, "", 0, ""&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;' Open the output log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;Set objOutputFile = objFSO.CreateTextFile(strOutputFile)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Read the initial record from the log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;objIISLog.ReadLogRecord&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Write the headers to the output log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Software: Microsoft Internet Information Services 5.0"&lt;BR&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Version: 1.0"&lt;BR&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Date: " &amp;amp; BuildDateTime(objIISLog.DateTime)&lt;BR&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Fields: date time c-ip cs-username s-ip s-port " &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"cs-method cs-uri-stem cs-uri-query sc-status cs(User-Agent)"&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Loop through the records in the log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;Do While Not objIISLog.AtEndOfLog&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Format the log file fields.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = BuildDateTime(objIISLog.DateTime)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.ClientIP) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.UserName) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.ServerIP) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.ServerPort) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.Method) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.URIStem) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.URIQuery) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.ProtocolStatus) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;" " &amp;amp; FormatField(objIISLog.UserAgent)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Write the output log file record.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine strLogRecord&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;' Read the next record from the log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;objIISLog.ReadLogRecord&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;Loop&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;' Close the input log file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;objIISLog.CloseLogFiles 1&lt;BR&gt;&amp;nbsp;&amp;nbsp;objIISLog = Null&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;End If&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Inform the user that the operation has completed.&lt;BR&gt;MsgBox "Finished!"&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Format a log file field.&lt;BR&gt;Function FormatField(tmpField)&lt;BR&gt;&amp;nbsp;On Error Resume Next&lt;BR&gt;&amp;nbsp;FormatField = "-"&lt;BR&gt;&amp;nbsp;If Len(tmpField) &amp;gt; 0 Then FormatField = Trim(tmpField)&lt;BR&gt;End Function&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Format a log file date.&lt;BR&gt;Function BuildDateTime(tmpDateTime)&lt;BR&gt;&amp;nbsp;On Error Resume Next&lt;BR&gt;&amp;nbsp;tmpDateTime = CDate(tmpDateTime)&lt;BR&gt;&amp;nbsp;BuildDateTime = Year(tmpDateTime) &amp;amp; "-" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Month(tmpDateTime),2) &amp;amp; "-" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Day(tmpDateTime),2) &amp;amp; " " &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Hour(tmpDateTime),2) &amp;amp; ":" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Minute(tmpDateTime),2) &amp;amp; ":" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Second(tmpDateTime),2)&lt;BR&gt;End Function&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' Create a random name.&lt;BR&gt;Function CreateRandomName(intNameLength)&lt;BR&gt;&amp;nbsp;Const strValidChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"&lt;BR&gt;&amp;nbsp;Dim tmpX, tmpY, tmpZ&lt;BR&gt;&amp;nbsp;For tmpX = 1 To intNameLength&lt;BR&gt;&amp;nbsp;&amp;nbsp;tmpY = Mid(strValidChars,Int(Rnd(1)*Len(strValidChars))+1,1)&lt;BR&gt;&amp;nbsp;&amp;nbsp;tmpZ = tmpZ &amp;amp; tmpY&lt;BR&gt;&amp;nbsp;Next&lt;BR&gt;&amp;nbsp;CreateRandomName = tmpZ&lt;BR&gt;End Function&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;Happy coding!&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=562127" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Creating an Itemized List of Server Bindings</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2006/02/21/creating-an-itemized-list-of-server-bindings.aspx</link><pubDate>Tue, 21 Feb 2006 22:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:536299</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/536299.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=536299</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Verdana&gt;One of my servers has a large number of individual web sites on it, and each of these web sites has several serveral server bindings for different IP addresses, Port Assignments, and Host Headers. As I continue to add more web sites on the server, it becomes increasingly difficult to keep track of all the details using the IIS user interface.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;With that in mind, I wrote the following ADSI script which creates a text file that contains an itemized list of all server bindings on a server.&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Option Explicit&lt;BR&gt;On Error Resume Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Dim objBaseNode, objChildNode&lt;BR&gt;Dim objBindings, intBindings&lt;BR&gt;Dim objFSO, objFile, strOutput&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' get a base object&lt;BR&gt;Set objBaseNode = GetObject("IIS://LOCALHOST/W3SVC")&lt;BR&gt;Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")&lt;BR&gt;Set objFile = objFSO.CreateTextFile("ServerBindings.txt")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' check if if have an error ...&lt;BR&gt;If (Err.Number &amp;lt;&amp;gt; 0) Then&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' ... and output the error.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strOutput = "Error " &amp;amp; Hex(Err.Number) &amp;amp; "("&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strOutput = strOutput &amp;amp; Err.Description &amp;amp; ") occurred."&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;' ... otherwise, continue processing.&lt;BR&gt;Else&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' loop through the child nodes&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each objChildNode In objBaseNode&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' is this node for a web site?&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If objChildNode.class = "IIsWebServer" Then&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the name of the node&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strOutput = strOutput &amp;amp; "LM/W3SVC/" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objChildNode.Name&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the server comment&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strOutput = strOutput &amp;amp; " (" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objChildNode.ServerComment &amp;amp; ")" &amp;amp; vbCrLf&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the bindings&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objBindings = objChildNode.ServerBindings&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' loop through the bindings&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For intBindings = 0 To UBound(objBindings)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strOutput = strOutput &amp;amp; vbTab &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Chr(34) &amp;amp; objBindings(intBindings) &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Chr(34) &amp;amp; vbCrLf&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' try not to be a CPU hog&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Wscript.Sleep 10&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;End If&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;objFile.Write strOutput&lt;BR&gt;objFile.Close&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objBaseNode = Nothing&lt;BR&gt;Set objFSO = Nothing&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;Hope this helps!&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=536299" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Updating several IP addresses using ADSI</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2006/01/11/updating-several-ip-addresses-using-adsi.aspx</link><pubDate>Wed, 11 Jan 2006 19:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:511616</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/511616.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=511616</wfw:commentRss><description>&lt;P&gt;(&lt;EM&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;: I had originally posted this information on a blog that I kept on &lt;A href="http://weblogs.asp.net/" mce_href="http://weblogs.asp.net/"&gt;http://weblogs.asp.net&lt;/A&gt;, but it makes more sense to post it here&lt;/EM&gt;. [:)] )&lt;/P&gt;
&lt;P&gt;Like many web programmers, I host several hobby web sites for fun. (They make a wonderful test bed for new code. ;-] )&lt;/P&gt;
&lt;P&gt;And like many computer enthusiasts, I sometimes change my ISP for one reason or another. If you are hosting web sites in a similar situation, I’m sure that you can identify the pain of trying to manually update each old IP address to your new IP address. This situation can be made even more difficult when any number of your web sites are using several host headers because the user interface for the IIS administration tool only lists the first host header. This means that you have to manually view the properties for every site just to locate the IP addresses that you are required to change.&lt;/P&gt;
&lt;P&gt;Well, I’m a big believer in replacing any repetitive task with code when it is possible, and a recent change of ISP provided just the right level of inspiration for me to write a simple Active Directory Service Interfaces (ADSI) script that locates IP addresses that have to be changed and updates them to their new values.&lt;/P&gt;
&lt;P&gt;To use the example script, I would first suggest that you make a backup copy of your metabase. (The script works fine, but it is always better to have a backup. ;-] ) As soon as your metabase has been backed up, copy the example script into notepad or some other text editor, update the old and new IP addresses that are defined as constants, and then run the script.&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Option Explicit&lt;BR&gt;On Error Resume Next&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Dim objIIS&lt;BR&gt;Dim objSite&lt;BR&gt;Dim varBindings&lt;BR&gt;Dim intBindings&lt;BR&gt;Dim blnChanged&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Const strOldIP = "10.0.0.1"&lt;BR&gt;Const strNewIP = "192.168.0.1"&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;Set objIIS = GetObject("IIS://LOCALHOST/W3SVC")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080&gt;If (Err &amp;lt;&amp;gt; 0) Then&lt;BR&gt;&amp;nbsp; WScript.Echo "Error " &amp;amp; Hex(Err.Number) &amp;amp; "(" &amp;amp; _&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Err.Description &amp;amp; ") occurred."&lt;BR&gt;&amp;nbsp; WScript.Quit&lt;BR&gt;Else&lt;BR&gt;&amp;nbsp; For Each objSite In objIIS&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnChanged = False&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If objSite.class = "IIsWebServer" Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varBindings = objSite.ServerBindings&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For intBindings = 0 To UBound(varBindings)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If InStr(varBindings(intBindings),strOldIP) Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blnChanged = True&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; varBindings(intBindings) = Replace(varBindings(intBindings),strOldIP,strNewIP)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If blnChanged = True Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objSite.ServerBindings = varBindings&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; objSite.Setinfo&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp; Next&lt;BR&gt;End If&lt;BR&gt;MsgBox "Finished!"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That’s all for now. Happy coding!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=511616" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item><item><title>Converting NCSA log files to W3C format</title><link>http://blogs.msdn.com/robert_mcmurray/archive/2005/11/30/converting-ncsa-log-files-to-w3c-format.aspx</link><pubDate>Thu, 01 Dec 2005 02:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:498658</guid><dc:creator>robert_mcmurray</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/robert_mcmurray/comments/498658.aspx</comments><wfw:commentRss>http://blogs.msdn.com/robert_mcmurray/commentrss.aspx?PostID=498658</wfw:commentRss><description>&lt;p&gt;One of the great utilities that ships with IIS is the CONVLOG.EXE application, which converts W3C or MS Internet Standard log files to NCSA format, where they can be processed by any of the applications that only parse NCSA log file information. The trouble is, what happens when you already have NCSA log files and you want W3C log files? You can't use the CONVLOG.EXE application, it only works in the opposite direction.&lt;/p&gt;
&lt;p&gt;With that in mind, I wrote the following Windows Script Host (WSH) script that will read the current directory and convert all NCSA-formatted log files to W3C format. To use this code, just copy the code into notepad, and save it with a ".vbs" file extension on your system. To run it, copy the script to a folder that contains NCSA log files, (named "nc*.log"), then double-click it.&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Option Explicit&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Dim objIISLog&lt;br/&gt;Dim objFSO&lt;br/&gt;Dim objFolder&lt;br/&gt;Dim objFile&lt;br/&gt;Dim objOutputFile&lt;br/&gt;Dim strInputPath&lt;br/&gt;Dim strOutputPath&lt;br/&gt;Dim strLogRecord&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Set objFolder = objFSO.GetFolder(".")&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;For Each objFile In objFolder.Files&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;strInputPath = LCase(objFile.Name)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;If Left(strInputPath,2) = "nc" And Right(strInputPath,4) = ".log" Then&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;strOutputPath = objFolder.Path &amp;amp; "\" &amp;amp; "ex" &amp;amp; Mid(strInputPath,3)&lt;br/&gt;&amp;nbsp;&amp;nbsp;strInputPath = objFolder.Path &amp;amp; "\" &amp;amp; strInputPath&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;Set objIISLog = CreateObject("MSWC.IISLog")&lt;br/&gt;&amp;nbsp;&amp;nbsp;objIISLog.OpenLogFile strInputPath, 1, "", 0, ""&lt;br/&gt;&amp;nbsp;&amp;nbsp;Set objOutputFile = objFSO.CreateTextFile(strOutputPath)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;objIISLog.ReadLogRecord&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Software: Microsoft Internet Information Services 5.0"&lt;br/&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Version: 1.0"&lt;br/&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Date: " &amp;amp; BuildDateTime(objIISLog.DateTime)&lt;br/&gt;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine "#Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem cs-uri-query sc-status cs(User-Agent)"&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;Do While Not objIISLog.AtEndOfLog&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = BuildDateTime(objIISLog.DateTime)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.ClientIP)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.UserName)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.ServerIP)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.ServerPort)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.Method)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.URIStem)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.URIQuery)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.ProtocolStatus)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;strLogRecord = strLogRecord &amp;amp; " " &amp;amp; FormatField(objIISLog.UserAgent)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;objOutputFile.WriteLine strLogRecord&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;objIISLog.ReadLogRecord&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;Loop&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;&amp;nbsp;&amp;nbsp;objIISLog.CloseLogFiles 1&lt;br/&gt;&amp;nbsp;&amp;nbsp;objIISLog = Null&lt;br/&gt;&amp;nbsp;&lt;br/&gt;&amp;nbsp;End If&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Next&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Function FormatField(tmpField)&lt;br/&gt;&amp;nbsp;On Error Resume Next&lt;br/&gt;&amp;nbsp;FormatField = "-"&lt;br/&gt;&amp;nbsp;If Len(tmpField) &amp;gt; 0 Then FormatField = Trim(tmpField)&lt;br/&gt;End Function&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" color=#000080&gt;Function BuildDateTime(tmpDateTime)&lt;br/&gt;&amp;nbsp;On Error Resume Next&lt;br/&gt;&amp;nbsp;tmpDateTime = CDate(tmpDateTime)&lt;br/&gt;&amp;nbsp;BuildDateTime = Year(tmpDateTime) &amp;amp; "-" &amp;amp; _&lt;br/&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Month(tmpDateTime),2) &amp;amp; "-" &amp;amp; _&lt;br/&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Day(tmpDateTime),2) &amp;amp; " " &amp;amp; _&lt;br/&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Hour(tmpDateTime),2) &amp;amp; ":" &amp;amp; _&lt;br/&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Minute(tmpDateTime),2) &amp;amp; ":" &amp;amp; _&lt;br/&gt;&amp;nbsp;&amp;nbsp;Right("0" &amp;amp; Second(tmpDateTime),2)&lt;br/&gt;End Function&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I hope this helps!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=498658" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/IIS+Topics/default.aspx">IIS Topics</category><category domain="http://blogs.msdn.com/robert_mcmurray/archive/tags/Scripting/default.aspx">Scripting</category></item></channel></rss>