Special folders script

This topic contains 4 replies, has 3 voices, and was last updated by  Troy Oosterwijk 2 years, 7 months ago.

  • Author
  • #19955

    Troy Oosterwijk

    Hi all,

    Me again, with another question here.

    I've created a Windows config script, which mostly works fine, but I've been struggling a bit with the following.
    With this script I also want to automate changing the "Special Folders" for the user.
    For example, I want "C:\Users\X\Documents" to be moved to "D:\Users\X\Documents".
    Basicially I got it working, but I'm relying on some hardcoded variables, which in my eyes are a bit cumbersome at the moment.

    Below are the specific lines of scripting, which I think can be tweaked a bit:

    $MyDirs = "Contacts","Desktop","Documents","Downloads","Favorites","Music","Pictures","Saved Games","Videos"
    $folders = [System.Enum]::GetValues[[System.Environment+SpecialFolder]]
    $paden = foreach [$folder in $folders] {[System.Environment]::GetFolderPath[$folder]}
    $paden2 = foreach [$MyDir in $MyDirs] {$paden |Select-Object -Unique |Where-Object {$_ -like "*$MyDir"}}
    # example:
    foreach [$pad in $paden2] {New-Item -Type File "$pad\textx.txt"} or copy to the new location, or something else.

    The first line I use is to hardcode the folder-keywords I'm looking for to move.
    The [b]$Folders[/b] gets me a list of ALL the special folders names. Now I need to get only the ones I want (with the hardcoded MyDirs) and I also need their paths.
    So the[b] $paden[/b] shows me all of the paths and with the use of the final variable, I can filter them against my hardcoded MyDirs and continue to do whatever I want with them.
    The reason I use this method, is because different versions and languages of Windows tend to have different Special Folder Paths. This way, no matter what installion I run, the folders will always be checked with the [b]System.Environment[/b] coding.

    But again, as you can see, it's a bit overly complicated and I was wondering if there's an easier way of doing what I'm trying to achieve here.
    Comments are welcome!

    Thanks in advance,


  • #19956

    Dave Wyatt

    Folder Redirection is typically implemented with Group Policy. I'm not sure if there's an easy way to do this with a script for just one user account; it's not something I've tried before. Web searches are turning up some information that might be useful, but would need some testing to find out for sure.

    Here's the official documentation: http://technet.microsoft.com/en-us/library/hh848267.aspx

  • #19959

    Troy Oosterwijk

    Thanks for your reply Dave.

    I can assure it will work just fine. Especially for a home environment, you don't want to hassle around with local policies.
    My "older version" of the script used the following lines:

    set MyDirs "Contacts","Desktop","Documents","Downloads","Favorites","Music","Pictures","Saved Games","Videos"
    New-Item -Path $MyShell -type directory -Force
    Set-Location -LiteralPath $MyShell
    foreach ($MyDir in $MyDirs) {Copy-Item $HOME\$MyDir -recurse -Force}

    After that part, the script makes the appropriate registry changes, to make sure the folders points to the new location.

    As you can see, it relies too much on the hardcoded [b]MyDirs[/b] variable, which would be used without checking it against the "real-world" paths.
    The part I posted first, will work fine, but the use of so many variables seems unlogic to me and I'm pretty sure there must be an easier way for achieving my intended goals.

    edit: apparently while copy/pasting my lines in the first post, some of the characters have been changed (parentheses became squares). Please ignore this...

  • #19967

    Adam Bertram

    If you only want to copy those directories out of all of the special folders you really have no choice to specify them in an array like that. Your code looks pretty good already. You could trim it down a little bit but it wouldn't change the performance all that much.

  • #21580

    Troy Oosterwijk

    Hey y'all,

    A little update here. I've managed to create something that works better in my opinion. The following code no longer relies on hardcoded paths, instead it checks the userhome directory of the current folders which can be redirected.
    The code relies on two functions though,
    [b]Show-MsgBox[/b]: for a fancy way of making the choices throughout the script
    [b]Get-RegistryKeyPropertiesAndValues[/b]: to read out the correct properties and values to adjust later on

    For those who are interested, here it is:

    $answer = Show-MsgBox -title "Changing the User Library Paths" -prompt "Do you want to change the user documents folder?" -BoxType YesNo -Icon Question
    if [$answer -eq "Yes"]
        $MyDirs = Get-ChildItem "$HOME" -Name -Exclude "Links", "Searches"
        if [$MyDirs]
            $ShellFolder = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
            $UserShellFolder = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
            foreach [$MyDir in $MyDirs]
                $RegName = Get-RegistryKeyPropertiesAndValues $ShellFolder |Where-Object {$_.Value -match "$MyDir"} |foreach {$_.property}
                $answer = Show-MsgBox -title "Change $MyDir Folder" -prompt "Do you want to change the $Mydir folder?" -BoxType YesNo -Icon Question
                if [$answer -eq "Yes"] 
                    $inputbox = $null
                    $inputbox = Show-Inputbox -message "Enter the path of the $MyDir folder" -title "Entering path..." -default "D:\Users\$env:username\$MyDir"
                    if [$inputbox] 
                        if [![Test-Path "D:\Users\$env:username\$MyDir"]] {New-Item "D:\Users\$env:username\$MyDir" -ItemType Directory -Force}
                        Set-ItemProperty -Path $ShellFolder -Name $RegName -Value $inputbox
                        Set-ItemProperty -Path $UserShellFolder -Name $RegName -Value $inputbox
                        Move-Item "$HOME\$MyDir\*" "D:\Users\$env:username\$MyDir" -Force
                        attrib +r "D:\Users\$env:username\$MyDir"
                        rd $HOME\$MyDir -recurse -Force
            Show-MsgBox -title "Press OK to continue" -prompt "Folder redirection done!" -BoxType OkOnly -Icon Exclamation



You must be logged in to reply to this topic.