ObjectShell looping issues

Hi all,

I’m trying to create a function that will loop through a certain directory and adjust the icons in there to my liking.

Roughly my code contains a bit of this:

# get all shortcuts
$Lnks = Get-ChildItem $Path -Filter *.Lnk -Recurse

# start loopy loop
foreach ($Lnk in $Lnks)
    # get the shortcut object
    $ObjectShell = New-Object -ComObject WScript.Shell
    $ShortCut = $ObjectShell.CreateShortcut($Lnk)

    # change shortcut details
    $Arguments = "something new"
    $Icon = "a new icon file"
    $TargetPath = "new targetpath thingy"
    $WorkingDirectory = "new worky dir"

    # set shortcut details
    $ShortCut.Arguments = $Arguments
    $ShortCut.IconLocation = "$Icon"
    $ShortCut.TargetPath = $TargetPath
    $ShortCut.WorkingDirectory = $WorkingDirectory

    # presto, lets save the shorcut

Obviously I’ve left out all the details, but the shortcuts get all their arguments dynamically based on what they already contain. The script itself works…but…

When I use it in the loop, only the first shortcut gets processed, the rest remain unaltered.
It seems when using the ObjectShell part, it somehow breaks when trying to use that in a loop.
Is this something someone else is familiar with? Do I need to cleanup the Shell object in each loop, or should I maybe use a Start-Job kinda solution for this?

Thanks in advance!

Hi, welcome back :wave:

Your example code is working fine for me.

foreach ($Lnk in $Lnks)

Appending an ‘s’ like this often leads to mistakes with the variable names. Are you sure you’ve not got a typo somewhere in your actual code?

Hi Matt,

Thanks for your reply!

After some tweaking I finally got it to work, the problem was not in the foreach naming, but I did took your advice to heart and changed it to something a bit more readable.

There was more at hand then I first thought. Apparantly I had a Set-Location issue, which caused a lot of icons suddenly to be stored at my “C:\User\MyUsername” folder instead of the original shortcut location.
And in the foreach loop, I had to define a Get-Item for each of the shortcuts found, not sure why that is though.

I also had a issue with the Shortcut argument having required quotes in them, but changing the shortcut, would give me double quotes. Now, I’m a big fan of quotes, but this was getting out of hand. I solved that part, by filtering out the quotes and reassamble them later on. Basically I fixed it with the changes below.

Set-Location -Path $Path

foreach ($Link in $Shortcuts) {restofcode}

$ShortCut = $ObjectShell.CreateShortcut((Get-Item $Link))
$ShortCutPath = $ShortCut.Arguments -replace ('"','') |Split-Path

if (!$StartIn) {$WorkingDirectory = $ShortCutPath}
else {$WorkingDirectory = $StartIn}

I created the function so I could change the shortcuts for my games in bulk, after which I can start them with DosBox (or ScummVM, or any other emulator). It relies on all the games having the same “Play.bat” and “icon.ico” files, so that they can all be changed accordingly

If however someone is interested in the complete function, I can post it here, free of charge :wink:

Thanks again for the support and until we troubleshoot again…