Create multiple shortcuts in different folders based on file name

2

Basically, we have a lot of .mht files (generated periodically with MicroStrategy) and we need to serve these files on different folders to apply security. To avoid space consumption, we thought of creating shortcuts on several folders.

The files all start with groupings of 4 digits and an underscore (e.g. 0001_0041, 0001_0043, etc.).

This is what I have now:

Get-Childitem -Path "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
Foreach-Object {
  $ruta = Get-Childitem -Path "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
  $nombre = Get-Childitem -Name "C:\Users\Max\Google Drive\Portal\Mermaid" -Recurse -Include "0002*.mht"
  $ncorto = $nombre | ForEach-Object {$nombre.Substring(0,9)}
  $container = "C:\Users\Max\Google Drive\Portal\Mermaid\MHT_Shortcuts\$ncorto"
  if (!(Test-Path $container)) {
    New-Item -ItemType directory -Path $container | Out-Null
  }
  $TargetFile = $ruta
  $ShortcutFile = "$container\$nombre.lnk"
  $WScriptShell = New-Object -ComObject WScript.Shell
  $Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
  $Shortcut.TargetPath = $TargetFile
  $Shortcut.Save()
}

This works as long as there is only one file starting with 0002. However, they keep historic files that have the same name with timestamp.

If there are multiple files that start with 0002 (there will be as they keep historic versions of these files), I get the error:

Exception setting "TargetPath": "The parameter is incorrect. (Exception from
HRESULT: 0x80070057 (E_INVALIDARG))"
En C:\Users\Max\Desktop\MK_LNK_V01.ps1: 25 Character: 7
+                         $Shortcut.TargetPath = $TargetFile
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : CatchFromBaseAdapterSetValueTI

Sorry if this is a duplicate, I couldn't find a post about this specific issue.

powershell
desktop-shortcut
asked on Stack Overflow Jan 12, 2016 by Max Feulien • edited May 31, 2018 by Max Feulien

3 Answers

2

Here's a short example of how to create .lnk files for all files in a directory:

$shortcutPath = "C:\TextFiles"
$wshShell = New-Object -ComObject "WScript.Shell"
Get-ChildItem (Join-Path $shortcutPath "*.txt") | ForEach-Object {
  $lnkFilename = Join-Path $shortcutPath ("{0}.lnk" -f [IO.Path]::GetFilenameWithoutExtension($_.FullName))
  $shortcut = $wshShell.CreateShortcut($lnkFilename)
  $shortcut.TargetPath = $_.FullName
  $shortcut.Save()
}

Of course you will need to modify this example to suit your needs.

answered on Stack Overflow Jan 12, 2016 by Bill_Stewart
0

The TargetPath property of a WshShortcut object expects a single path, not a list of paths. Also, I'd recommend moving everything that doesn't require repeated exectution outside the loop.

$app = New-Object -ComObject 'WScript.Shell'

$container = 'C:\shortcut\folder'
$path = 'C:\Users\Max\Google Drive\Portal\Mermaid'

if (!(Test-Path $container)) {
  New-Item -Type Directory -Path $container | Out-Null
}

Get-Childitem -Path $path -Recurse -Include "0002*.mht" | Foreach-Object {
  $ShortcutFile = "$container\$nombre.lnk" -f $_.BaseName
  $Shortcut = $app.CreateShortcut($ShortcutFile)
  $Shortcut.TargetPath = $_.FullName
  $Shortcut.Save()
}
answered on Stack Overflow Jan 12, 2016 by Ansgar Wiechers • edited May 31, 2018 by Max Feulien
0

Based on the script that @Bill_Stewart provided, I added some lines to first delete the links, then create the containing folder based on the 1st 9 characters of the filename and create the shortcuts in it:

$shortcutPath = "C:\Origin"
$contenedor = "C:Destination"
$wshShell = New-Object -ComObject "WScript.Shell"
Get-ChildItem -Path $contenedor -Include *.lnk -File -Recurse | foreach { $_.Delete()}
Get-ChildItem (Join-Path $shortcutPath "*.mht") | ForEach-Object {
  $nombre = $_.BaseName
  $ncorto = $nombre.SubString(0, 9)
  $destino = Join-Path $contenedor $ncorto
  if (!(test-Path $destino)) {
                        New-Item -ItemType directory -Path $destino | Out-Null}     
  $lnkFilename = Join-Path $destino("{0}.lnk" -f [IO.Path]::GetFilenameWithoutExtension($_.FullName))
  $shortcut = $wshShell.CreateShortcut($lnkFilename)
  $shortcut.TargetPath = $_.FullName
  $shortcut.Save()

This worked as a charm. Thanks all for your help.

answered on Stack Overflow Jan 14, 2016 by Max Feulien • edited Jan 14, 2016 by Max Feulien

User contributions licensed under CC BY-SA 3.0