Manually Migrating Users (3.3.5 -> 4.4.1) 

It is possible to copy users from a DNN 3.x installation to a DNN 4.x installation manually and this article will explain the processs needed to complete this task. Please note there are a number of assumptions and requirements listed below, please TAKE all of them seriously as making modifications to your database can have tragic effects. Also, all scripts listed here are in their inital stages, they do NOT handle conflict items such as duplicate user accounts or anything of that nature, therefore it is assumed that you are loading all users into a blank 4.x instllation.

Setup Requirements

To successfully copy users from 3.x -> 4.x following the below tutorial you must ensure that the following items are complete in your configuration. First you must ensure that the validation and decryption keys are the same for both applications. Secondly you must know the application name for your 4.x installation. Lastly you must have both databases on the same server, you can transfer data cross server, however that is outside of the scope of this article.

All examples below are showing a conversion from 3.3.5 -> 4.4.1 with databse names of dnn335 and dnn441. Prior to following the steps below you should make backup copies of BOTH databases. REMEMBER, there are many points for potential failure by performing these actions and I am NOT responsible for any data loss or corruption you may encounter while trying to perform this data copy

NOTE REGARDING BELOW SQL: All SQL Examples include full database names based on the dnn335 and dnn441 database names. You MUST change these names to reflect your databse names for these scripts to work successfully.

The Process

Once you have validated that your environment is setup in a manner that will allow you to follow this process it is time to get started. First we need to find the applicationid for the new DNN installation. To do this run the following script replacing 'DotNetNuke' with your application name. (by default DotNetNuke is the value set).

SELECT ApplicationId
FROM dnn441.dbo.aspnet_applications
WHERE ApplicationName 'DotNetNuke'

Now that you have noted your ApplicationId it is time to start the data copies. We will first move the records from the aspnet_users table, when we move our records we will NOT be moving any records for the host or admin accounts to avoid any potential conflicts with accounts.  Below is the query used to copy the users records from our dnn335 database to the dnn441 database. 

NOTE: you will need to change the ApplicationId value that is hard coded in the query to be that of your application, which you researched above.

INSERT INTO dnn441.dbo.aspnet_users (ApplicationId, UserId, username, 
                                        LoweredUsername, IsAnonymous, LastActivityDate)
SELECT 'E3AD66EA-58E6-46A5-AC80-0904A9FB8E4D' as "ApplicationId", userid, username, 
        loweredusername, IsAnonymous, lastActivityDate
FROM dnn335.dbo.aspnet_users
WHERE username NOT LIKE 'Host' AND username NOT LIKE 'admin'

The next step of the process is to copy over all aspnet_membership information for the users. The information contained in the membership table is what controls the users ability to login to the site, including password and password salt values. Below is the script needed to copy the user accounts.

NOTE: As with the last script be sure to change the hard set ApplicationId value to the value you found for your application.

--Insert Statement to place new records into the DNN 44l aspnet_membership table
INSERT INTO dnn441.dbo.aspnet_membership(applicationid, userid, [password], PasswordFormat,
                PasswordSalt, Email, LoweredEmail, isApproved, isLockedOut, CreateDate,
                LastLoginDate, LastPasswordChangedDate, lastLockoutDate, FailedPasswordAttemptCount,
                FailedPasswordAttemptWindowStart, FailedPasswordAnswerAttemptCount, 
                FailedPasswordAnswerAttemptWindowStart, Comment)
SELECT 'E3AD66EA-58E6-46A5-AC80-0904A9FB8E4D', u.userid, m.[password], m.passwordformat,
        m.PasswordSalt, m.Email, m.LoweredEmail, m.isApproved, m.islockedout, m.createdate,
        m.LastLoginDate, m.lastPasswordChangedDate, m.lastLockoutDate, m.FailedPasswordAttemptCount,
        m.FailedPasswordAttemptWindowStart, m.FailedPasswordAnswerAttemptCount,
        m.FailedPasswordAnswerAttemptWindowStart, m.comment
FROM dnn335.dbo.aspnet_users u
    
INNER JOIN dnn335.dbo.aspnet_membership m
        
ON (u.userid m.userid)
WHERE u.username NOT LIKE 'Host' AND username NOT LIKE 'admin'

Next we will want to copy over any profile information that might have been stored for the users in the aspnet_profile table. Below is a script to copy over all profile information.

--Script to copy over any potential user profile information stored for a user
INSERT INTO dnn441.dbo.aspnet_profile (UserId, PropertyNames, PropertyValuesString,
                                        PropertyValuesBinary, LastUpdatedDate)
SELECT u.UserId, PropertyNames, PropertyValuesString, PropertyValuesBinary, LastUpdatedDate
FROM dnn335.dbo.aspnet_profile p
    
INNER JOIN dnn335.dbo.aspnet_users u
        
ON (p.userid u.userid)
WHERE u.username NOT LIKE 'Host' AND u.username NOT LIKE 'admin'

The next step is to copy over the DNN user information. This query is a bit more complicated than you would expect. The reason for this is a tendency for older versions of DNN to not correctly remove user accounts. To ensure that we ONLY copy over active user accounts we will perform a join to the aspnet_users table this way we only copy over user accounts that have all needed supporting information. Also we will be setting the database to temporarily allow for IDENTITY_INSERT which will allow us to insert records into an identity field. NOTE: This requires that there be NO additional accounts other than host and admin in your new portal, if there are more user accounts this step of the process could fail.

--Script to copy over all DNN user table information!
SET IDENTITY_INSERT dnn441.dbo.users ON

INSERT INTO 
dnn441.dbo.users (UserId, UserName, FirstName, LastName, IsSuperUser,
                                AffiliateId, Email, DisplayName, UpdatePassword)
SELECT dnnu.UserId, dnnu.username, dnnu.firstname, dnnu.lastname, 
        dnnu.isSuperuser, dnnu.AffiliateId, dnnu.Email, dnnu.DisplayName, 
        dnnu.UpdatePassword
FROM dnn335.dbo.users dnnu
    
INNER JOIN dnn335.dbo.aspnet_users u
        
ON (dnnu.username u.username)
WHERE u.username NOT LIKE 'Host' AND u.username NOT LIKE 'admin'

SET IDENTITY_INSERT dnn441.dbo.users OFF

The final step is to copy over the UserPortal table. This is the table that maps a users permission to a specific portal. Since your setup currently only has one portal, I will be defaulting the script to automatically set users to only access your primary portal. If you have other portals or needs you will need to modify this query. As with the last query this will have a few joins in it to ensure that we only have good records for users.  This script is another where we will need to temporarily turn on IDENTITY_INSERT as we will be inputting information into an identity field.

--Script to copy over the user portal information
SET IDENTITY_INSERT dnn441.dbo.userportals ON

INSERT INTO 
dnn441.dbo.userportals (UserId, PortalId, UserPortalId, CreatedDate, Authorised)
SELECT up.userid, as "PortalId", up.UserPortalId, up.createdDate, up.Authorised
FROM dnn335.dbo.userportals up
    
INNER JOIN dnn335.dbo.users dnnu
        
ON (up.userid dnnu.userid)
    
INNER JOIN dnn335.dbo.aspnet_users u
        
ON (dnnu.username u.username)
WHERE u.username NOT LIKE 'Host' AND u.username NOT LIKE 'admin'

SET IDENTITY_INSERT dnn441.dbo.userportals OFF

Testing the Transfer

To test the data transfer you can simply try to login with one of your existing user accounts. You should be able to login without any difficulties using the same password as you did on the old portal.

Final Thoughts

This tutorial provides you a method to copy user accounts over from a 3.3.5 installation to a 4.4.1 installation. This only covers the basics of moving the root accounts into a clean portal. To perform more detailed moves with regard to multiple portals etc additional thought will need to take place when migrating user data.

Please leave your feedback below, if you have any requests for assistance please visit my forums where I will gladly respond to any questions.

Posted by Mitchel on Sunday, March 04, 2007
 

Comments

When running your scripts for migrating users from DNN 322 to DNN 441, this part gives an error:

INSERT INTO dnn441.dbo.aspnet_users (ApplicationId, UserId, username,
LoweredUsername, IsAnonymous, LastActivityDate)
SELECT '73FAFC1C-B2B5-497E-8868-F4B4C8412E8E' as "ApplicationId", userid, username,
loweredusername, IsAnonymous, lastActivityDate
FROM dnn322.dbo.aspnet_users
WHERE username NOT LIKE 'Host' AND username NOT LIKE 'admin'

The error is as follows:
Server: Msg 2601, Level 14, State 3, Line 1
Cannot insert duplicate key row in object 'aspnet_Users' with unique index 'aspnet_Users_Index'.
The statement has been terminated.

Roy...

By Roy M. Halvorsen on Monday, March 05, 2007 at 7:19 PM

Roy,

It appears you have a conflict on usernames....try the below query, as it will prevent duplicates from being introduced.

INSERT INTO dnn441.dbo.aspnet_users (ApplicationId, UserId, username,
LoweredUsername, IsAnonymous, LastActivityDate)
SELECT '73FAFC1C-B2B5-497E-8868-F4B4C8412E8E' as "ApplicationId", userid, username,
loweredusername, IsAnonymous, lastActivityDate
FROM dnn335.dbo.aspnet_users
WHERE username NOT LIKE 'Host'
AND username NOT LIKE 'admin'
AND userid NOT IN (SELECT DISTINCT userid
FROM dnn441.dbo.aspnet_users)

I will update this posting tonight to include this update

By mitchel.sellers@gmail.com on Tuesday, March 06, 2007 at 9:42 AM

Mitchel,
There also some errors showing up running "--Script to copy over all DNN user table information!":
Server: Msg 207, Level 16, State 3, Line 3
Invalid column name 'DisplayName'.
Server: Msg 207, Level 16, State 1, Line 3
Invalid column name 'UpdatePassword'.
Server: Msg 209, Level 16, State 1, Line 3
Ambiguous column name 'UserName'.

And the last one "--Script to copy over the user portal information":
Server: Msg 207, Level 16, State 3, Line 3
Invalid column name 'Authorised'.
Server: Msg 209, Level 16, State 1, Line 3
Ambiguous column name 'UserName'.

I'm trying to figure out what the problem is...

By Roy on Wednesday, March 07, 2007 at 4:08 PM

Roy,

You can simply remove those columns from the individual queries....

By mitchel.sellers@gmail.com on Wednesday, March 07, 2007 at 4:09 PM

Here is the last modification I did. Now I was able to copy more than 1000 users from a DNN322 installation to a DNN441 installation :)
Thanks a lot for the help, Mitchel !!

By Roy on Wednesday, March 07, 2007 at 4:34 PM

Here's my modofications:
SET IDENTITY_INSERT dnn441.dbo.users ON

INSERT INTO dnn441.dbo.users (UserId, Username, FirstName, LastName, IsSuperUser,
AffiliateId, Email, DisplayName, UpdatePassword)
SELECT dnnu.UserId, dnnu.Username, dnnu.firstname, dnnu.lastname,
dnnu.isSuperuser, dnnu.AffiliateId, dnnu.Email, dnnu.firstname + ' ' + dnnu.lastname as DisplayName,0
FROM dnn335.dbo.users dnnu
INNER JOIN dnn335.dbo.aspnet_users u
ON (dnnu.username = u.username)
WHERE u.username NOT LIKE 'Host' AND u.username NOT LIKE 'admin'

SET IDENTITY_INSERT dnn441.dbo.users OFF


SET IDENTITY_INSERT dnn441.dbo.userportals ON

INSERT INTO dnn441.dbo.userportals (UserId, PortalId, UserPortalId, CreatedDate, Authorised)
SELECT up.userid, 0 as "PortalId", up.UserPortalId, up.createdDate, 1
FROM dnn335.dbo.userportals up
INNER JOIN dnn335.dbo.users dnnu
ON (up.userid = dnnu.userid)
INNER JOIN dnn335.dbo.aspnet_users u
ON (dnnu.username = u.username)
WHERE u.username NOT LIKE 'Host' AND u.username NOT LIKE 'admin'

SET IDENTITY_INSERT dnn441.dbo.userportals OFF

By Roy on Wednesday, March 07, 2007 at 4:34 PM

Mitchel,
unfortunately no users can log in to the new 441 site. I also tried to send password, but it failed. Seems like we're missing something...

By Roy on Wednesday, March 07, 2007 at 4:35 PM

Roy,

Do you have the same validation key in your 4.4.1 installation?

If you do not, you will need to change it to the same as was used in 3.2.2. Otherwise you can try to reset the password for one of the newly copied accounts using a password from an existing working user.

I know there have been a few problems as it appears between 3.2.2 and 3.3.5 they changed some of the user information....

Another idea is to compare data values for a known working user and a known broken user to see if there are any fields with nulls that might be causing issues.

By mitchel.sellers@gmail.com on Wednesday, March 07, 2007 at 4:37 PM
Click here to post a comment

Donate

Show your appreciation for the content/modules made available by MitchelSellers.com by making a donation. Donations are used to assist with dedicating time to creating free content.