0

I found a snippet on the internet that does this

 function Get-DesktopShortcuts{
    $Shortcuts = Get-ChildItem -Recurse "C:\users\public\Desktop" -Include *.lnk
    $Shell = New-Object -ComObject WScript.Shell
    foreach ($Shortcut in $Shortcuts)
    {
        $Properties = @{
        ShortcutName = $Shortcut.Name;
        ShortcutFull = $Shortcut.FullName;
        ShortcutPath = $shortcut.DirectoryName
        Target = $Shell.CreateShortcut($Shortcut).targetpath
        }
        New-Object PSObject -Property $Properties
    }

[Runtime.InteropServices.Marshal]::ReleaseComObject($Shell) | Out-Null
}

But I am unsure how to manipulate the results.

$output = get-desktopshortcuts stores the results, and I can output it all $output | out-gridview but if Target had foo.exe, I want just the path, C:\Program Files\Foo Enterprises. Since there is no guaranteed way for me to know if the enduser installed it into a non-default location, and of course the shortcut isn't guaranteed, but then i will return the default for worse case scenario.

Thank you!

Jon Weinraub
  • 397
  • 1
  • 8
  • 18
  • `$paths = Get-DesktopShortcuts | ForEach-Object { Split-Path $_.ShortcutFull -Parent }` ? – Bill_Stewart Aug 06 '19 at 17:16
  • How do I search for a specific substring? This will just out put c:\users\public\desktop for every icon i have. I need the target of a specific substring in program files. – Jon Weinraub Aug 06 '19 at 17:19
  • When you "open" the shortcut (with the `CreateShortcut()` method), the `TargetPath` member contains the path of the file that the shortcut points to, which is what you appear to want. See [this question](https://stackoverflow.com/questions/42762122/get-target-of-shortcut-lnk-file-with-powershell/). – Jeff Zeitlin Aug 06 '19 at 17:23
  • Possible duplicate of [Get target of shortcut (.lnk) file with powershell](https://stackoverflow.com/questions/42762122/get-target-of-shortcut-lnk-file-with-powershell) – Jeff Zeitlin Aug 06 '19 at 17:24
  • Sorry, that should be `$_.Target` rather than `$_.ShortcutFull` – Bill_Stewart Aug 06 '19 at 17:25
  • @Bill_Stewart - Actually, it's `$_.TargetPath` - see the proposed duplicate. – Jeff Zeitlin Aug 06 '19 at 19:16
  • Don't think so (the output object uses the property `Target`) – Bill_Stewart Aug 06 '19 at 20:44
  • But aside from all this, a good problem description would be helpful. What is the specific goal/purpose of this script and why does checking desktop shortcuts help? (Example: What if the program is installed but the end user deleted the shortcut to it?) – Bill_Stewart Aug 06 '19 at 20:45
  • The purpose is for PDQ Deploy post-processing. The path of an install is unknown since the user may not have placed the install in a default location, so I can't assume it is in it. I kinda mentioned in the descriptuon the reasoning what I need, though it was vague, it wasn't intentionally so. I didn't want it to be too descriptive for fearing it would be not the scope of the site for being only a single purpose, so i was hesitant and made it more broad. – Jon Weinraub Aug 06 '19 at 20:50
  • Why not check the registry for what's installed? (It doesn't seem to me that checking paths in desktop shortcuts is anywhere near reliable enough. – Bill_Stewart Aug 06 '19 at 23:32
  • I actually tried that first and screwed up the registry read and failed so I tried this method instead. I finally got it working, registry method that is. But now I kinda want to see if I can get this to work too, mainly to learn new things. – Jon Weinraub Aug 07 '19 at 02:02
  • @Bill_Stewart - Good catch; somehow I missed that the routine was creating its own object instead of just passing the shortcut through. – Jeff Zeitlin Aug 07 '19 at 10:55

2 Answers2

0

Once you have the full filename of the file you are interested in, you can use the Split-Path cmdlet to get the directory that the file is located in. For example, if you have a filename with path in $target,

Split-Path -Path $target -Parent

will return the path without the filename, e.g., C:\Windows\System32 if $target happened to be C:\Windows\System32\Notepad.exe.

You can find out more on Split-Path at Microsoft Docs.

Jeff Zeitlin
  • 9,773
  • 2
  • 21
  • 33
  • Right but I don't know how to select and find the correct substring, "FOO.EXE", like something like `$output = Get-DesktopShortcuts | ForEach-Object { Split-Path $_.Target = "FOO.EXE" -Parent }` – Jon Weinraub Aug 06 '19 at 19:13
  • I ***strongly*** urge you to look at the proposed duplicate question. – Jeff Zeitlin Aug 06 '19 at 19:14
  • Wouldn't it be better to either have the substring I want to find part of the function, return path if TargetPath == "foo.exe"? I am reading the proposed duplicate and while I do see some similarities I don't think it applies that directly to what I am trying to accomplish. – Jon Weinraub Aug 06 '19 at 19:31
  • If you have a _shortcut_ on the desktop, and you want to find out the folder that the _actual program that the shortcut 'points' to_ is installed in, the proposed duplicate tells you _exactly_ what you need to know - you need to get the `TargetPath` of the shortcut, which will normally contain the full path of the program invoked, and then you need to use `Split-Path` to get the parent of that file. If that's not what you're looking for, then you need to rewrite your question to make it clear what you are looking for, including _examples_. – Jeff Zeitlin Aug 06 '19 at 19:34
  • I am sorry Jeff, maybe I am braindead today. When I run ` Get-DesktopShortcuts | ForEach-Object { Split-Path $_.Target. -Parent }` it outputs the paths of all shortcuts in public desktop. I only want a single path returned from that foreach function, the one looking for a specific target, "FOO.EXE". Since the proposed answer isn't answering question *directly*, can you please answer my question? I am still trying to learn PowerShell and playing a guessing game won't help me learn. – Jon Weinraub Aug 06 '19 at 19:47
  • 1
    `Get-DesktopShortcuts | Where-Object {$_.TargetPath -match "FOO.EXE"} | Split-Path -Parent` – Jeff Zeitlin Aug 06 '19 at 20:01
  • Thnak you for putting me in right direction, though this outputs nothing. If I use $_.Target, the correct object gets returned, but the path prints nothing as is. I will figure this out I hope. – Jon Weinraub Aug 06 '19 at 20:48
  • I missed that your `Get-DesktopShortcuts` is generating a new object instead of just passing the shortcut through. Try using `$_.Target` in the `Where-Object` instead of `$_.TargetPath`. – Jeff Zeitlin Aug 07 '19 at 10:56
0

Using the function I already had above, I played around and found a rather elegant way, which works.

$sc = Get-DesktopShortcuts
$target = $sc."Target" | select-string -pattern "FOO"
split-path -parent $target

Yes, it does assume the shortcut exists, but in the end, it answered what I asked.

Jon Weinraub
  • 397
  • 1
  • 8
  • 18