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.
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.
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()
}
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.
User contributions licensed under CC BY-SA 3.0