Trying to compare list of shortcuts on one machine to saved list

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of Ian Follett Ian Follett 3 months, 3 weeks ago.

  • Author
    Posts
  • #49778
    Profile photo of Ian Follett
    Ian Follett
    Participant

    Basically what I want to create is a PowerShell script to compare the applications included in an OEM install of Windows 10 against those included in a clean install of Windows 10 and copy any application links which aren't on a clean install to a specific folder so that I can easily see which apps have been added by the OEM.

    I've figured out how to get a list of which applications have links on the Start Menu:

    $Path = "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs"
    Get-ChildItem $Path -Recurse -Include *.lnk

    And I've figured out how to assign that to an array:

    $a = Get-ChildItem $Path -Recurse -Include *.lnk

    Or how to copy that list of shortcuts to a folder:

    Get-ChildItem $Path -Recurse -Include *.lnk | Copy-Item -Destination C:\temp\

    Or save the list to a CSV:

    Get-ChildItem $Path -Recurse -Include *.lnk | Export-Csv list.csv

    And how to assign a CSV to an array:

    $b = Import-Csv list.csv

    And how to compare two arrays:

    Compare-Object $a $b

    But this is where I get stuck. I want to be able to do this:

    Run this on a computer with no 3rd party apps, only a clean Windows 10 install:

    $Path = "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs"           
    Get-ChildItem $Path -Recurse -Include *.lnk | Export-Csv cleaninstallapps.csv

    Then take the cleaninstallapps.csv and copy it to a computer with 3rd party apps on it and get a list of only the apps which are not part of a clean Windows 10 install. And then copy links to those apps to a folder by doing this:

    $Path = "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs”
    Get-ChildItem $Path -Recurse -Include *.lnk | | Export-Csv oeminstallapps.csv
    $a = Import-Csv oeminstallapps.csv
    $b = Import-Csv cleaninstallapps.csv
    Compare-Object $a $b | Copy-Item –Destination C:\OEM_Programs

    Everything works up until it gets piped to Copy-Item. Something is lost that doesn't stop Compare-Object from working but does stop me from successfully piping that to Copy-Item. Any ideas for how to accomplish this task?

  • #49806
    Profile photo of Erik Sundin
    Erik Sundin
    Participant

    Hi,
    Copy-Item copies files and folders, not arrays, I suggest using Export-Csv again instead.
    Checking Start Menu for installed programs is not a good way to go, programs doesn´t need to have start menu shortcuts. This might be a good read: Use PowerShell to Quickly Find Installed Software

    • #49871
      Profile photo of Ian Follett
      Ian Follett
      Participant

      Erik, thanks for the article. I should be a little more clear about my purpose. I want to easily test the functionality of any application a user would be likely to open which isn't part of a clean Windows 10 install. That's why I'm checking for shortcuts rather than all installed programs and also why I want to create a folder with shortcuts to those programs. What I want is for a tester to be able to run a script on a device which opens up a folder with all of the non clean install programs in it so he can easily open and test each of them.

      Dan, I like that code. I'll use that instead of Compare-Object.

  • #49823
    Profile photo of Dan Potter
    Dan Potter
    Participant

    I find the compare-object confusing.

    $a = (1..10)
    $b = (1..15)
    $b | ? {$_ -notin $a}

  • #49875
    Profile photo of Dan Potter
    Dan Potter
    Participant

    It does have it's uses. You can do compare $a $b -IncludeEqual | ? {$_.sideindicator -eq '=>'}

    When dealing with large similar arrays I get confused as to whether I compared fruit to vegetables or vegetables to fruit. The greatthan lessthan signs aren't good indicators for my brain to process:D

  • #49985
    Profile photo of Erik Sundin
    Erik Sundin
    Participant

    Like I said earlier, Copy-Item can´t copy an array, when you export and then import from csv you loose the objects that you got from Get-ChildItem. If you skip that step and use Where-Object to filter your objects you´ll get what you want, something like:

    $Path = "$Env:ProgramData\Microsoft\Windows\Start Menu\Programs”
    $a = Get-ChildItem $Path -Recurse -Include *.lnk
    $b = Import-Csv cleaninstallapps.csv
    $a | Where-Object {$_.name -notin $b.name} | Copy-Item –Destination C:\OEM_Programs

    Also, if some of the file names from the clean install contains special characters you need to use the -Encoding parameter for both Export-Csv and Import-Csv (example: Import-Csv -Encoding UTF8 cleaninstallapps.csv) else the imported file names will contain ? as a replacement for every special character.

    • #50032
      Profile photo of Ian Follett
      Ian Follett
      Participant

      That worked perfectly! Thank you very much for helping me with this and taking the time to explain what I was doing wrong!

You must be logged in to reply to this topic.