Just a short, simple blog for Bob to share his thoughts.
10 November 2008 • by Bob • FTP
In part 2 of my series on FTP clients, I thought it would be best to have a discussion about the differences between Implicit FTPS and Explicit FTPS. In my recent "FTP Clients - Part 1: Web Browser Support" blog post, I referenced Implicit and Explicit FTPS with a link to my Using FTP Over SSL walkthrough. But it occurred to me that some people may not understand the difference between the two, and my upcoming blog posts are going to build upon that knowledge, so I thought that a quick discussion of these two technologies would be prudent.
One of the many limitations of the File Transfer Protocol (FTP) is a general lack of security; e.g. user names and passwords are transmitted in clear text, data is transferred with no encryption, etc. In order to address this situation, FTP over SSL (FTPS) was introduced in Requests for Comments (RFC) article 2228 - FTP Security Extensions, and expanded in RFC 4217 - Securing FTP with TLS to address Transport Layer Security (TLS).
Following up on these RFC articles, the FTP service for Windows Server 2008 added support for FTPS, and the FTP SSL Settings Feature in the IIS Manager allows you to configure your FTPS settings to allow or require SSL, enforce 128-bit SSL, or customize your control/data channel SSL settings.
Explicit FTPS is really what RFCs 2228 and 4217 envisioned; basically the way this works is an FTP client connects over the control/command channel (usually on port 21), and then the client can negotiate SSL for either the command/control channel or the data channel using new FTP commands like AUTH, PROT, CCC, etc.
The FTP service for Windows Server 2008 allows customized settings for both the command/control channel and the data channel through the Advanced SSL Policy dialog:
There are several ways that Explicit FTPS might be implemented depending on your business needs:
Control Channel Data Channel Notes Allow Allow This configuration allows the client to decide whether any part of the FTP session should be encrypted. Require only
for credentialsAllow This configuration protects your FTP client credentials from electronic eavesdropping, and allows the client to decide whether data transfers should be encrypted. Require only
for credentialsRequire This configuration requires that the client's credentials must be secure, and then allows the client to decide whether FTP commands should be encrypted. However, all data transfers must be encrypted. Require Require This configuration is the most secure - the client must negotiate SSL using the FTPS-related commands before other FTP commands are allowed, and all data transfers must be encrypted.
Implicit FTPS takes SSL one step further than simply requiring that SSL-related commands must be sent first like you can with Explicit SSL; with Implicit FTPS, an SSL handshake must be negotiated before any FTP commands can be sent by the client. In addition, even though Explicit FTPS allows the client to arbitrarily decide whether to use SSL, Implicit FTPS requires that the entire FTP session must be encrypted. Basically the way that Implicit FTPS works is that an FTP client connects to the command/control channel, in this case using port 990, and immediately performs an SSL handshake; after SSL has been negotiated, additional FTP commands for the session can be sent by the FTP client.
Using FTPS in FTP service for Windows Server 2008 follows the Internet Assigned Numbers Authority (IANA) specification that the Implicit FTPS command/control channel is on port 990 and the Implicit FTPS data channel is on port 989.
Here's the way that you specify which type of FTP over SSL (FTPS) that you are using in Windows Server 2008:
Note: If you are using FTP on any ports other than the defaults of 21/20 and 990/989, you must make sure that those ports are not already assigned by IANA to another protocol. For more information, see the list of assigned port numbers on IANA's web site.
Choosing whether to use Explicit FTPS over Implicit FTPS is a personal choice, and generally this choice may depend on your business needs or your FTP client. In several FTP clients that I've tested, the FTP client chooses one form of FTPS over another as the default method, and the FTP client may require some manual configuration to use the other.
Shortly after shipping the FTP service for Windows Server 2008 we discovered an issue where the FTP service was not cleaning up Implicit SSL connections properly, and we issued a hotfix rollup package for the FTP service that is discussed in Microsoft Knowledge Base article 955136.
I hope this helps to clear things up a bit. ;-]
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
02 October 2008 • by Bob • IIS, Troubleshooting
I had an interesting question from a coworker who was trying to use AppCmd to set the site-level SSL options for an FTP site. This should have been straightforward, and the syntax that he gave me looked correct:
appcmd.exe set config -section:system.applicationHost/sites -[name='Default FTP Site'].ftpServer.security.ssl.controlChannelPolicy:SslAllow /commit:apphost
That being said, whenever he or I ran the command we received the following cryptic error from AppCmd:
Failed to process input: The parameter 'Site'].ftpServer.security.ssl.controlChannelPolicy='SslAllow'' must begin with a / or - (HRESULT=80070057).
The HRESULT=80070057
code can mean either "One or more arguments are invalid" or "The parameter is incorrect", which seemed wrong to me because the arguments looked correct. Based on the error message referring to the word 'Site', I retried the command using the site ID instead of the site name:
appcmd.exe set config -section:system.applicationHost/sites -[id='4'].ftpServer.security.ssl.controlChannelPolicy:SslAllow /commit:apphost
This worked as expected, so I knew that somehow the problem was with the site name.
I searched around and I found a forum post on IIS.NET where Anil Ruia had stated that when the site name has a space in it you should enclose the entire parameter statement in quotes. Armed with that knowledge, I tried the following command:
appcmd.exe set config -section:system.applicationHost/sites "-[name='Default FTP Site'].ftpServer.security.ssl.controlChannelPolicy:SslAllow" /commit:apphost
This fixed the problem and the command worked as I would have originally expected.
By the way, in general you should be able use the following command to get the FTP syntax listing for an area:
appcmd.exe set config -section:system.applicationHost/sites -? | find /i "ftp"
This wouldn't have helped my coworker identify the problem with the "name" parameter, but it would have helped by giving him the syntax for using the "id" parameter.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
30 September 2008 • by Bob • Office, VBA
Over the years, I had noticed that I had appointments from years ago stuck in my calendar, so I wrote this Outlook VBA Macro to export a list of all my appointments to a tab-separated (TSV) file so that I could open it in Microsoft Excel and analyze all of my appointments. (After writing this macro, I wrote my Delete Old Appointments macro to delete old appointments.)
Sub ExportAppointmentsToTsvFile()
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Dim objAppointement As Outlook.AppointmentItem
Dim objNetwork As Object
Dim objFSO As Object
Dim objFile As Object
Dim strUserName As String
Set objOutlook = Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
Set objNetwork = CreateObject("WScript.Network")
strUserName = objNetwork.UserName
If InStr(strUserName, "\") = 0 Then
strUserName = objNetwork.UserDomain & "\" & strUserName
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("c:\outlook-calendar.tsv")
objFile.WriteLine "UserName" & vbTab & _
"AppointementStart" & vbTab & _
"AppointementEnd" & vbTab & _
"AppointementRecurrenceState" & vbTab & _
"AppointementSubject" & vbTab & _
"AppointementSize" & vbTab & _
"AppointementUnRead" & vbTab & _
"AppointementLocation"
For Each objAppointement In objFolder.Items
DoEvents
objFile.WriteLine strUserName & vbTab & _
objAppointement.Start & vbTab & _
objAppointement.End & vbTab & _
objAppointement.RecurrenceState & vbTab & _
objAppointement.Subject & vbTab & _
objAppointement.Size & vbTab & _
objAppointement.UnRead & vbTab & _
objAppointement.Location
Next
MsgBox "Done!"
End Sub
30 September 2008 • by Bob • Office, VBA
Over the years, I had noticed that I had appointments from years ago stuck in my calendar, so I wrote this Outlook VBA Macro to help keep my outlook calendar thinned-out.
Note: This macros deletes appointments and attachments from your Outlook calendar - make sure that you want to do this before running this macro.
By default the macro will:
You can alter these dates by adjusting the appropriate lines in the macro.
Sub DeleteOldAppointments()
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Dim objAppointement As Outlook.AppointmentItem
Dim objAttachment As Outlook.Attachment
Dim objNetwork As Object
Dim lngDeletedAppointements As Long
Dim lngCleanedAppointements As Long
Dim lngCleanedAttachments As Long
Dim blnRestart As Boolean
Dim intDateDiff As Integer
Set objOutlook = Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
Here:
blnRestart = False
For Each objAppointement In objFolder.Items
DoEvents
intDateDiff = DateDiff("d", objAppointement.Start, Now)
' Delete year-old appointments.
If intDateDiff > 365 And objAppointement.RecurrenceState = olApptNotRecurring Then
objAppointement.Delete
lngDeletedAppointements = lngDeletedAppointements + 1
blnRestart = True
' Delete attachments from 6-month-old appointments.
ElseIf intDateDiff > 180 And objAppointement.RecurrenceState = olApptNotRecurring Then
If objAppointement.Attachments.Count > 0 Then
While objAppointement.Attachments.Count > 0
objAppointement.Attachments.Remove 1 Wend
lngCleanedAppointements = lngCleanedAppointements + 1
End If
' Delete large attachments from 60-day-old appointments.
ElseIf intDateDiff > 60 Then
If objAppointement.Attachments.Count > 0 Then
For Each objAttachment In objAppointement.Attachments
If objAttachment.Size > 500000 Then
objAttachment.Delete
lngCleanedAttachments = lngCleanedAttachments + 1
End If
Next
End If
End If
Next
If blnRestart = True Then GoTo Here
MsgBox "Deleted " & lngDeletedAppointements & " appointment(s)." & vbCrLf & _
"Cleaned " & lngCleanedAppointements & " appointment(s)." & vbCrLf & _
"Deleted " & lngCleanedAttachments & " attachment(s)."
End Sub
25 September 2008 • by Bob • FTP
Since we've been testing a lot of FTP clients with our new FTP server for IIS 7, I thought that it would be a good idea to discuss some of the highlights and pitfalls that we have run into when testing various clients.
I thought that I'd begin this series with an examination of several web browsers, which are really not the best FTP clients around - web browsers are mostly just "putting a pretty face" on an FTP site rather than functioning as an FTP client. In any event, here's a summary table of different features that I tested with a few web browsers:
Client Name | Directory Browsing | Explicit FTPS | Implicit FTPS | Virtual Hosts | True HOSTs |
---|---|---|---|---|---|
FireFox 3.0.2 (Mozilla) | Rich | N | N | Y | N |
Google Chrome 0.2.149 (Beta) | Basic | N | N | Y | N |
Internet Explorer 7.0 | Basic | N | N | Y | N |
Opera 9.5.2 | Rich | N | N | Y | N |
See the individual client notes below for more information on each client.
As far as web browsers are concerned, they're not great FTP clients. That being said, here's my thoughts on their respective experiences:
In the next part of this series, I'll start taking a look at some specific FTP clients.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
23 April 2008 • by Bob • FrontPage, IIS, WebDAV
Following up on my last blog post, today's blog post will discuss some of the highlights and pitfalls that I have seen while transitioning from using the FrontPage Server Extensions to publish web sites to WebDAV. It should be noted, of course, that FTP still works everywhere - e.g. Expression Web, FrontPage, Visual Studio, etc. As the Program Manager for both WebDAV and FTP in IIS I can honestly say that I love both technologies, but I'm understandably biased. <grin> That said, I'm quite partial to publishing over HTTP whenever possible, and Windows makes it easy to do because Windows ships with a built-in WebDAV redirector that enables you to map a drive to a web site that is using WebDAV.
To set the mood for today's blog, let's have a little fun at FPSE's expense...
To start things off, I wrote a detailed walkthrough with instructions regarding how to migrate a site that is using FPSE to WebDAV that is located at the following URL:
Migrating FPSE Sites to WebDAV
http://go.microsoft.com/fwlink/?LinkId=108347
I wrote that walkthrough from the point-of-view that you might want to preserve the FPSE-related metadata in order to open your web site using a tool like Visual Studio or FrontPage. Neither of these tools have native WebDAV support, so you have to map a drive to a WebDAV-enabled web site in order to use those tools, and the instructions in that walkthrough will lead you through the steps to make the FrontPage-related metadata available to those applications over WebDAV.
The part of that walkthrough that makes backwards compatibility work is where I discuss adding settings for the IIS 7 Request Filtering feature so that FPSE-related metadata files are blocked from normal HTTP requests, but still available to WebDAV. (These metadata settings are all kept in the folders with names like _vti_cnf, _vti_pvt, etc.)
It should be noted, however, that if you are not interested in backwards compatibility, the steps are much simpler. In Step 1 of the walkthrough, you would choose "Full Uninstall" as the removal option, and all of your _vti_nnn folders will be deleted. If you've already removed FPSE from a web site and you chose the "Uninstall" option, you can remove the _vti_nnn folders from your site by saving the following batch file as "_vti_rmv.cmd" in the root folder of you web site and then running it:
dir /ad /b /s _vti_???>_vti_rmv.txt for /f "delims=;" %%i in (_vti_rmv.txt) do rd /q /s "%%i" del _vti_rmv.txt
It's worth noting, of course, that this batch file can be pretty disastrous if run in the wrong web site, as FPSE will no longer be able to access any of the metadata that defined your web site. Any content stored in folders like _private, fpdb, _overlay, etc., will all be preserved.
Windows Vista and Windows Server 2008 both ship a first-class director, making it easy to use WebDAV sites across the Internet as though they were local shares. Using the WebDAV director is as intuitive as mapping a drive to any UNC share, you just specify the drive letter and the destination URL:
If you prefer, you can also use the command-line to map a drive to a WebDAV site:
net use * http://www.example.com/ Enter the user name for 'www.example.com': msbob Enter the password for www.example.com: ****** Drive Z: is now connected to http://www.example.com/. The command completed successfully.
Rather than repeat myself any more than necessary, I wrote the following walkthrough for anyone that plans on using the WebDAV redirector:
Using the WebDAV Redirector
http://go.microsoft.com/fwlink/?LinkId=112138
That walkthrough discusses how to install the redirector if necessary, how to map drives to WebDAV sites, and how to troubleshoot any problems that you might see.
One of my favorite publishing features in Expression Web is that it has native WebDAV support built-in, so it doesn't have a dependency on the WebDAV redirector in order to work with a WebDAV-enabled web site. If you're currently using Expression Web to open a web site using FPSE, the change to WebDAV should be fairly seamless. If you're currently using FrontPage, the Expression Web team has put together a whitepaper that describes the differences between FrontPage and Expression Web, which is available from the following link:
That being said, when opening a WebDAV web site in Expression Web, you simply enter the HTTP URL the same way that you would if you were opening a site using FPSE:
When you first open a web site using WebDAV, Expression Web will prompt you whether to edit the web site live, or edit locally and publish your changes later:
Once your live web site is opened, the WebDAV editing experience is what you would have expected from using FPSE:
So in closing, I've presented a few things to consider when working with WebDAV instead of FPSE. Using the WebDAV redirector makes working with WebDAV sites as easy as working with network shares, and using Expression Web is by far the easiest way to edit WebDAV sites.
17 April 2008 • by Bob • FrontPage, IIS
Today's blog post will be the first in a series of blog posts that I intend to write about my experiences with putting together a Windows Server 2008 machine without using the FrontPage Server Extensions (FPSE) for any web publishing. The main goal of this series is to describe some of the highlights and pitfalls that I have run into while transitioning away from FPSE.
Over the years I've seen the users of FPSE broken down into two groups: those that love FPSE and those that hate FPSE. So before anyone thinks that I fall into the category of people that hate FPSE, in this first part of the series I will explain a brief bit of my history with FPSE.
In late 1995, Microsoft bought a little-known Massachusetts-based company named Vermeer Technologies, Inc., which really only had one product: FrontPage 1.0. (Incidentally, that's where all of those _vti_nnn folders that FPSE uses come from: the "vti" stands for Vermeer Technologies, Inc.)
FrontPage was quickly transitioned into the Microsoft array of Office products, and Microsoft realized that they needed someone to support it. With that in mind, four of my coworkers and I started a FrontPage support team in Microsoft's Product Support Services (PSS) organization. The following photo shows what the five of us looked like "way back when..."
Back then we supported both the FrontPage client and FPSE. Two coworkers specialized on what was then a small array of Windows-based servers (WebSite, Netscape, etc.), while another coworker and I specialized on the wider array of Unix-based servers, (NCSA, CERN, Netscape, Apache, etc.) At first FPSE was 100% CGI-based, but Microsoft soon released Internet Information Services (IIS) 1.0 for Windows NT Server 3.51 and we provided an ISAPI version of FPSE when FrontPage 1.1 was released in early 1996. In either case, FPSE was often somewhat difficult to configure, so a couple of my coworkers and I used to spend our free time searching the Internet looking for servers that were using FPSE incorrectly, then we would call them and offer to help fix their web sites for free. (Support was different back then, wasn't it? )
Industry acceptance for FrontPage and FPSE grew rapidly through the releases of FrontPage 97 and FrontPage 98. During that same time period Microsoft released IIS 2.0 through IIS 4.0 for Windows NT Server 4.0, where I switched from supporting the FrontPage client and refocused my career to work exclusively with FPSE and IIS. Over a short period of time a couple of coworkers and I became the escalation point for all the really difficult FPSE cases - so chances are good that if you were using FPSE back then and you had a problem then one us us probably helped you fix it. Sometime around this period Microsoft decided to scrap internal development for the Unix version of FPSE, so Microsoft contracted Ready-to-Run Software, Inc., to port FPSE to Unix.
The next couple of years saw the releases of FrontPage 2000, FrontPage 2002, and FrontPage 2003, where FrontPage did its best to move away from a simple web authoring tool into more of a feature-rich developer tool. During that same time period Microsoft released IIS 5.0 for Windows Server 2000 and IIS 6.0 for Windows Server 2003. Through all of these releases I slowly transitioned from an escalation team member to writing content, where I wrote or edited hundreds of Knowledge Base articles about FPSE and IIS for Microsoft's support web site. I also worked extensively with several members of the IIS product team in order to get some much-needed changes into FTP and WebDAV.
What was interesting about the release of FrontPage 2003 is that Microsoft did not release a version of FPSE to coincide with that release. This decision was based on the fact that the product team that was responsible for FPSE was also responsible for SharePoint, and they decided to drop FPSE as a separate product in favor of SharePoint. What this meant to FPSE end users was - FPSE was being slowly phased out in favor of SharePoint, or in favor of competing publishing technologies like WebDAV or FTP.
After the release of IIS 6.0 I accepted a position as an SDK writer on the IIS User Education team, and a short time later I found out that the Product Unit Manager for IIS, Bill Staples, was looking for someone to take over web publishing in IIS 7.0 on Windows Server 2008. Bill and I had already had several discussions on the subject so I volunteered for the position, and for the last few years my life has been happily consumed with shipping FPSE, FTP, and WebDAV for Windows Server 2008.
During this same time period, however, Microsoft ended the line of FrontPage products; the team responsible for the FrontPage client splintered into the groups that now make the SharePoint Designer and Expression Web products, and the FPSE product team was now focusing exclusively on SharePoint. This situation meant that no one that worked on FPSE in the past was available to work on a new version for Windows Vista or Windows Server 2008, which left FPSE users in a predicament if they wanted to upgrade their operating systems. With this in mind, the IIS product team decided to contract Ready-to-Run Software, Inc. again in order to port the Windows version of FPSE to Windows Vista and Windows Server 2008. Even then, though, FPSE's days are numbered.
So, the short end to this long story is that I've been around the FrontPage Server Extensions in one way or another ever since the very beginning, and I've seen the good, the bad, and the ugly.
In my next post, I'll discuss using WebDAV instead of FPSE.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
08 March 2008 • by Bob • IIS, Scripting
Many years ago I wrote the following KB article:
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 IIsBack.vbs script to help customers automate backups.
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 Microsoft TechEd, I thought it might make a nice blog post for everyone that can't make it to TechEd.
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 to your executable search path as well.)
@echo off cls pushd "%WinDir%\System32\inetsrv" echo.| date | find /i "current">datetime1.tmp echo.| time | find /i "current">datetime2.tmp for /f "tokens=1,2,3,4,5,6" %%i in (datetime1.tmp) do ( echo %%n>datetime1.tmp ) for /f "tokens=1,2,3,4,5,6" %%i in (datetime2.tmp) do ( echo %%m>datetime2.tmp ) for /f "delims=/ tokens=1,2,3" %%i in (datetime1.tmp) do ( set TMPDATETIME=%%k%%i%%j ) for /f "delims=:. tokens=1,2,3,4" %%i in (datetime2.tmp) do ( set TMPDATETIME=D%TMPDATETIME%T%%i%%j%%k%%l ) appcmd add backups %TMPDATETIME% del datetime1.tmp del datetime2.tmp set TMPDATETIME= popd echo.
You can use Task Scheduler in Windows Server 2008's Server Manager to schedule this script to run at whatever interval you choose, although I usually schedule it to run once a week.
Backups will be created in the following path:
%WinDir%\System32\Inetsrv\Backups\DyyyymmddThhmmssii
Where yyyymmdd is the year, month, day, and hhmmssii is the hour, minute, second, millisecond for the time of the backup.
I hope this helps!
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/
17 February 2008 • by Bob • FrontPage
This FrontPage VBA Macro is designed to disable the right-click and text selection functionality for every HTML or ASP file within the currently open web site by inserting some simple JavaScript code.
Note: Unfortunately, not all web clients are created or configured equally, so some web clients will ignore this JavaScript code. So this feature will almost always work, but there's no way to guarantee.
Public Sub DisableRightClickInAllFolders()
Dim objWebFolder As WebFolder
Dim objWebFile As WebFile
Dim strExt As String
If Len(Application.ActiveWeb.Title) = 0 Then
MsgBox "A web must be open." & vbCrLf & vbCrLf & "Aborting.", vbCritical
Exit Sub
End If
With Application
For Each objWebFile In .ActiveWeb.AllFiles
DoEvents
strExt = LCase(objWebFile.Extension)
If strExt = "htm" Or strExt = "html" Or strExt = "asp" Then
objWebFile.Edit
DoEvents
.ActiveDocument.body.onContextMenu = "return false"
.ActiveDocument.body.onselectstart = "return false"
.ActivePageWindow.Save
.ActivePageWindow.Close
End If
Next
End With
End Sub
17 February 2008 • by Bob • FrontPage
This FrontPage VBA Macro is designed to return an array of all the folder URLs for the currently-open web site. I call this function from a lot of my other macros.
Private Function BuildFolderUrlTree() As Variant
On Error Resume Next
' Declare all our variables
Dim objWebFolder As WebFolder
Dim objFolder As WebFolder
Dim objSubFolder As WebFolder
Dim strBaseFolder As String
Dim lngFolderCount As Long
Dim lngBaseCount As Long
With Application
' Check the caption of the application to see if a web is open.
If .ActiveWebWindow.Caption = "Microsoft FrontPage" Then
' If no web is open, display an informational message...
MsgBox "Please open a web before running this function.", vbCritical
' ... and end the macro.
Exit Function
End If
' Change the web view to folder view.
.ActiveWeb.ActiveWebWindow.ViewMode = fpWebViewFolders
' Refresh the web view and recalc the web.
.ActiveWeb.Refresh
' Define the initial values for our folder counters.
lngFolderCount = 1
lngBaseCount = 0
' Dimension an aray to hold the folder names.
ReDim strFolders(1) As Variant
' Get the URL of the root folder for the web...
strBaseFolder = .ActiveWeb.RootFolder.Url
' ... and store the URL in our array.
strFolders(1) = strBaseFolder
' Loop while we still have folders to process.
While lngFolderCount <> lngBaseCount
' Set up a WebFolder object to a base folder.
Set objFolder = .ActiveWeb.LocateFolder(strBaseFolder)
' Loop through the collection of subfolders for the base folder.
For Each objSubFolder In objFolder.Folders
' Check to make sure that the subfolder is not a web.
If objSubFolder.IsWeb = False Then
' Increment our folder count.
lngFolderCount = lngFolderCount + 1
' Increase our array size
ReDim Preserve strFolders(lngFolderCount)
' Store the folder name in our array.
strFolders(lngFolderCount) = objSubFolder.Url
End If
Next
' Increment the base folder counter.
lngBaseCount = lngBaseCount + 1
' Get the name of the next folder to process.
strBaseFolder = strFolders(lngBaseCount + 1)
Wend
End With
' Return the array of folder names.
BuildFolderUrlTree = strFolders
End Function