What about Desktop and Favorites migration? Wouldn’t it be nice if there was a GPO that made the migration of your user’s Desktop and Favorites as easy as the migration of their My Documents? I think it would be nice. Since there isn’t, I created a script that would do the migration. This script should be run following a successful My Documents migration as the goal would be to put the files in the same location as the My Documents files.
When I first started the project, I was hoping that my script would run prior to showing the desktop. This is important because if it runs while the user has access to the desktop, that user may start using files that would prevent the script from running correctly (file locks). I had no luck; if anyone has an idea on how to do this, let me know. Otherwise, I created a .NET application that covers the entire screen on the primary monitor (if more than 1 monitor, then the second one is still visible).
BlankScreen
The BlankScreen application is written in VisualStudio .NET 2008 using .NET Framework 2.0 if I remember correctly. There are some changes you may want to make on this application to tailor it for your environment. The first change would be to put your logo on the application form. The second change, and really the more important change, is to change the ProcessPath variable to point to the UNC path of where you plan on putting the desktop.vbs file. This application just runs the VBScript.
So you might be thinking, why would you have an application that is capable of much more advanced programming run a VBScript? Well, I wrote the script first and didn’t feel like porting it to VB.NET. If you feel like spending the time, go for it.
desktop.vbs
Enough chatter about the other stuff, on to the real product of this blog post, the VBScript.
The VBScript has four basic functions that it completes one after the other based on the success of the previous function. Step 1 is to get the username of the logged in user. Step 2 is to create the folders in the user’s My Documents location and copy the files into that new folders (nothing is moved). Step 3 is to update the registry for the Desktop and Favorites locations to the newly created folders. Step 4 renames the old folders in the C:\Documents and Settings\[user]\ folder to DesktopOLD and FavoritesOLD. I feared losing user files, so I did not make the script perform anything that couldn’t be reversed.
Just as you had to change a string variable in the BlankScreen application for your specific server, you also have to change the location of your user’s folder on the network. In my case it was \\fileserver\users\.
The migration will change the registry keys:
HKCR\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, Favorites HKCR\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, Desktop HKCR\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Favorites HKCR\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Desktop
The new locations will look something like this:
Desktop: \\[server]\[share]\[username]\Desktop-[username]
Favorites: \\[server]\[share]\[username]\Favorites-[username]
e.g. \\fileserver\users\aaron\Desktop-aaron\ would be my desktop folder.
Conclusion
Implementing this solution is fairly easy. First modify the VB.NET application and compile it. Place the .exe file in a shared location that your login script for users has permissions. Place the VBScript file in a similar location, as you specified in the VB.NET application, and modify the serverpath variable and email variables. Test with your user account in your login script batch file using something similar to below:
if %USERNAME% == yourusername (
rem lets make sure the user has a my documents folder prior to trying to migrate their desktop
if exist "\\[server]\Users\%USERNAME%" (
if exist "C:\Documents and Settings\%USERNAME%\Desktop" (
rem lets make sure they have the 2.0 Framework installed.
if exist "C:\Windows\Microsoft.Net\Framework\v2.0*" (
start "Desktop Migration" "\\[server]\[share]\blankscreen.exe"
)
)
)
)
As a disclaimer, the application AND script are provided without any warranty and is only for educational / informational purposes. If you choose to use it in your environment, production or not, the outcome is your responsibility.
desktop.vbs Code
On Error Resume Next
'alert user of what is happening...
MsgBox "Please click OK to begin the backup process for your Desktop and Internet Explorer Favorites. This process could take a few minutes, please be patient and Do NOT Cancel anything, otherwise data could be lost!" & vbCrLf & vbCrLf & "If you have Administrator privileges, your computer will restart after all of your files have been copied!"
'get the current user
user = getUser()
'set the server location, the following \ is required!
serverpath = "\\[server]\Users\"
'if you have a helpdesk solution with email capability:
useemailnotify = 0
smtpfrom = "email@domain.com"
smtpto = "email@domain.com"
smtpserver = "smtp.domain.com"
'create folders
m_cf = createFolderscopyFiles(user)
If m_cf <> 1 Then
'update the registry and reboot
m_ur = updateRegistry(user)
If m_ur <> 1 Then
'rename the old folders so it does not use them anymore!
m_rof = renameOldFolders(user)
'reboot
Set WSHShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "C:\WINDOWS\system32\shutdown.exe -r -t 0"
End If
End If
Function getUser()
'get the current user environment variable.
Set oShell = CreateObject( "WScript.Shell" )
user = oShell.ExpandEnvironmentStrings("%UserName%")
If Err.Number <> 0 Then
'we have failure!
getUser = 1
Err.Clear
Else
getUser = user
End If
End Function
Function createFolderscopyFiles(user)
Set objFSO = CreateObject("Scripting.FileSystemObject")
'lets only do the folder create and file copy if that folder doesn't already exist. Otherwise, its just gonna set the registry and reboot.
If Not objFSO.FolderExists(serverpath & user & "\Desktop-" & user) Then
'Create the new Desktop and the Favorites folder.
objFSO.CreateFolder(serverpath & user & "\Desktop-" & user)
objFSO.CreateFolder(serverpath & user & "\Favorites-" & user)
Set oSHApp = CreateObject("Shell.Application")
'Copy the Desktop files
Set fromDFolder = oSHApp.Namespace("C:\Documents and Settings\" & user & "\Desktop")
Set toDFolder = oSHApp.Namespace(serverpath & user & "\Desktop-" & user)
toDFolder.CopyHere fromDFolder.Items, 16+512
'Copy the Favorites files
Set fromFFolder = oSHApp.Namespace("C:\Documents and Settings\" & user & "\Favorites")
Set toFFolder = oSHApp.Namespace(serverpath & user & "\Favorites-" & user)
toFFolder.CopyHere fromFFolder.Items, 16+512
End If
If Err.Number <> 0 Then
'we have failure!
SendEmail user,"failed at createFolderscopyFiles",Err.Description
createFolderscopyFiles = 1
Err.Clear
Else
createFolderscopyFiles = 0
End If
End Function
Function updateRegistry(user)
'lets work on the registry now
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
'update the registry for Desktop and Favorites (User Shell Folders)
'set Favorites
Set oFReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
strValueName = "Favorites"
strValue = serverpath & user & "\Favorites-" & user
oFReg.SetExpandedStringValue HKEY_CURRENT_USER,strKeyPath,strValueName,strValue
'set Desktop
Set oDReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
strValueName = "Desktop"
strValue = serverpath & user & "\Desktop-" & user
oDReg.SetExpandedStringValue HKEY_CURRENT_USER,strKeyPath,strValueName,strValue
'update the registry for Desktop and Favorites (Shell Folders)
'set Favorites
Set otFReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
strValueName = "Favorites"
strValue = serverpath & user & "\Favorites-" & user
otFReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,strValueName,strValue
'set Desktop
Set otDReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
strValueName = "Desktop"
strValue = serverpath & user & "\Desktop-" & user
otDReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,strValueName,strValue
If Err.Number <> 0 Then
'we have failure!
SendEmail user,"failed at updating registry",Err.Description
updateRegistry = 1
Err.Clear
Else
updateRegistry = 0
End If
End Function
Function renameOldFolders(user)
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.MoveFolder "C:\Documents and Settings\" & user & "\Desktop", "C:\Documents and Settings\" & user & "\DesktopOLD"
objFSO.MoveFolder "C:\Documents and Settings\" & user & "\Favorites", "C:\Documents and Settings\" & user & "\FavoritesOLD"
If Err.Number <> 0 Then
'we have failure!
SendEmail user,"failed at renaming old folders",Err.Description
renameOldFolders = 1
Err.Clear
Else
renameOldFolders = 0
End If
End Function
Sub SendEmail(user,contnt,contntB)
'if the setting is to send an email, then do it, otherwise...nada.
If useemailnotify = 1 Then
'send an email!!
Set objEmail = CreateObject("CDO.Message")
objEmail.From = smtpfrom
objEmail.To = smtpto
objEmail.Subject = "Desktop and Favorites Migration Issue for " & user
objEmail.Textbody = "User had a Desktop files migration error." & vbCrLf & vbCrLf & contnt & vbCrLf & vbCrLf & contntB
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtpserver
objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update
objEmail.Send
If Err.Number <> 0 Then
'we have failure!
MsgBox "Your Desktop migration didn't go very well."
Err.Clear
Else
'YAY!
End If
End If
End Sub
Downloads
BlankScreen.zip – VB.NET application
desktop.zip – VBScript

