Hi,
Need assistance to use RoboCopy to copy folders recursively to a DVD, if found shortcut .lnk in a folder, extract all files in a defined location on the DVD with link. Need RoboCopy as we have very long paths that cannot be copied and accessed otherwise.
Many thanks for the assistance.
Zak
Olaf
May 26, 2022, 8:43am
2
Zak,
Welcome to the forum.
You should enable the “long path support ”
What have you tried already? Please share your code.
Thanks for the response.
Any tweak to the Registry is not allowed on the Company’s network, this is the reason why we are always using Robocopy to perform such tasks.
This is a code I picked from the following site. It does not copy ALL “.lnk” files and folders within the recursive folders.
#https://github.com/mbrowniebytes/powershell-copy-shortcut-
# _copy_shortcut_contents.ps1
#
# from the source directory, find all shortcuts, and copy the shortcut contents to a destination directory
# options
# only output what would happen, dont actually copy anything
$dryrun = 0;
# where to copy from; full path; end with slash
# $src = "C:\zRename\"
# use current dir as srcDir
$srcDir = "C:\zSOURCE\"
# where to copy to; full path; end with slash
# $destDir = "T:\"
$destDir = "C:\zDESTINATION\"
# 1 (recommended) - use dos copy to get progress per file, 0 - use copy-item
$useCopyProgress = 1;
# if dest path exists, skip
$skipExistingDestPath = 0;
# 1 (recommended) - if dest file exists, skip, 0 - re-copy
$skipExistingDestFile = 1;
# 1 - show existing files, 0 - dont show, reducing output
$showExistingFiles = 0;
# start
# initial padding for progress bar
write-host ""
write-host ""
write-host ""
write-host ""
write-host ""
write-host ""
write-host ""
write-host ""
write-host ""
Write-Progress -Id 1 -Activity "Copying shortcut contents from $srcDir to $destDir" -Status "Progress 0%" -PercentComplete 0
write-host "Copying shortcut contents from $srcDir to $destDir"
write-host ""
if ($destDir -eq "") {
write-host "Stopped"
write-host "Edit srcDir and destDir variables and read script"
write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
exit
}
# Get all shortcuts
$shortcuts = gci "$srcDir\*.lnk"
# iterate over shortcuts
$total = $shortcuts.count
$index = 0
$sh = New-Object -COM WScript.Shell
foreach ($shortcut in $shortcuts) {
# get target path from shortcut ie what shortcut points to
$srcPath = $sh.CreateShortcut($shortcut.fullname).Targetpath
$srcDrive = $srcPath.substring(0, 3)
# duplicate src folder structure in dest
$destPath = $srcPath.replace($srcDrive, $destDir)
# indicate progress
$progress = "{0:N2}" -f ($index / $total * 100)
$index++
# -NoNewLine if not using xcopy
write-host " Copying: $srcPath -> $destPath " -foregroundcolor DarkGreen -backgroundcolor white
Write-Progress -Id 1 -Activity "Processing $index of $total shortcuts" -Status "Progress $progress%" -PercentComplete $progress
# skip existing dirs
if (Test-Path "$destPath") {
write-host " $destPath " -NoNewLine
write-host " Exists " -foregroundcolor white -backgroundcolor DarkGreen
if ($skipExistingDestPath) {
continue
}
}
# get dest path for copy-item to recurse into
if (Test-Path "$destPath") {
# if path exists, copy-item will re-create within it, so go up one level
$destRecreatePath = "$destPath\..\"
} else {
# if path does not exist, copy-item will create it
$destRecreatePath = $destPath
}
# copy shortcut contents to destination, including subdirs
if (!$useCopyProgress) {
# use copy-item to copy shortcut contents to destination, including subdirs
# but no progress per file
if ($dryrun) {
write-host "dryrun: copy-item -Path $srcPath -Destination $destRecreatePath -Force -Recurse -Container -Exclude $exclude"
} else {
# get current list of files, if any
$exclude = ""
if (Test-Path "$destPath") {
$origFiles = gci "$destPath" -File -Recurse
# exclude already copied dirs/files
if ($skipExistingDestFile) {
$exclude = gci $destPath
}
} else {
$origFiles = @()
}
# copy
copy-item -Path "$srcPath" -Destination "$destRecreatePath" -Force -Recurse -Container -Exclude $exclude
# show results in destPath, from current or prior copy-item
$files = gci "$destPath" -File -Recurse
foreach ($file in $files) {
$srcFile = $file.fullname
$destFile = $srcFile.replace($srcDrive, $destDir)
$destRelPath = $destFile.replace($destPath, "")
if ($origFiles.fullname -contains $file.fullname) {
if ($showExistingFiles) {
write-host " $destRelPath " -NoNewLine
write-host " Exists "
}
} else {
write-host " $destRelPath " -NoNewLine
write-host " Copied " -foregroundcolor white -backgroundcolor DarkGreen
}
}
}
} else {
# use msdos copy to copy shortcut contents to destination, including subdirs
# copy folder structure only ie create srcPath directories in destRecreatePath
if ($dryrun) {
write-host "dryrun: copy-item -Path $srcPath -Destination $destRecreatePath -Filter {PSIsContainer} -Force -Recurse -Container"
} else {
# https://stackoverflow.com/questions/9996649/copy-folders-without-files-files-without-folders-or-everything-using-powershel
copy-item -Path "$srcPath" -Destination "$destRecreatePath" -Filter {PSIsContainer} -Force -Recurse -Container
}
# copy files with progress
$files = gci "$srcPath" -File -Recurse
foreach ($file in $files) {
$srcFile = $file.fullname
$destFile = $srcFile.replace($srcDrive, $destDir)
# skip existing files, compare by date
if (Test-Path "$destFile") {
$srcLastTime = $file.LastWriteTime
$destLastTime = (gci "$destFile").LastWriteTime
if ($srcLastTime -eq $destLastTime) {
if ($showExistingFiles) {
write-host " $destFile " -NoNewLine
write-host " Exists "
}
if ($skipExistingDestFile) {
continue
}
}
}
# show file name being copied
$destRelPath = $destFile.replace($destPath, "")
# spacing for copy output
# '100% copied 1 file(s) copied. '
write-host " $destRelPath" -NoNewLine
# copy with progress %
if ($dryrun) {
write-host ""
write-host "dryrun: cmd /c copy /z $srcFile $destFile"
} else {
# https://stackoverflow.com/questions/2434133/progress-during-large-file-copy-copy-item-write-progress
# xcopy prompts for is this a file/dir, no progress
# robocopy asks for admin perms on ntfs/audit attribs
# copy copies with progress %
# /z : Copies networked files in restartable mode.
cmd /c copy /z $srcFile $destFile
}
}
}
# copied, update progress
$progress = "{0:N2}" -f ($index / $total * 100)
Write-Progress -Id 1 -Activity "Processing $index of $total shortcuts" -Status "Progress $progress%" -PercentComplete $progress
}
# finish
Write-Progress -Id 1 -Activity "Processed $index of $total shortcuts" -Status "Progress $progress%" -PercentComplete $progress
write-host ""
write-host "Finished"
write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Olaf
May 26, 2022, 10:44am
5
Please go back, edit your last post and fix the formatting of the code.
When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.
Thanks in advance
How to format code in PowerShell.org <---- Click
Olaf
May 26, 2022, 11:03am
6
It’s not a shady registry hack it’s a supported setting you can access by GPO
If you’re not in the IT department you should urgently approach the IT department regarding this setting - we have 2022!! It’s like you have to boil water but you’re not allowed to use heat.
The link you posted is broken.
But anyway I am not willing to digg into that big chunk of badly written and formatted piece of code. Sorry. Please reduce the code to the part you have an issue with so we may be able to copy and to reproduce the problem.
Thanks in advance.
This is the link
https://github.com/mbrowniebytes/powershell-copy-shortcut-contents/blob/master/_copy_shortcut_contents.ps1
The point is this code does not use Robocopy, and the result when run does not extract the folders and files from “.lnk” files within the “source” subfolders.
Olaf
May 26, 2022, 11:23am
8
I can see you to have two options. Either you contact the author and hope for help of you start writing the code you need from scratch yourself.
When I search for “powershell determine target of link ” I get the following as the first hit:
https://social.technet.microsoft.com/Forums/en-US/912c7ff9-4d08-451c-ac2b-30fe2184939a/powershellhow-do-i-get-link-target-for-a-shortcut?forum=winserverpowershell
Using this as an insliration we get this snippet to extract all targets from all shortcuts from a given folder:
$Path = 'D:\sample'
$WScript = New-Object -ComObject WScript.Shell
Get-ChildItem -Path $Path -Filter '*.lnk' |
ForEach-Object {
$WScript.CreateShortcut($_.FullName).TargetPath
}
Thanks for responding and your efforts.
What I need is to extract the actual folders and files that the .lnk is pointing to, not just the path.
Olaf
May 26, 2022, 11:41am
10
I’ve got that. Did you get that I try to help you to get started? The code snippet I posted shouldn’t be the solution. It’s meant to be a hint where to start.
This forum is for scripting questions rather than script requests. We do not write customized and ready to use scripts or solutions on request. And we do not review and refactor code you’ve found on the internet.
Edit:
And BTW: robocopy follows symbolic links by default.
2 Likes