first post here and complete beginner with PowerShell (and coding in general), so apologies if I'm missing something trivially obvious.
I have a text file with three columns (delimited by " : "). The first contains a path for a shortcut that I would like to create. The second contains the target path. The third column contains the path for the corresponding ICO file that should be applied to the shortcut.
I have been trying out various ways to phrase the code but my fundamentals are a bit too weak to really troubleshoot things effectively and so I'm mainly stumbling around in the dark. Here is what I thought would do the trick:
$Contents = Get-Content "D:\Projects\Learning To Code\PowerShell\Commands and Scripts\Shortcuts List.txt"
ForEach ($Line in $Contents) {
$ShortcutFile = "`"" "D:\Projects\PowerShell\Test Environment\" $Contents[0].Split(":")[1] ".lnk`""
$TargetFile = "`"" "D:\Projects\PowerShell\Test Environment\" $Contents[1].Split(":")[1] "`""
$IconFile = "`"" "D:\Miscellaneous\Other\Backend\Icons\" $Contents[2].Split(":")[1] ".ico`""
$WshShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $TargetFile
$Shortcut.IconLocation = $IconFile
$Shortcut.Save()
}
The contents of the "Shortcuts Lists.txt" are as follows:
Random Path 1\Name A – Title A:Random Path 2\Name A – Title A:Random Path 3\Name A – Title A
Random Path 1\Name B – Title B:Random Path 2\Name B – Title B:Random Path 3\Name B – Title B
Random Path 1\Name C – Title C:Random Path 2\Name C – Title C:Random Path 3\Name C – Title C
Random Path 1\Name D – Title D:Random Path 2\Name D – Title D:Random Path 3\Name D – Title D
Random Path 1\Name E – Title E:Random Path 2\Name E – Title E:Random Path 3\Name E – Title E
Random Path 1\Name F – Title F:Random Path 2\Name F – Title F:Random Path 3\Name F – Title F
Random Path 1\Name G – Title G:Random Path 2\Name G – Title G:Random Path 3\Name G – Title G
Random Path 1\Name H – Title H:Random Path 2\Name H – Title H:Random Path 3\Name H – Title H
Random Path 1\Name I – Title I:Random Path 2\Name I – Title I:Random Path 3\Name I – Title I
Random Path 1\Name J – Title J:Random Path 2\Name J – Title J:Random Path 3\Name J – Title J
Random Path 1\Name K – Title K:Random Path 2\Name K – Title K:Random Path 3\Name K – Title K
Random Path 1\Name L – Title L:Random Path 2\Name L – Title L:Random Path 3\Name L – Title L
Random Path 1\Name M – Title M:Random Path 2\Name M – Title M:Random Path 3\Name M – Title M
Random Path 1\Name N – Title N:Random Path 2\Name N – Title N:Random Path 3\Name N – Title N
Random Path 1\Name O – Title O:Random Path 2\Name O – Title O:Random Path 3\Name O – Title O
Random Path 1\Name P – Title P:Random Path 2\Name P – Title P:Random Path 3\Name P – Title P
Random Path 1\Name Q – Title Q:Random Path 2\Name Q – Title Q:Random Path 3\Name Q – Title Q
A bit more debugging has suggested that the root of the problem might lie with the Em Dash that's present in the shortcut path and target path for each line. Using the Write-Output $ShortcutFile command shows that the Em Dash gets replaced by `–
Renaming all the files to replace the Em Dash isn't really an option so I'm hoping there's an alternative solution.
UPDATE: I've managed to circumvent the issue with Em Dash by replacing it with a unique string in the text file and adding a "-Replace" argument to the main code, but still no dice on the output. The Write-Output $ShortcutFile command shows that the code isn't going through line by line but just repeating the first line over and over. And I'm still getting the error telling me that the $Shortcut must end with ".lnk" or ".url"
CodePudding user response:
You could replace those EM dashes with
$inputFile = "D:\Projects\Learning To Code\PowerShell\Commands and Scripts\Shortcuts List.txt"
(Get-Content -Path $inputFile -Raw) -replace '\p{Pd}','-' |
Set-Content -Path $inputFile -Force
Regex \p{Pd}
means "any kind of hyphen or dash"
Then it should be possible to use Import-Csv on that
# define the COM object only once
$WScriptShell = New-Object -ComObject WScript.Shell
# read and parse the CSV. Supply headers and define the delimiter used
$data = Import-Csv -Path $inputFile -Header 'Shortcut','Target','Icon' -Delimiter ':'
# loop through the data
foreach ($item in $data) {
$ShortcutFile = Join-Path -Path "D:\Projects\PowerShell\Test Environment" -ChildPath ('{0}.lnk' -f $item.Shortcut)
$TargetFile = Join-Path -Path "D:\Projects\PowerShell\Test Environment" -ChildPath $item.Target
$IconFile = Join-Path -Path "D:\Miscellaneous\Other\Backend\Icons" -ChildPath ('{0}.ico' -f $item.Icon)
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = $TargetFile
$Shortcut.IconLocation = $IconFile
$Shortcut.Save()
}
# finally remove the used COM objects from memory
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Shortcut)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WScriptShell)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
CodePudding user response:
Is this how you want your data to be formatted? This is first line of your data, if this is right then it can be looped for other lines too and the shortcut can be created with the rest of your code.
$line = "Random Path 1\Name A – Title A:Random Path 2\Name A – Title A:Random Path 3\Name A – Title A"
$array = $line.split(":")
$array
$shortcutFile = "D:\Projects\PowerShell\Test Environment\" $array[0] ".lnk"
$targetFile = "D:\Projects\PowerShell\Test Environment\" $array[1]
$iconFile = "D:\Miscellaneous\Other\Backend\Icons\" $array[2] ".ico"
Write-Output $shortcutFile
Write-Output $targetFile
Write-Output $iconFile