Special folders script

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Troy Oosterwijk Troy Oosterwijk 1 year, 11 months ago.

  • Author
    Posts
  • #19955
    Profile photo of Troy Oosterwijk
    Troy Oosterwijk
    Participant

    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,

    T.O.

  • #19956
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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
    Profile photo of Troy Oosterwijk
    Troy Oosterwijk
    Participant

    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:

    $MyShell=$inputbox
    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
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    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
    Profile photo of Troy Oosterwijk
    Troy Oosterwijk
    Participant

    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
            cls
            }

    Cheers,

    T.O.

You must be logged in to reply to this topic.