Making Sense of the SharePoint World

Nov-122009

SharePoint Virtualization

MCj04115480000[1]All of Your Eggs in One Basket?

Every time a new version of a virtualization tool comes out, people get all excited about the possibility of reducing the costs of running their data centers. Most of them are thinking in terms of hardware consolidation, but virtualized environments also allow for new ways of handling resilience and recovery as well.

This is all well and good, but then you run into what I call "the new hammer syndrome". The idea is, after you buy a new hammer, everything starts to look like a nail. You keep thinking of ways to apply this new tool. Some of them are great. Others, not so much.

Virtualization and SharePoint

SharePoint, in particular, frequently seems like a ripe target for virtualization. It has a multitude of roles, which can be (and often are) distributed among many servers. Data center managers see all of this hardware and envision collapsing it onto a single box. And, SharePoint is officially supported in virtualized environments. It seems like a match made in heaven, doesn't it?

But, not so fast! Take a step back and think about what I just said. You are taking all of these SharePoint roles, and spreading them out among multiple servers. Now you want to take all of these servers and virtualize them back onto a single piece of hardware? Where is the sense in that?

Why did you build out that many servers in the first place?

Pausing while people try to gather back the pieces of their exploded heads from that bit of circular logic...

Profound, isn't it? Almost like a Zen koan.

On Over-Engineering a Solution

SharePoint will very happily run all of its roles on a single server (physical or virtual), if you want it to. So, why would you want to split the roles at all? There are really only two reasons (good ones, anyway) - performance, and resilience. (No, I don't consider being able to point at a monitoring station covering a half-dozen or more servers and saying "Look at all of the systems I manage in my SharePoint farm" a good reason.)

From a performance standpoint, some SharePoint roles are real resource hogs. The two big ones would be SQL Server and Search Indexing/Crawling. SQL Server, though not technically part of SharePoint, is hit pretty much constantly by nearly every SharePoint component, and so is almost always set aside on separate hardware. The search crawl process, though intense, is "peaky." In other words, it goes through cycles of short bursts of intense activity, followed by periods of near idleness. In comparison, the web front-end functionality is a cake-walk. A single WFE server can handle potentially many thousands of users without breaking a sweat.

In fact, a big, modern server can probably handle hundreds, if not thousands, of users even with everything except SQL Server running on it. (Naturally, this depends upon just what those users are doing.) So performance is rarely the real reason for splitting off most of SharePoint's functions, except in very large environments.

That leaves resilience. Resilience is the ability of a system to keep on going, even if a piece of it fails. By splitting the SharePoint roles onto several servers, and having multiple instances of the roles that face your users, you can create a system which can tolerate a failure of any one component with minimal short-term impact. It is possible to take this too far, however. It isn't a case of "if two are good, three must be better, and five are better still."

What good is having three or more web front end servers, when they all sit practically idle at singe-digit percent utilization - even during peak periods? Not very good at all. At a minimum, it is not a very efficient use of resources. This is the kind of thing that makes virtualization look really attractive.

Balance

So, is virtualization really the answer? Maybe. Or maybe not. Let's get back to that biggest of little questions - "Why?"

Why did you build out your farm onto multiple servers?

Did you build out this big farm because your usage is so heavy, you were stressing out anything less? Then you are almost certainly not a good candidate for virtualization. In this case, you've got your hardware optimized to its load. Virtualization is just going to add another layer, and if you're already fully loading your systems, you won't get any benefit from host sharing with other virtual servers. The only reason you might justify going virtual is to be able to quickly replicate a failed system from an image, or shift a running image onto another host. But can you handle the extra overhead?

Did you build out your farm for resilience? The minimum "fully" resilient SharePoint farm is a configuration I call "2.1+". That's two servers running as WFE and Query servers (along with Excel Services in Enterprise Edition), one application server running the Index role (of which there can be only one per SSP) and optionally running other duplicated roles as well, "plus" a properly specified SQL cluster. This configuration can handle thousands of users, even with modest (by today's standards) hardware. In fact, from a performance standpoint it is probably still overkill for most organizations. Here, you might find some room to virtualize. But be careful - you split these roles out in the first place to avoid having a single point of failure. Virtualizing them and simply placing all of the VM's on a single host eliminates that benefit.

And What About SQL Server?

I decided to write about virtualization because I've been approached several times in the last week or so with folks asking about virtualizing the SQL Server side of SharePoint. Up until now, even when virtualization has been appropriate for some SharePoint components, I've always advised against making SQL virtual. But VMWare has just introduced a new version for which their marketing message is claiming that SQL virtualization is now a good thing.

Frankly, I'm not convinced. My main concern is that SharePoint is a very heavy user of SQL Server. Again it boils down to your utilization. Are your SQL Servers already CPU or disk I/O bound? If so, virtualization isn't going to help matters. If not, then you might be OK. Even if you decide to virtualize computation, I would still avoid virtualizing the data storage without first doing extensive load testing.

Going Forward

Ultimately, all computer configuration involves trade-offs. Cost, performance, and resilience are three corners of one of those "pick any two" engineering triangle conundrums. Virtualization doesn't eliminate the trade-off, but it can shift the balance toward the lower-cost corner. Whether or not it is appropriate in your case will depend upon your server load and tolerance for risk. In the case of SharePoint, you can achieve many of the same results as virtualization by simply re-consolidating the roles that were originally split off.

Mark Twain once said: "Keep all of your eggs in one basket - then watch that basket!" If you do decide to virtualize, make sure you take appropriate precautions. The Microsoft Consulting Services UK SharePoint Team has written an excellent series of articles on SharePoint virtualization. I suggest checking that out for more technical details.


Sep-202009

Indexing SharePoint List Columns

MCj03800210000[1]

Helping SharePoint Help You

A SharePoint system manages a huge amount of data. Amazingly, in a SharePoint content database, all of the data, for every list and library item, in every site and subsite, is stored in a single table. Looking at hundreds of sites, each with dozens of lists and libraries, each potentially containing hundreds or thousands of items, and you end up with one massive table!

Not So Limiting After All

Everybody has heard about the so-called "2000 item limit" in SharePoint. Remember that this isn't really a limit. SharePoint is quite capable of handling lists with tens, or even hundreds, of thousands of items. The issue is the "rendering" of those items, which starts becoming perceptibly slower if you have more than 2000 items in a single view.

While the indexing discussed in this article can have a minor effect on this rendering, it really is more general, and can improve list performance across the board.

Ask any DBA how to achieve maximum performance on a huge table, while other options may also come up, at a minimum you'll always hear the word "indexing". And make no mistake - SharePoint (whether Windows SharePoint Services 3.0, or Office SharePoint Server 2007) does do a lot of indexing. But that is only dealing with the user data table as a whole.

Once SharePoint has figured out which site and list the data belongs to, normally it is pretty much done with indexing. When you perform a query - whether in code, or for a web part view - each item in the list is examined individually for a match. As the amount of information in your sites grows, this can take quite a bit of time and cause significant slowdowns (This is independent of the "2000 item limit" - see sidebar).

Fortunately, you don't have to put up with this default behavior. SharePoint gives you the additional ability to index the information within individual lists or libraries.

Look at the settings page for just about any list or library, and you will find a link for "Indexed columns":

image

When you click the link, you will be given the opportunity to select which columns in your list you wish to index. This is where an understanding of your information, and how you use it comes into play. While you could just click everything, that isn't usually a good idea. For each column you index, SharePoint needs to store extra information about every item in your list.

You should only select columns for indexing that you will be using to query/filter, sort, and group your list. For this list, I'll usually need to do this with the item's title (or name), who created or modified an item, and when it starts. So those are the columns I'll select to index:

image

Note: When setting up indexed columns, you will almost always want to include the title or name field.

Once you click OK, SharePoint will build the appropriate extra indexes. While there won't be any change to the way your list looks, you should see the performance results almost immediately. (Of course, the more items in your list, the greater the impact will be...)

One place you usually see immediate results is when you click on the context menu of a column title to change the sorting or filtering. The list of unique values builds much faster on an indexed column.

image

That's all there is to it! Setting up indexed columns in your SharePoint list really is that simple. Give it a shot, and you might be surprised at how much faster your SharePoint applications can be.


Sep-162009

SharePoint Values Your Uniqueness

MCj04356080000[1]"Who Did You Say You Were?"

Today I'm going to talk about user accounts. In particular, Windows Active Directory accounts. You might be thinking, "This doesn't sound like a SharePoint topic!" But rest assured, it is.

I've talked about Windows accounts and SharePoint before. For example, I've told you about the many accounts you need to consider when setting up a SharePoint farm, and how to discover the Setup User account after the fact. I've also mentioned how you can let SharePoint know when User ID's change.

Normally, each person has one Windows account (user ID and password). They use this account to log into their PC in the morning, thus proving to the network who they are. This is called "authentication". Many systems that recognize Windows authentication (including SharePoint) will simply accept these credentials from the user's PC, without any further user intervention.  The systems use these credentials to determine what data and functions the user has been "authorized" to access by the administrator of the system.

Note: Behind the scenes, it is quite a bit more complicated than that. While a complete discussion of handshaking and protocols is beyond the scope of this article, understand that the negotiations taking place do result in one of the issues I will describe below.

On Being a Highlander - "There Can Should be Only One"

By and large, this system works pretty well. However, it is based on a pretty big assumption - that each user has only one account for their "day to day" system usage, and each account has only one user. Unfortunately, from time to time this assumption doesn't hold true. This can cause some subtle, and not-so-subtle (but hard to trace) problems in SharePoint if you aren't careful.

I'm going to discuss three main scenarios:

  1. One user has multiple accounts
  2. One account is shared across multiple users
  3. Accounts in different domains that have the same UserID portion, but different passwords.

For each group, I'll talk about why it might occur, how it presents a challenge, a few variations on the theme, and what you can do to minimize the difficulties presented by it.

One User, Multiple Accounts

Why it might happen:

There are many specific reasons a user might have multiple accounts, but they generally fall into three categories - Administration, Test, and Transition.

Transitions can be wide-spread - such as when companies realign or change naming standards, or individual - such as when marital status changes. Regardless of the reason for a transition though, generally there will be an "old" account, and a "new" account.

For purposes of this section, I'm considering administrative and test accounts to be equivalent. They don't need to be "administrators" per se, and the account may exist mainly for applications other than SharePoint. Essentially these are any accounts that a user signs into for a particular task that has different privileges from their normal User ID (e.g. DBA), and their use is often dictated by policy or best-practice. Regardless of the reason, the challenges and resolutions are basically the same.

Why this is a challenge:

Aside from the obvious - making sure each account actually has access to the correct resources - SharePoint keys a lot of stuff based on the current user. From Created and Modified by tags, to personalized pages, and audience targeting, SharePoint knows and shows who you are. But the real hazard of multiple accounts is their effect on profiles and my-sites.

User profiles are crated from Active Directory imports, as well as user-entered information. Certain features of My Sites, such as organizational relationships are built using the imported information. Typically a user's "primary" account will populate such fields a their title, office location, manager, and other useful business information. Administration and Test accounts, on the other hand, generally just use the name to describe the purpose of the account, and little else.

These impact not only the current user, but others as well. For example, suppose you fully populate AD info for each of the accounts. When someone clicks on the manager's profile, suddenly they will show all of the secondary accounts, as well as the "real" user, in their reporting relationships. Or, what if the user has reports of their own? Since each can only have one manager, you need to be very careful to assign it to the correct account, otherwise, someone may end up not appearing in org charts, or they may appear in the wrong place.

image

When someone starts using these secondary accounts for day-to-day activities in SharePoint, this is the account noted as the creator or modifier of data items, and tracked in logs. If you use Communicator, SharePoint's presence indicators can also be affected. They will show the presence and contact info for the account that actually made the change, rather than the potential real presence for the user.

Finally, aside from the profile, each of these accounts will register as separate for the creation of My Sites. Since Office can hook into a user's My Site as a default storage location, this can also cause confusion, as personal documents appear and disappear based upon which ID user is using to perform their activities.

Minimizing the pain:

Wherever possible, strive to make transitions instantaneous - at least as far as SharePoint is concerned. Don't let users access SharePoint with more than one of these accounts at a time. When the time comes, make use of the stsadm "migrateuser" operation as soon as possible, so that users don't get confused or accidentally start generating content under the new account before their old information is reassigned.

For admin/test situations, make sure there is a clear distinction in the users' minds about the purposes of each account. In addition, make sure the metadata in Active Directory correctly reflects which account will be used for day-to-day operations.

One Account, Multiple Users

Why it might happen:

The reasons for multiple users sharing an account typically revolve around cost savings in one form or another - either licensing or administrative.

A typical example might be in a "shop" situation, where one PC is on the floor, and once it is logged in, everyone just accesses the information they need.

Why this is a challenge:

Some of the challenges here are similar to those you might face in an Internet-facing, anonymous access, scenario. Essentially, when someone does something, you don't know who it was.

But there is an added complication. When you are authenticated, this triggers some things in SharePoint. For example, since you have an account, SharePoint will treat you as a named user for "Created by" information. But you can't use effectively use the "only their own" global list permission, or filter things by [Me], as everyone who shares the account will have that permission or see that information. Or on surveys that prevent multiple entries, only one person will be allowed to fill it in from that account. Discussion comments all appear to come from the same person.

Minimizing the pain:

By sharing a single account, you essentially remove the effectiveness "social" elements of SharePoint. Consider reducing confusion by turning off access to MySites and Personalization for the shared account. If you want to use interactive discussions, add a field for users to manually enter their names when posting, and make it a required field.

Frequently such shared resources are "read only". Consider simply allowing anonymous read-only access in those instances.

Another option is to enable a forms-based authentication zone for that group. This allows you to keep your AD clear of staff who otherwise don't use PC's, but still maintain individual control over SharePoint access, and monitor who is posting to writable areas.

Name's the Same, Different Domain

Why it might happen:

Unlike accounts within the same domain, which by definition must have unique IDs, it is possible for accounts in different domains to have the same "userID" part. For example, EMEA\SallieJo, AM\SallieJo, and APAC\SallieJo.

These may represent different users, or one user who travels. Sometimes organizations merge, and each already has their own Active Directory domain. Or for various reasons, your organization requires multiple domains on an ongoing basis. In some cases, this can be similar to "One User, Multiple Accounts". In fact, sometimes the situation is the same - accounts are held by the same user, and/or they are transitional. If this is the case, then the cautions mentioned in that section apply as well; but this situation presents its own unique challenges.

Why this is a challenge:

Here is where that "Behind the scenes" techie stuff I mentioned at the beginning comes into play. Essentially, when a user's web browser (Internet Explorer) and IIS (Internet Information Services) start negotiating authentication, only the UserID portion of their credentials, along with encrypted password information is sent from the client to the server. (SharePoint relies on IIS and the ASP.NET engine for authentication.)

Here's the problem - IIS usually assumes the user will be in the same domain as it is, and will try to match the ID with an account in that domain. Only if it doesn't find a match will it make a deeper query of Active Directory. If it finds an ID match, it will try to validate the encrypted password against the current domain. If the passwords match, no problem - or maybe big problem. SharePoint thinks IIS has authenticated the local user. If both accounts are really for the same person, you're OK. If it is a different user from the other domain, who just happened to have the same ID and password, they could actually be seeing the local user's information!

If the passwords don't match, unlike the situation when the UserID is different, IIS won't continue its search. It will just return a fatal error - typically a "500". (If the user is persistent, this also has the potential of locking out accounts in IIS' local domain.)

Note: This isn't an issue unique to SharePoint - you can encounter this problem with almost any system that requires NTLM pass-through authentication.

Minimizing the pain:

The best defense here is to make sure your user ID's are unique across all trusted domains accessing resources. Before initiating trusts, run reports and reconcile them, and set forest policies to prevent duplicates.

When duplicates exist for one or two users, a workaround for users in the remote domain is to assign your site to a specific zone (e.g. trusted sites) and configure Internet Explorer to always prompt for authentication in that zone.

image

If this is a problem for a large number of users, configuration changes at the server may be in order.

When the majority of your users are in a domain other than the one hosting SharePoint, you can configure IIS to use digest authentication and a different default realm. You can also extend SharePoint into multiple zones, and configure a different realm for each site in IIS. Then ensure that each domain's DNS points to the correct SharePoint zone.

image

Of course, if you change configurations - whether they be IE or AD, IIS or SharePoint - make sure you document them!


Sep-32009

Calculated Columns and SPD Workflow Part 2

MCj02317860000[1]In this two part series, I show you how to take advantage of SharePoint calculated columns in your SharePoint Designer workflows. Part 1 introduced calculated columns. Part 2 will describe several string manipulation functions, and show you how to consolidate these calculated columns into a "function library" of sorts.

Hide the Clutter

In part 1, I showed you how to use a calculated column to enhance a SharePoint Designer workflow. This is all well and good, but what if you have interim calculations? What if you need to do this manipulation on values entered by your user in the workflow initiation form?  Or maybe you have other types of information you don't want getting in the way of your users when they view the list.

This is where that "Function Library" I talked about comes into play. Technically, in SharePoint terms, it is actually a function list. We will create a list in SharePoint that contains not just the calculated columns, but "input" columns for the functions as well. We will then hide the list in SharePoint designer. Your workflows can still access it, but your users won't even know it is there.

Holiday for Strings

String manipulation is a great application for calculated columns.

One common workflow scenario is processing the items sent to an email-enabled list. Typically, you will want to parse the subject line to find some routing information. This information may take several forms, including:

  • The beginning of the subject up to a delimiter
  • The end of the subject following a delimiter
  • The information contained within a pair of delimiters
  • Everything except what is contained between a pair of delimiters

Of course, there are other possibilities, but these should be enough to illustrate the concept.

Building the List

We're going to create a list that supports all of the calculations described in the previous section. To start, of course, we need to create the list. (Remember, SharePoint Designer 2007 doesn't have the ability to create or edit the columns in a MOSS 2007/WSS 3.0 list, so we'll do this in the web UI.)

  1. From Site Actions, select "Create"
  2. From the Create page, select "Custom List"
  3. Give it the name TextFormulas. Since we're ultimately going to hid the list, don't show it on the QuickLaunch
    image
  4. Click Create

Now that we have a basic list, we need to create our input columns:

  1. Display the newly-created TextFormulas list.
  2. From the Settings toolbar, select List Settings
    image
  3. There is a "Title" column created by default. Click on it, change the name to "SourceString", and click OK.
    Note: This step isn't technically required, but it helps things make sense in the Workflow Designer
    image
  4. Click Create Column
  5. Enter "Delimiter1" for the Column Name.
  6. Make sure "Single line of text" is selected as the field type, and click OK.
    image
  7. Repeat steps 4-6, except use "Delimiter2" as the column name.

Once you have your input columns defined, you might think it is time to create your calculated columns. While you could, there is one more step you might want to perform. Because the output from string calculations isn't always obvious, it can be helpful to have some sample data to work with so you can see if the formulas are doing what you want them to.

Add an item to your list:

image

This item will give you all of the possibilities that we might want to work with - text before, after, within, and outside of, delimiters.

Now we're ready to create the calculated columns.

For the first column we just want the text to the left of the first delimiter. This has the simplest formula, but it isn't necessarily as obvious as you might think. The formula is "trim(left([SourceString],find([Delimiter1],[SourceString])-1))"

We're using three string functions: Trim(), Left(), and Find(). They're also "nested", meaning that we're calling one function from within another function.

The obvious function is "Left()". It takes two parameters, the string we want the left hand side of, and how much of the string we want. Unfortunately, since this is delimited rather than a fixed position, we need to "Find()" the position of the delimiter in the source string.

That's all well and good, but why are we then subtracting 1? That's because we would otherwise return the delimiter itself in our results. Find returns the position of the delimiter, and Left function expects a count of returned characters. Since we don't want the delimiter, we subtract 1 so that we get the position immediately before it.

The Trim() function gets rid of any leading and trailing spaces, as even if you don't see them, these can make comparisons fail.

Create your calculated columns in accordance with this table:

Column Name Formula
BeforeDelimiter1 trim(left([SourceString],find([Delimiter1],[SourceString])-1))
AfterDelimiter1 trim(right([SourceString],len([SourceString])-len([BeforeDelimiter1])-2)
BetweenDelimiters trim(left([AfterDelimiter1],find([Delimiter2],[AfterDelimiter1])-1))
AfterDelimiter2 trim(right([AfterDelimiter1],len([AfterDelimiter1])-len([BetweenDelimiters])-2)
OutsideDelimiters [BeforeDelimiter1]&" "&[AfterDelimiter2]

Notice that each formula builds on the one before it - we're using the results of some calculated columns as input to others. This helps us avoid the 8-deep function nesting limit, as well as the 1000 character formula length limit. It also makes them a lot easier to read!

Assuming the formulas are entered correctly, viewing your sample data item will give you these results:

image

While the value for "AfterDelimiter1" doesn't look very useful in and of itself, that is only because of the particular SourceString we are using. In this case, it is simply an interim value for deriving the BetweenDelimiters result. With a different SourceString it could be the final answer you are looking for. For example, you may have a simple two-part source with a single delimiter, such as "G131131|Memory Failure". That string, with just the pipe (|) as Delimiter1, will result in "Memory Failure" for the AfterDelimiter1 value.

Back to SharePoint Designer

Once you have your function list created, you can use it in your SharePoint Designer workflows.

For this example, we're going to create a workflow on an email-enabled Time Off list. When a new item arrives, we want to parse the subject line to get the reason for the absence and assign it to the reason field. The reason text follows a dash (-), so we're just going to use the "AfterDelimiter1" calculated value.

Note: You may need to enable email-based workflows with the following command before using this example: "stsadm -o setproperty -pn declarativeworkflowautostartonemailenabled -pv true" See this KB Article for details.

When you define your workflow, first check the "Automatically start this workflow when a new item is created box, as shown below:

image

Click Next.

From the Actions menu, select Create List Item. (Since the menu is built from recently used actions, you may need to select it from the "More Actions" dialog.) You will get a new line in the Actions block that looks like the one below. Click the "this list" link.

 image

Select the TextFormulas list from the dropdown:

image

The SourceString (*) field will already be chosen, as it is a required field. (This will be the "Title" field if you didn't rename it earlier.)

Click the "Modify..." button. You want to use the E-Mail Subject field from the current item as the source.

image

After you click OK, Click Add in the Create New List Item dialog, and add the Delimiter1 field. Enter the dash as the Value. When you click OK, the Create dialog should look like this:

 image

Click OK. Notice SPD automatically generates a variable called "Create" as the output of this function. That variable will hold the item ID for the formula item we create. This will be needed later.

A Pregnant Pause

The next action may seem a little odd. We're going to select the "Pause for Duration" action, and then set it to 0 days, 0 hours, and 0 minutes. The reason for this is that the calculations in our function list item don't take place instantaneously. If we were to try to grab the result as the next step, all we would get is an empty string. By telling our workflow to Pause, we give SharePoint a chance to catch up.

Note: Even though we set everything in the pause to zero, the workflow will wait until the next event cycle to continue. This delay may be a minute or so.

Back to Work

Once the workflow comes back from its coffee break, we need to get our value back.

  1. From the Actions menu, select Set Field in Current Item.
  2. Click the "field" link, and select Reason from the dropdown.
  3. Click the "value" link, then click the fx button that appears.
  4. Select TextFormulas for the Source, with the Field of AfterDelimiter1.

Now we need to tell the workflow how to find the row we want. Here's where that "create" variable comes into play.

  1. Select the TextFormulas:ID field from the Field dropdown
  2. Click the fx button beside the Value field.
  3. Select Workflow Data for the Source, and Varable: create for the Field
  4. If your lookup dialog looks like the one below, click OK
    image

The reason lookup should now look like the capture below:

image

Click OK.

Cleaning Up

Now it is time to clean up after ourselves.

Just as "real" SharePoint developers need to keep in mind the need to "dispose" objects they create once they are done with them, we need to delete the formula record we created now that we are done with it. Fortunately, SharePoint provides a "Delete Item" action item for us. Select it from the Actions menu, and click the "this list" link. As you might guess by now, we're going to use the same "create" variable as before to select the item to delete from the TextFormulas list.

image

Click OK, then click Finish in the Workflow Designer. SharePoint Designer will then validate the workflow and save it.

Covering our Tracks

Finally, as I mentioned way back at the beginning of this article, you may not want your users to readily see your formula list. Especially since the interim information will be hanging around during that pause. Although we suppressed the list from the Quick Launch when we created it, people can still see it from the "View All Site Content" link. To make it go away from there, we can take advantage of SharePoint Designer's ability to "hide" a list.

To hide a list, first open the Lists folder (you won't need this step for document libraries).

Right-click the list you want to hide and select Properties, as shown below:

image

Click the "General" tab. Click on the checkbox labeled "Hide from browsers".

Click OK

image

Now the list will be "invisible" via most normal ways of discovering SharePoint content. That is also why we waited until after the workflow was done in order to hide it. Although you can still see and work with hidden lists in most parts of SharePoint Designer, the function called by the Workflow Designer to enumerate lists is the same one used by the web interface, so you wouldn't be able to select it.

Conclusion

This second part took a bit longer to write than I expected. I hope you found it worth the wait!

In these two articles, I have showed you the power of SharePoint calculated columns, and how to use them in a SharePoint Designer workflow. In the process, I have introduced a number of other concepts, including:

  • String functions
  • Hidden lists
  • Email enabling lists
  • Using the output of one calculated column to feed another.
  • Workflow variables

Even so, I have barely scratched the surface. I encourage you to explore further the capabilities of calculated columns and SharePoint Designer workflows.