For numerous reasons, I needed to define an alternate local users directory on my Server 2008 and Windows 7
installations, my plan was to rename the directory "users" to "profiles". I have detailed the method to do
that automatically: Installing Server 2008 (and R2)
with alternate Profiles (Users) directory using unattended method. I have also detailed a manual method
on the Manually move Server 2008 Profiles (Users)
directory page.
NOTE: Although I first wrote this for Windows 2008, I can confirm that this information also applies
to Windows 7 Professional. It would seem Server 2008 R2 and Windows 7 have identical profile setup, directory
structure, and functionality.
After a system is running with an alternate local profiles directory, There are known issues with system
directory junction points documented in Microsoft KB article
929831. To fix this problem, I created a batch file script (below) to fix all problem junction points.
Background: What strikes me as astounding is that a fresh 2008 Server install using the ProfilesDirectory
parameter in autounattend.xml does NOT correctly create the junction points using this variable! Considering I
am NOT a batch file expert, I would think if I could fix the junction points with a batch file, it seems
insufficient that Microsoft's install process does not correctly create the junction points.
Quick primer for those unfamiliar with junction points: think of a program that insists on saving some
information to the 'C:\Documents and Settings\All Users' directory, but that directory no longer exists under
Windows 2008/Vista/7. So that would be nice if we could make an 'alias' or 'shortcut' redirecting the
'C:\Documents and Settings' directory to the 'C:\Profiles' (or by default 'C:\Users') directory. For those
familiar with *nix systems, these are known as symbolic links.
Additionally, in the process of recreating the junction points, I discovered there was an endless loop in
the directory structure created, in that there is at least one known instance of a link pointing to a parent
directory. When a program such as a backup program descends through the directory tree, the junction point is
encountered, and listing it's (aliased to parent directory) contents lists again the junction point, which
again lists the parent directory, creating an endless loop. Just do an internet search for "Application
Data\Application Data\Application Data" and you will see numerous references to this problem.
Microsoft's solution to this problem is to add a 'deny list directory for everyone' permission to the
junction point. It is annoying that in Windows Explorer, you double-click a junction point and you get
'Access Denied' message, but this is actually necessary to prevent recursive loops. Note that just 'List
Directory' permission is denied, but all other read and write permissions are in effect allowing hard-coded
paths to 'C:\Documents and Settings' to function correctly.
In my batch file, you will see that I was able to use a couple of 'icacls' commands to duplicate the
Microsoft default permissions, and then change the attributes on the junction point with the 'attrib' command
to duplicate the Microsoft attributes. Warning: be careful to apply to these commands with the '/L' switch,
so that the command executes against the junction point (symbolic link), OTHERWISE the command will execute on
the directory pointed to!
See for yourself In Windows Explorer, (with 'show hidden and system files' enabled) junction
points will *usually* appear as a folder with a shortcut arrow on it. From the command prompt, junction
points are hidden when listing files. To view the junction point information for 'C:\Documents and Settings'
at the command prompt, change to the root directory: cd \
then use the list files with 'Link' attribute: dir /al C:\
you should see: 07/18/2010 06:35 PM <JUNCTION>
Documents and Settings [C:\Users]
This indicates that 'C:\Documents and Settings' is redirecting to the 'C:\Users' directory. You can
list all junction points on the entire C: drive by adding the 'recurse sub-directories' switch:
dir /al /s C:\
Be aware that this list will be a bit large. Before you use the script to fix the links, you should
probably run this command with output redirected to a reference file so that you have a snapshot of your
system before any changes were made.
Preview script
You can copy & paste a script that will preview the changes:
TweakSymbolicLinksPreview.txt. You may want to
compare the output to the reference file created in the previous paragraph, only links that contain the path
in the FindBadDir variable will be listed.
Example: C:\TweakSymbolicLinksPreview.bat > C:\OrigSymbolicLinks.txt
DISCLAIMER: Using this script, or any of this advice may turn your system into a puddle of silicon
or cause a complete loss of all data. Use at your own risk! Perhaps it was an accident that this
worked for me. This information is intended for IT administrators, if you are unsure of any of these terms
then you should probably get some expert advice.
Of course, you can tweak this batch file to suit your needs. I saved both the TweakSymbolicLinksPreview.bat
file and the TweakSymLinks.bat batch file to the root of the C: drive, and cd'd to the root directory in
Command Prompt to execute the batch file.
TweakSymLinks.bat script
-----------------------------------------------------------------------------------------
:: Sample TweakSymLinks.bat file
:: DISCLAIMER: Using this script, or any of this advice may turn your system into a puddle
:: of silicon or cause a complete loss of all data. Use at your own risk!
:: Author: Jay Ohman, Ohman Automation Corp.
:: Rev: 10/30/2011
:: Purpose: Script for changing all junction points and symbolic links when referenced path
:: has changed.
:: Development Reference: (contains debug echo's and fully commented)
:: http://www.OhmanCorp.com/RefWin-Win2008R2-TweakSymbolicLinksPreview.txt
@echo off
setlocal
echo ----------------------------- BEGIN -----------------------------
C:
set FindBadDir=C:\Users
set CorrectDir=C:\Profiles
:: ** if desired, try a simpler directory first
set BeginDir="\"
:: set BeginDir="\Profiles"
:: set BeginDir="\Profiles\Default\Documents"
cd %BeginDir%
echo Fetching all junction/symlink references from entire C: drive....
for /f "tokens=1-3 delims=><" %%a in ('dir /al /s') do call :x1 "%%a" "%%b" "%%c"
goto :finish
:x1
echo %~1 | findstr /i /r /c:"Directory of C:" > NUL && call :x2 %1
echo %~3 | findstr /i /r /c:"%FindBadDir:\=\\%" > NUL && call :x3 %3
goto :EOF
:x2
set xLin=%~1
set xCurDir=%xLin: Directory of C:=C:%
if NOT "%xCurDir%"=="C:\" set xCurDir=%xCurDir%\
echo Checking directory: %xCurDir%
goto :EOF
:x3
set xLin=%~1
set xParseLin=%xLin: =%
for /f "tokens=1-2 delims=][" %%i in ('echo %xParseLin%') do call :x4 "%%i" "%%j"
set xLin=
set xParseLin=
goto :EOF
:x4
set xTmp=%~1###
set xFPName=%xCurDir%%xTmp: ###=%
set xFPDestBad=%~2
Setlocal EnableDelayedExpansion
set xFPDestNew=!xFPDestBad:%FindBadDir%=%CorrectDir%!
Endlocal&Set xFPDestNew=%xFPDestNew%
echo ----------------------------------------------------------
echo Old: %xFPName% --^> %xFPDestBad%
echo New: %xFPName% --^> %xFPDestNew%
echo Deleting old Junction: %xFPName%
rmdir "%xFPName%"
echo Making new Junction:
mklink /J "%xFPName%" "%xFPDestNew%"
echo Changing permissions:
icacls "%xFPName%" /deny everyone:(RD) /L
icacls "%xFPName%" /setowner SYSTEM /L
echo Changing attributes:
attrib +S +H +I "%xFPName%" /L
rem pause
set xTmp=
set xFPName=
set xFPDestBad=
set xFPDestNew=
goto :EOF
:finish
set FindBadDir=
set CorrectDir=
set BeginDir=
:: -- remove these next lines if you prefer the *spoofed* names to appear
del /ah "C:\Profiles\desktop.ini"
del /ah "C:\Profiles\Public\Documents\desktop.ini"
del /ah "C:\Profiles\Public\Downloads\desktop.ini"
del /ah "C:\Profiles\Public\Music\desktop.ini"
del /ah "C:\Profiles\Public\Pictures\desktop.ini"
del /ah "C:\Profiles\Public\Videos\desktop.ini"
echo ------------------------------ END ------------------------------
-----------------------------------------------------------------------------------------
If you want to verify the batch file worked, use the Command Prompt to again list the Link files
at the root directory: dir /al C:\
you should see: 07/18/2010 06:35 PM <JUNCTION>
Documents and Settings [C:\Profiles] (or whatever alternate name you chose).
NOTE: you will see at the end of the batch file some commands to delete some desktop.ini files. For
some *unfathomable* reason, Microsoft decided that in Windows Explorer, the 'Public\Music' directory should
appear as 'Public\Public Music'. Then to *really* make an admin see red, the desktop.ini created from the
autounattend.xml install in the 'C:\Profiles' directory will make the folder appear as '\Users'! Now
why-in-the-world would it be desirable to have a *spoofed* directory name on a server?! I absolutely
detest spoofed directory names! (I have yet to see any benefit what-so-ever to having desktop.ini files on a
server, I should just delete them all). *end of rant*
Should you decide to move the location of the "Documents" directory (formerly known as "My Documents"), say
to another local drive or network drive, you may want to recreate the links in the "Documents" directory to
the new location. Tip: changing the location of "My Documents" was fairly easy in Windows XP, to do this in
Win7/2008R2 is a little more complicated, navigate to: "Libraries\Documents\My Documents" and right-click My
Documents choose "Properties". In the pop-up window, you should now see the familiar "Location" tab that you
can use to move the location of the "Documents" folder. You will need to repeat this process under
"Libraries" for Music, Pictures, and Videos.
I believe Microsoft created these symbolic links in case any programs are expecting "My Pictures"
to be located under the directory "My Documents" as was the case in Windows XP. Note that Music,
Pictures, and Videos directories are no longer located under "Documents" (My Documents).
Instead these directories are now "Moved up a level" to the user's profile (root) directory.
One more tip: if you decide to also move the "Public" directories to another location, you may need to
re-create the desktop.ini files to restore the original appearance of these directory names. There is a good
reference for re-creating desktop.ini files by Windows7Themes.Net at:
Desktop.ini in Windows 7.
Feel free to send me feedback if you find any mistakes, or if this saved you a bunch of time.
|