A customer asked me a question a little while ago that provided me the opportunity to recycle some code that I had written many years ago. In so doing, I also made a bunch of updates to the code to make it considerably more useful, and I thought that it would make a great blog.
Here's the scenario: a customer had hundreds of user accounts created, and he wanted to use the FTP service's User Isolation features to restrict each user to a specific folder on his FTP site. Since it would take a long time to manually create a folder for each user account, the customer wanted to know if there was a way to automate the process. As it turns out, I had posted a very simple script in the IIS.net forums several years ago that did something like what he wanted; and that script was based off an earlier script that I had written for someone else back in the IIS 6.0 days.
One quick reminder - FTP User Isolation uses a specific set of folders for user accounts, which are listed in the table below.
|User Account Types||Home Directory Syntax|
|Local Windows user accounts
(Requires Basic authentication.)
|Windows domain accounts
(Requires Basic authentication.)
Note: %FtpRoot% is the root directory for your FTP site: for example, C:\Inetpub\Ftproot.
That being said, I'm a big believer in recycling code, so I found the last version of that script that I gave to someone and I made a bunch of changes to it so it would be more useful for the customer. What that in mind, here's the resulting script, and I'll explain a little more about what it does after the code sample.
' Define the root path for the user isolation folders.
' This should be the root directory for your FTP site.
Dim strRootPath : strRootPath = "C:\Inetpub\wwwroot\"
' Define the name of the domain or the computer to use.
' Leave this blank for the local computer.
Dim strComputerOrDomain : strComputerOrDomain = ""
' Define the remaining script variables.
Dim objFSO, objCollection, objUser, objNetwork, strContainerName
' Create a network object; used to query the computer name.
Set objNetwork = WScript.CreateObject("WScript.Network")
' Create a file system object; used to creat folders.
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Test if the computer name is null.
If Len(strComputerOrDomain)=0 Or strComputerOrDomain="." Then
' If so, define the local computer name as the account repository.
strComputerOrDomain = objNetwork.ComputerName
' Verify that the root path exists.
If objFSO.FolderExists(strRootPath) Then
' Test if the script is using local users.
If StrComp(strComputerOrDomain,objNetwork.ComputerName,vbTextCompare)=0 Then
' If so, define the local users container path.
strContainerName = "LocalUser"
' And define the users collection as local.
Set objCollection = GetObject("WinNT://.")
' Otherwise, use the source name as the path.
strContainerName = strComputerOrDomain
' And define the users collection as remote.
Set objCollection = GetObject("WinNT://" & strComputerOrDomain & "")
' Append trailing backslash if necessary.
If Right(strRootPath,1)<>"\" Then strRootPath = strRootPath & "\"
' Define the adjusted root path for the container folder.
strRootPath = strRootPath & strContainerName & "\"
' Test if the container folder already exists.
If objFSO.FolderExists(strRootPath)=False Then
' Create the container folder if necessary.
' Specify the collection filter for user objects only.
objCollection.Filter = Array("user")
' Loop through the users collection.
For Each objUser In objCollection
' Test if the user's account is enabled.
If objUser.AccountDisabled = False Then
' Test if the user's folder already exists.
If objFSO.FolderExists(strRootPath & "\" & objUser.Name)=False Then
' Create the user's folder if necessary.
objFSO.CreateFolder(strRootPath & "\" & objUser.Name)
I documented this script in great detail, so it should be self-explanatory for the most part. But just to be on the safe side, here's an explanation of what this script is doing when you run it on your FTP server:
- Defines two user-updatable variables:
- strRootPath - which specifies the physical path to the root of your FTP site.
- strComputerOrDomain - which specifies the computer name or the domain name where your user accounts are located. (Note: You can leave this blank if you are using local user accounts on your FTP server.)
- Creates a few helper objects and determines the local computer name if necessary.
- Checks to see if the physical path to the root of your FTP site actually exists before continuing.
- Creates a connection to the user account store (local or domain).
- Determines the container folder name that be the parent directory of user account folders, and creates it if necessary. (See my earlier note about the folder names.)
- Defines a filter for user objects in the specifies account repository. (This removes computer accounts and such from the operation.)
- Loops through the collection of user accounts, checks each account to see if it is enabled, and creates a folder for each user account if it does not already exist.
That's all for now. ;-]
(Cross-posted from http://blogs.msdn.com/robert_mcmurray/)