The Membership Data Store

10/10/2010 5:40:27 PM
The key membership feature is the ability of ASP.NET to store user credentials in a database. The idea is that you make a few choices about the information that will be stored and the security policy that will be used. From that point on, ASP.NET manages the user database for you—adding new user information, checking credentials when users try to log in, and so on.

Clearly, the membership data store has the ability to greatly reduce the amount of code you need to write. You can create a secure website with much less code and, hence, much less work. You also don't need to worry about inevitable bugs, because the ASP.NET membership module is a well-known, carefully tested component.

So, why wouldn't you want to use the membership data store? A few possible reasons exist:

You don't want to store your user data in a database:

In theory, you can store your user list in any type of data store, from an XML file to an Oracle database. Technically, each data store requires a different membership provider. However, ASP.NET includes only two providers—the SQL Server provider you'll use in this chapter and a provider for Active Directory. If you want to use another data store, such as a different relational database, you'll need to find a corresponding membership, or you'll need to forgo membership altogether.

You need backward compatibility:

If you've already created a table to store user information, it may be too much trouble to switch over to the membership data store. That's because the SQL Server membership provider expects a specific table structure. It won't work with existing tables, because they'll have a subtly different combination of fields and data types. And even if you don't need to keep the current table structure, you might find it's just too much work to re-create all your user records in the membership data store.

You want to manage user information in non-ASP.NET applications:

As you'll see in this chapter, ASP.NET gives you a powerful set of objects for interacting with membership data. For example, you can update user records, delete user records, retrieve user records based on certain criteria, and so on. You can even use the membership objects in other types of .NET applications (for example, you can create a Windows application to manage user accounts). However, if you're creating another application outside .NET that needs to perform these tasks, you might find it's not as easy, because you'll need to understand the membership table structure. In this case, you may find that it's easier to manage users with straight SQL statements that work with your own table.

If you decide not to use the membership data store, it's up to you to write ADO.NET code to retrieve user records and check user credentials.

Before continuing any further, you should set up your website to use forms authentication by adding the <forms> tag. Here's what you need to add:

<authentication mode="Forms" />

1. Membership with SQL Server Express

Assuming you do decide to use membership, you need to create the membership database. If you're using SQL Server Express (the free version of SQL Server that's included with Visual Studio), the task is a lot easier than you might expect. In fact, it all happens automatically.

By default, membership is enabled for every new website you create. The default membership provider makes the following assumptions:

  • You want to store your membership database using SQL Server Express.

  • SQL Server Express is installed on the current computer, with the instance name SQLEXPRESS. (Usually, you'll install SQL Server Express when you run the Visual Studio setup program.)

  • Your membership data store will be a file named aspnetdb.mdf, which will be stored in the App_Data subfolder in your web application directory.

These assumptions make a lot of sense. They allow you to create as many web applications as you want while still keeping the user databases separate. That's because each website will have its own aspnetdb.mdf file. These files are never registered in SQL Server, which means when you open a connection in another application, you won't see dozens of user databases. Instead, the only way to connect to them is to specify the file path in the connection string, which ASP.NET does.

Another advantage of this setup is that it's potentially easier to deploy your website. Assuming the web server where you'll deploy your application has SQL Server Express, you won't need to change the connection string. You also don't need to perform any extra steps to install the database—you simply copy the aspnetdb.mdf file with your website. This is clearly a great advantage for large web hosting companies, because it's otherwise quite complex to support multiple websites, each with its own custom database that needs to be installed and maintained.

To see how this works, it helps to create a new web project with a simple test page. Drag the CreateUserWizard control onto your page from the Login section of the Toolbox. Now run the page (shown in Figure 1), without adding any code or configuring the control.

Figure 1. The CreateUserWizard control

Fill in all the text boxes with user information. Note that by default you need to supply a password that includes at least one character that isn't a number or a letter (such as an underscore or an asterisk) and is at least seven characters long. Once you've filled in all the information, click Create User.

At this point, the CreateUserWizard control uses the ASP.NET Membership class behind the scenes to create a new user. The default membership provider creates the aspnetdb.mdf file (if it doesn't exist already) and then adds the new user record. Once this process is complete, the CreateUserWizard control shows a message informing you that the user was created. Miraculously, all of this takes place automatically even though you haven't configured anything in the web.config file and you didn't create the database file in advance.

To reassure yourself that the user really was created, you can check for the aspnetdb.mdf file. In the Solution Explorer, right-click the App_Data folder, and select Refresh Folder. You'll see the aspnetdb.mdf file appear immediately. Using Visual Studio, you can even dig into the contents of the aspnetdb.mdf file. To do so, double-click the file in the Solution Explorer. Visual Studio will configure a new connection and add it to the Server Explorer on the left. Using the Server Explorer, you can roam freely through the database, examining its tables and stored procedures. (Remember, the Server Explorer window is called Database Explorer in Visual Studio Web Developer Express, even though the window works the same way.)

You can check the aspnet_Users table to find the user record you created. Just right-click the table name, and choose Show Table Data. You'll see something like the record shown in Figure 2. Among other details, you'll find a randomly generated GUID that uniquely identifies the user and the date the user last used your web application. You won't see the password and password question—that's stored in a linked record in the aspnet_Membership table, and it's encrypted to prevent casual snooping.

Figure 2. A user record in the aspnetdb.mdf database


At first glance, you'll find the membership database includes a dizzying number of tables.

Before diving into the rest of ASP.NET's membership features in detail, it's important to consider what you should do if you don't want the default membership data store. For example, you might decide to store your membership tables in a different database, or you might want to configure one of the many options for the membership provider. You'll learn how to do so in the next two sections.

2. Using the Full Version of SQL Server

If you're using the automatically generated database for SQL Server Express, you don't need to touch the web.config file. In any other case, you'll need to do a bit of configuration tweaking.

The simplest case is if you're using the full version of SQL Server. In this case, you can still use the default membership settings. However, you need to change the connection string.

The default membership settings and local connection string are set in the machine.config file. You can take a look at this file (and even edit it to update the settings for all web applications on your computer). Look in the c:\Windows\Microsoft.NET\Framework\[Version[\Config directory, where [Version] is the version of ASP.NET that's installed, such as v4.0.30319. Or, if you're configuring a deployed web application using IIS on a 64-bit operating system, look in the c:\Windows\Microsoft.NET\Framework64\[Version[\Config directory.

The default connection string that's used with membership is named LocalSqlServer. You can edit this setting directly in the machine.config. However, if you just need to tweak it for a single application, it's better to adjust the web.config file for your web application. First, you need to remove all the existing connection strings using the <clear> element. Then, add the LocalSqlServer connection string—but this time with the right value:

<clear />
<add name="LocalSqlServer" providerName="System.Data.SqlClient"
connectionString="Data Source=localhost;Integrated Security=SSPI;
Initial Catalog=aspnetdb" />

This <connectionStrings> section removes all connection strings and then creates a new connection string. This new connection string connects to a database named aspnetdb on the local computer. The only catch is that the aspnetdb database won't be created automatically. Instead, you'll need to generate it with the aspnet_regsql.exe command-line tool. Rather than hunt around for this file, the easiest way to launch it is to fire up the Visual Studio command prompt (open the Start menu and choose All Programs => Microsoft Visual Studio 2010 => Visual Studio Tools => Visual Studio Command Prompt). You can then type in commands that use aspnet_regsql.

You can use aspnet_regsql in two ways. If you use it without adding any command-line parameters, a Windows wizard will appear that leads you through the process. You'll be asked to supply the connection information for your database server. The database will be named aspnetdb, which is the recommended default.

Your other option is to specify exactly what you want to happen using command-line switches. This is particularly useful when deploying your application—you can use aspnet_regsql as part of a setup batch file, which will then create the membership data store automatically. This is the option you'll use if you want to choose the database name or if you want to install only some of the database tables. By default, the aspnet_regsql tool installs tables that can be used for user authentication, role-based authorization, profiles, and Web Parts personalization. This gives you maximum flexibility, but you may feel it's overkill if you aren't planning to use some of these features.

Table 1 describes the most important command-line options. Here's an example command line that connects to an unnamed SQL Server instance on the current computer (using the -S parameter), connects with the current Windows account (using the -E parameter), installs all tables (using the -A all parameter), and places them all in a database named aspnetdb (which is the default):

aspnet_regsql -S (local) -E -A all

If you want to use a different database, you must specify the database name using the -d parameter.

It's a good idea to install all the tables at once (using the –A all option). This way, your database will be ready for the profile feature discussed in the next chapter. Once you've finished testing your application and you're ready to create the final database, you can create a database that only has the options you've decided to use. (For example, use –A mr to use membership and role management but nothing else.)

Table 1. Command-Line Switches for aspnet_regsql.exe
-S ServerNameSpecifies the location of the SQL Server instance where you want to install the database.
-EConnects to the server through Windows authentication, using the currently logged-in Windows account.
-U UserName and -P PasswordSpecify the user name and password you need to connect to the SQL Server database. Usually, you'll use -E instead.
-ASpecifies the features you want to use (and determines the database tables that are created). Valid options for this switch are all, m (membership), r (role-based security), p (profiles), c (Web Part personalization), and w (for database cache dependencies with SQL Server 2000).
-RRemoves the databases that support the features specified by the -A switch.
-d DatabaseNameAllows you to specify the name of the database in which the tables will be created. If you don't specify this parameter, a database named aspnetdb is created automatically.
-sqlexportonlyCreates SQL scripts for adding or removing the specified features to the database, but doesn't actually create the tables in the database. Instead, you can run the script afterward. This can be a useful technique when deploying your application.


If you're deploying your website to a web hosting company, you probably won't be allowed to run aspnet_regsql on the web server. Instead, you'll probably need to use SQL Server Express. In this case, your database will be deployed in the App_Data folder as part of your web application, and no extra configuration steps will be required. If your web host doesn't support SQL Server Express, you'll need to use a tool like SQL Server Management Studio to prepare a .sql script file that installs your database. The administrators at the web hosting company can then run your script file to create the database you need.

3. Configuring the Membership Provider

Configuring the connection string is the simplest change you can make when setting up the membership data store. However, you may also want to tweak other membership settings. For example, you can change the default password policy.


As with the connection string, the default membership provider is defined in the machine.config file. You can edit the machine.config file to change these defaults for all applications on the computer, but you shouldn't, because it will complicate your life when you deploy the application. Instead, you should make the changes by configuring a new membership provider in your application's web.config file.

To configure your membership provider, you need to add the <membership> element to your web application. Inside the <membership> element, you define a new membership provider with your custom settings. Then, you set the defaultProvider attribute of the <membership> element so it refers to your membership provider by name.

Here's the basic structure you need to follow:

<membership defaultProvider="MyMembershipProvider">
<!-- Clear any existing providers. -->
<clear />

<!-- Define your provider, with custom settings. -->
<add name="MyMembershipProvider" ... />

Of course, the interesting part is the attributes you use in the <add> tag to configure your membership provider. Here's an example that defines a membership provider with relaxed password settings. The first three attributes supply required settings (the name, type, and connection string for the membership provider). The remaining settings remove the requirement for a security question and allow a password to be as short as one character and contain only letters and numbers:

<membership defaultProvider="MyMembershipProvider">
minRequiredNonalphanumericCharacters="0" />

Table 2 describes the most commonly used membership settings.

Table 2. Attributes for Configuring a Membership Provider
name[]Specifies a name for the membership provider. You can choose any name you want. This is the name you use later to reference the provider (for example, when you set the defaultProvider attribute). You can also use it to get provider information programmatically.
type[]Specifies the type of membership provider. In this chapter, you will always be using the System.Web.Security.SqlMembershipProvider. ASP.NET also includes an ActiveDirectoryMembershipProvider, which allows you to use the membership features with Windows authentication through an Active Directory server. (For more information on this topic, consult the Visual Studio Help.) Finally, you can use a custom membership provider that you or a third-party developer creates.
applicationNameSpecifies the name of the web application. This setting is primarily useful if you have several web applications using the same membership database. If you give each one a separate application name, all the information (including user, profiles, and so on) is completely separated so it's usable only in the appropriate application.
connectionStringName[]Specifies the name of the connection string setting. This must correspond to a connection string defined in the <connectionStrings> section of web.config or machine.config.
descriptionAllows an optional description for the membership provider.
passwordFormatSets the way passwords are stored in the database. You can use Clear (passwords are stored as is, with no encryption), Encrypted (passwords are encrypted using a computer-specific key), or Hashed (passwords are hashed, and the hash value is stored in the database). Hashing passwords offers similar protection to encrypting them (namely, if you look at the hash you'll have a difficult time reverse-engineering the password). However, when passwords are hashed, they can never be retrieved—only reset.
minRequiredPasswordLengthSpecifies the minimum length of a password. If the user enters fewer characters when creating an account, the attempt will be rejected with an error message.
minRequiredNonalphanumericCharactersSpecifies the number of nonalphanumeric characters (characters other than numbers and letters) the password needs to have. If the user enters fewer of these characters when creating an account, the attempt will be rejected with an error message. Although requiring nonalphanumeric characters makes for stronger (less guessable) passwords, it also can confuse users, causing them to forget their passwords more often or (worse) write them down in a conspicuous place, where they might be stolen.
maxInvalidPasswordAttemptsSpecifies the number of times a user is allowed to enter an invalid password for their login before the user account is locked and made inaccessible. The default is 5 attempts.
passwordAttemptWindowSets the internal time in which maxInvalidPasswordAttempts is measured. For example, if you set a window of 30 minutes, after 30 minutes the number of invalid password attempts is reset. If the user surpasses the maxInvalidPasswordAttempts within passwordAttemptWindow, the account is locked.
enablePasswordResetDetermines whether a password can be reset, which is useful if a password is forgotten.
enablePasswordRetrievalDetermines whether a password can be requested (and e-mailed to the user), which is useful if a user forgets a password. This feature is never supported if passwordFormat is set to Hashed, because the password isn't stored in that case.
requiresQuestionAndAnswerDetermines whether the membership security answer will be required when you request or reset a user password.
requiresUniqueEmailIf false, allows more than one user to have the same e-mail address. The e-mail address information is always optional. (However, the CreateUserWizard control requires an email address unless you set RequireEmail to False.)

[] This setting is required.

Now that you've seen the settings you can tweak, it's worth asking what the defaults are. If you look at the <membership> section in the machine.config file, here's what you'll find:

<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider ..."
passwordAttemptWindow="10" />

As you can see, the default membership provider is AspNetSqlMembershipProvider. It connects using the LocalSqlServer connection string and supports password resets but not password retrieval. Accounts require a security question but not a unique e-mail. The passwords themselves are hashed in the database for security, so they can't be retrieved. Passwords must be at least seven characters long with at least one nonalphanumeric character. Finally, if a user makes five invalid password attempts in ten minutes, the account is disabled.

4. Creating Users with the WAT

Once you've created the membership data store and (optionally) configured the membership provider, you're ready to use membership-backed security in your web application. As you've already seen, you can create new users with the CreateUserWizard control. You'll consider the CreateUserWizard control and the other security controls later in this chapter. First, it's worth considering your other options for setting up your user list.

One option is to use the WAT. Choose Website => ASP.NET Configuration to launch this tool. Next, click the Security tab. In the bottom-left corner, a box indicates how many users are currently in the database (see Figure 3). This box also provides links that allow you to examine the existing user records or add new ones.

Figure 3. Managing website security with the WAT

If you want to browse the current user list or update an existing user record, click the Manage Users link. To add new users, click Create User. You'll see a set of controls that are similar to the CreateUserWizard control used in the test page earlier (see Figure 4). After you've created a few users, you may want to take another look at the aspnet_Users and aspnet_Membership tables in your database to see what the user records look like.

Figure 4. Creating a new user

Although the WAT is a perfectly sensible way to add user records, you might find the web interface is a little sluggish if you have a large number of users to create. Another option is to use the Membership class, as shown here:

' Create a user record based with user name, password, and e-mail information.
Membership.CreateUser(userName, password, email)

Here's an example with hard-coded values:

Membership.CreateUser("joes", "ignreto12__", "")

This creates a new user with just a single line of code. Of course, the CreateUser() method has multiple overloads, which you can use to supply details such as the password question and answer. If you haven't changed the default membership settings, you won't be able to create an account unless you provide these details. Instead, you'll need to use this more complex overload:

Dim createStatus As MembershipCreateStatus
Membership.CreateUser("joes", "ignreto12__", "", _
"What is your favorite restaurant?", "Saigon", True, createStatus)

The first few parameters are self-explanatory—they take the user name, password, e-mail address, password question, and password answer. The second-to-last parameter takes a Boolean value that determines whether the account is given the IsApproved flag. If you supply False, the account won't be approved, and so it won't be active (and usable) until you modify it using the Membership.UpdateUser() method. In the simpler overload that doesn't include this parameter, accounts are always marked as approved.

The last parameter returns a value from the MembershipCreateStatus enumeration. If this value isn't MembershipCreateStatus.Success, an error occurred when creating the record. The value indicates the exact error condition (for example, a password that wasn't strong enough, a duplicate e-mail address when your membership provider doesn't allow duplicates, and so on). In the simpler overload that doesn't include the MembershipCreateStatus, any error results in an exception object being thrown that has the same information.

Clearly, if you needed to transfer a large number of user accounts from a custom database into the membership data store, the quickest option would be to write a routine that loops through the existing records and use the CreateUser() method to insert the new ones.

5. The Membership and MembershipUser Classes

There wouldn't be much point to using the membership data store if you still needed to write handcrafted ADO.NET code to retrieve or modify user information. That's why ASP.NET offers a more convenient, higher-level model with the Membership class.

Membership is a useful class that's full of practical shared methods such as CreateUser(). You can find it in the System.Web.Security namespace. Table 3 provides a snapshot of its most useful shared methods.

Table 3. Membership Methods
CreateUser()Adds a new user to the database.
DeleteUser()Deletes an existing user from the database. You specify the user by the user name. You can also choose whether you want to delete all related data in other tables (the default is to remove it).
UpdateUser()Updates the database with new information for a specific user.
GetUser()Gets a specific user from the database, by user name.
GetUserNameByEmail()Retrieves a user name for the user that matches a given e-mail address. Keep in mind that duplicate e-mail addresses are allowed by default, in which case this method will find only the first match.
FindUsersByName()Gets users from the membership database that match a given user name. This supports partial matches, so User will match TestUser, User001, and so on.
FindUsersByEmail()Gets users from the membership database that match a specific e-mail address. You can also supply part of an e-mail address (such as the domain name), in which case you'll get every user who has an e-mail address that contains this text.
GetAllUsers()Gets a collection that represents all the users in the database. An overloaded version of this method allows you to get just a portion of the full user list (a single page of users, based on a starting index and length).
GetNumberOfUsersOnline()Gets the number of logged-in users currently accessing an application. This calculation assumes a user is online if that user's last activity time stamp falls within a set time limit (such as 20 minutes).
GeneratePassword()Generates a random password of the specified length. This is useful when programmatically creating new user records.
ValidateUser()Check whether the supplied user name and password exist in the database. You can use this method to write your authentication logic in the login page.

The Membership class also provides shared read-only properties that let you retrieve information about the configuration of your membership provider, as set in the configuration file. For example, you can retrieve the required password length, the maximum number of password attempts, and all the other details described in Table 20-2.

Many of these methods use the MembershipUser class, which represents a user record. For example, when you call GetUser(), you receive the information as a MembershipUser object. If you want to update that user, you can change its properties and then call Membership.UpdateUser() with the modified MembershipUser object.


The MembershipUser object combines the details from the aspnet_Users table and the linked aspnet_Membership table. For example, it includes the password question. However, the password answer and the password itself aren't available.

The MembershipUser class also provides its own smaller set of instance methods. The most important ones are detailed in Table 4.

Table 4. Membership User Methods
UnlockUser()Reactivates a user account that was locked out for too many invalid login attempts.
GetPassword()Retrieves a user password. If requiresQuestionAndAnswer is true in the membership configuration (which is the default), you must supply the answer to the password question in order to retrieve a password. Note that this method won't work at all if the passwordFormat setting is Hashed or if enablePasswordRetrieval is set to false, which is also the default.
ResetPassword()Resets a user password using a new, randomly generated password, which this method returns. If requiresQuestionAndAnswer is true in the membership configuration (which is the default), you must supply the answer to the password question in order to reset a password. You can display the new password for the user or send it in an e-mail.
ChangePassword()Changes a user password. You must supply the current password in order to apply a new one.
ChangePasswordQuestionAndAnswer()Changes a user password question and answer. You must supply the current password in order to change the security question.

To get a sense of how the Membership class works, you can create a simple test page that displays a list of all the users in the membership database. Figure 5 shows this page.

Figure 5. Getting a list of users

To create this page, you simply need to begin by defining the GridView. The GridView will show a list of MembershipUser objects. For each user, it shows the values from the UserName and Email properties, along with a Select link. Here's the markup that creates the GridView (without the formatting details):

<asp:GridView ID="gridUsers" runat="server"
AutoGenerateColumns="False" DataKeyNames="UserName" >
<asp:BoundField DataField="UserName" HeaderText="User Name" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:CommandField ShowSelectButton="True" />

When the page is first loaded, it calls the Membership.GetAllUsers() method and binds the results to the GridView, as shown here:

Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load

gridUsers.DataSource = Membership.GetAllUsers()
End Sub

To make the example more interesting, when a record is selected, the corresponding MembershipUser object is retrieved. This object is then added to a collection so it can be bound to the DetailsView for automatic display:

Protected Sub gridUsers_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles gridUsers.SelectedIndexChanged

Dim list As New List(Of MembershipUser)()
detailsUser.DataSource = list
End Sub

Here's the DetailsView that does the work (again, without the formatting details):

<asp:DetailsView ID="detailsUser" runat="server"></asp:DetailsView>

This DetailsView uses automatic row creation (because AutoGenerateRows defaults to True). As a result, the DetailsView shows all the MembershipUser properties.

Figure 6 shows the information that's available in a single record. Among other details, you can use the MembershipUser object to check whether a user is online, when they last accessed the system, and what their e-mail address is.

Figure 6. The information in a MembershipUser object

6. Authentication with Membership

Now that you've switched to membership, and all your users are stored in the membership data store, you need to change the way your login page works. Life now gets a lot simpler—rather than create ADO.NET objects to query a database and see whether a matching user record exists, you can let the Membership class perform all the work for you. The method you need is Membership.ValidateUser(). It takes a user name and password and returns True if there's a valid match in the database.

Here's the new code you need in your login page:

Protected Sub cmdLogin_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdLogin.Click

If Membership.ValidateUser(txtName.Text, txtPassword.Text) Then
FormsAuthentication.RedirectFromLoginPage(txtName.Text, False)
lblStatus.Text = "Invalid username or password."
End If
End Sub

Actually, a fair bit of work is taking place behind the scenes. If you're using the default membership provider settings, passwords are hashed. That means when you call ValidateUser(), ASP.NET hashes the newly supplied password using the same hashing algorithm and then compares it to the hashed password that's stored in the database.

7. Disabled Accounts

An account can become disabled in the membership database in two ways:

The account isn't approved:

This occurs if you create an account programmatically and supply False for the isApproved parameter. You might take this step if you want to create an account automatically but allow an administrator to review it before it becomes live. To make this account active, you need to get a MembershipUser object for the corresponding user record, set MembershipUser.IsApproved to True, and call Membership.UpdateUser().

The account is locked out:

This occurs if the user makes multiple attempts to access a user account with an invalid password. In this case, you need to get a MembershipUser object for the user, and call MembershipUser.UnlockUser(). You may also want to call MembershipUser.ResetPassword() to prevent another lockout.

To help you with these tasks, you might want to create an administrative page like the one shown in Figure 20-6. For example, you can allow a user to review all accounts that aren't yet approved and approve them by clicking a button.

Similarly, if you want to disable an account at any time, you can retrieve a MembershipUser object for that user and set the IsApproved property to False. However, you have no way to programmatically lock a user account.

You're probably already thinking of a wide range of pages you can create using the Membership and MembershipUser classes. For example, you can build pages that allow users to request a password reset or check whether they are locked out. However, you might not need to create all these pages, because ASP.NET includes a rich set of security controls that automate many common tasks. You'll learn more about the security controls in the next section.

Most View
AMD Trinity the Chip to Take down Core i3? (Part 1)
Late 2012 Razer Blade - One Of The Luxurious Laptops (Part 4)
Installing Configuration Manager 2007 : Site Installation (part 4) - Installing Site Systems
Motorola RAZR i - How Does The Droid RAZR M Fare With A 2Ghz Intel Processor? (Part 2)
EVGA Z77 Stinger - A New Mini-ITX Motherboard
It's Not Finished Yet!
Troubleshoot Projector Problems
SQL Server 2008 : Mirroring in action (part 1) - Mirroring setup
BlackBerry Bold 9700 and 9650 Series : Connecting with Bluetooth (part 1) - Using Bluetooth on Your BlackBerry, Pairing Your BlackBerry with a Bluetooth Device
Visual Studio Team System 2008 : Command Line (part 2)
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered