How to create symbolic links for multiple files in multiple folders using command prompt or power shell?

11,394

Solution 1

You can try something link this:

function createSymbolicLinks ($source, $destination, [switch]$recurse) {
    Get-ChildItem $source -Recurse:$recurse | ? { !$_.PSISContainer } | % {
        $destpath = $_.Fullname -replace [regex]::Escape($source), $destination
        if(!(Test-Path (Split-Path $destpath))) {
            #Create missing subfolders
            New-Item (Split-Path $destpath) -ItemType Directory -Force | Out-Null
        }
        cmd /c mklink $destpath $($_.FullName) | Out-Null
    }
}

#Create symbolic links in c:\folderC for all files in d:\folderD(with recursive search)
createSymbolicLinks -source d:\folderD -destination c:\folderC -recurse

I believe this will fail if the same filename already exists in c:\folderc. So if you need to replace a file in c:\folderc with a symbolic link from d:\folderd, you need to extend it to remove the existing file.

UPDATE: This will only go down one level with the recurseoption. It's not the prettiest solution, but it should work.

function createSymbolicLinks ($source, $destination, [switch]$recurse) {
    Get-ChildItem $source | % { 
        if($_.PSIsContainer -and $recurse) { 
            Get-ChildItem $_.FullName
        } else { 
            $_
        }
    } | ? { !$_.PSIsContainer } | % { 
        $destpath = $_.Fullname -replace [regex]::Escape($source), $destination
        if(!(Test-Path (Split-Path $destpath))) {
            #Create missing subfolders
            New-Item (Split-Path $destpath) -ItemType Directory -Force | Out-Null
        }
        cmd /c mklink $destpath $($_.FullName) | Out-Null
    }
}

#Create symbolic links in c:\folderC for all files in d:\folderD(with recursive search)
createSymbolicLinks -source d:\folderD -destination c:\folderC -recurse

Solution 2

other way. In a .bat file, i use this :

for /f "delims=" %%i in ('dir /b /s *.jpg *.jpeg *.png *.gif') do (
    name of link = a path to a folder + a number + %%~nxi
    mklink </h for hard links or nothing for symlinks> name of link "%%i" >> log.txt
)

explanation : for /f ... loop in a chosen dir with subfolders, %%i is the name of a file found with path (folder\subfolder\one_file.ext).
%%i~nxi is the name without path (n) and with extent (x). mklink créate the link for %%i It works. My question was different. In 2 computers, i can browse all the symbolic links (all the folders and subfolders) but in the third, not exactly. But with hard links, all is OK (with mklink /H ) Read the end of my question please. Thanks

Solution 3

PS: Firstly I wanted to use hard links but it seems it is not possible.

Hard links are only possible within the same filesystem: they cannot span different drives (including when using reparse points to avoid drive letters).

Second, "symbolic links" in Windows are a shell (ie. Windows Explorer) artefact. they will only work when applications make use of the shell namespace (which most do not).

Better to avoid.

Share:
11,394
ide
Author by

ide

ide

Updated on June 04, 2022

Comments

  • ide
    ide almost 2 years

    I have two main folders which have a lot of sub-folders in different drives. Have to create symbolic link for all files in the second folder into the first one.

    C:\folderC>tree /f
    C:.
    ├───folder1
    │       file1.txt
    │       file3.txt
    │
    └───folder2
            file1.txt
            file3.txt
    
    D:\folderD>tree /f
    D:.
    ├───folder1
    │       file2.txt
    │
    └───folder2
            file2.txt
    

    Result using 2 commands:

    C:\>mklink C:\folderC\folder1\file2.txt D:\folderD\folder1\file2.txt
    symbolic link created for C:\folderC\folder1\file2.txt <<===>> D:\folderD\folder1\file2.txt
    
    C:\>mklink C:\folderC\folder2\file2.txt D:\folderD\folder2\file2.txt
    symbolic link created for C:\folderC\folder2\file2.txt <<===>> D:\folderD\folder2\file2.txt
    
    C:.
    ├───folder1
    │       file1.txt
    │       file2.txt
    │       file3.txt
    │
    └───folder2
            file1.txt
            file2.txt
            file3.txt
    

    How to make it for all files with a few commands instead of writing the code manually for each file?

    PS: Firstly I wanted to use hard links but it seems it is not possible.

    C:\>mklink /h C:\folderC\folder2\file2.txt D:\folderD\folder2\file2.txt
    The system cannot move the file to a different disk drive.
    
    • Adam Bertram
      Adam Bertram over 10 years
      Is there any way you can forego creating hard or symbolic links to accomplish what you're trying to do?
    • ide
      ide over 10 years
      @adbertram I do not think so, because files in D were moved from C and they should be visible inside C. I try to reduce internal HDD activity by using external USB drive.
  • Adam Bertram
    Adam Bertram over 10 years
    I agree. It'd be interesting to see what the OP is trying to accomplish to see if we can think of another way to do it.
  • ide
    ide over 10 years
    Can I limit the recursive with 1 sub-folder level?
  • Frode F.
    Frode F. over 10 years
    See updated answer. I couldn't think of a better way at the moment, but it does the job I think.
  • kamyl
    kamyl over 6 years
    To make it easier to read for others, wrap your code into ``, so it looks like this. For multi line code, add 4 spaces before every line. You can read about it here. ;)