Private/AppDiscovery.ps1
|
function New-SldAppCandidate { param( [Parameter(Mandatory)][string]$Name, [Parameter(Mandatory)][ValidateSet('DesktopAppLink', 'PackagedAppId', 'DesktopApplicationId')][string]$SourceType, [Parameter(Mandatory)][string]$Value, [string]$IconPath, [string]$Category = 'Detected' ) [pscustomobject]@{ Name = $Name SourceType = $SourceType Value = $Value IconPath = $IconPath Category = $Category StartSourceType = $SourceType StartValue = $Value TaskbarSourceType = $SourceType TaskbarValue = $Value AlternatePins = @() } } function Get-SldPreferredAppPin { param( [Parameter(Mandatory)][object[]]$App, [Parameter(Mandatory)][ValidateSet('Start', 'Taskbar')][string]$Mode ) $priority = if ($Mode -eq 'Start') { @('DesktopAppLink', 'PackagedAppId', 'DesktopApplicationId') } else { @('DesktopApplicationId', 'DesktopAppLink', 'PackagedAppId') } foreach ($sourceType in $priority) { $match = $App | Where-Object { $_.SourceType -eq $sourceType -and $_.Value } | Select-Object -First 1 if ($match) { return $match } } $App | Select-Object -First 1 } function Merge-SldCandidateApps { param([Parameter(Mandatory)][object[]]$App) $merged = New-Object System.Collections.Generic.List[object] foreach ($group in ($App | Group-Object { $_.Name.Trim().ToLowerInvariant() })) { $items = @($group.Group) $display = $items | Where-Object IconPath | Select-Object -First 1 if (-not $display) { $display = $items | Select-Object -First 1 } $startPin = Get-SldPreferredAppPin -App $items -Mode Start $taskbarPin = Get-SldPreferredAppPin -App $items -Mode Taskbar $sourceTypes = @($items.SourceType | Sort-Object -Unique) $categories = @($items.Category | Sort-Object -Unique) $pinSummary = if ($sourceTypes.Count -gt 1) { 'Start: {0} | Taskbar: {1}' -f $startPin.SourceType, $taskbarPin.SourceType } else { $display.SourceType } $merged.Add([pscustomobject]@{ Name = $display.Name SourceType = if ($sourceTypes.Count -gt 1) { 'App' } else { $display.SourceType } Value = $startPin.Value IconPath = $display.IconPath Category = if ($categories.Count -gt 1) { 'Detected app' } else { $display.Category } PinSummary = $pinSummary StartSourceType = $startPin.SourceType StartValue = $startPin.Value TaskbarSourceType = $taskbarPin.SourceType TaskbarValue = $taskbarPin.Value AlternatePins = @($items | ForEach-Object { [pscustomobject]@{ SourceType = $_.SourceType Value = $_.Value Category = $_.Category } }) }) } $merged } function Get-SldCommonWindowsApps { $apps = @( @{ Name = 'Microsoft Edge'; SourceType = 'DesktopAppLink'; Value = '%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk' }, @{ Name = 'Settings'; SourceType = 'PackagedAppId'; Value = 'windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel' }, @{ Name = 'File Explorer'; SourceType = 'DesktopAppLink'; Value = '%APPDATA%\Microsoft\Windows\Start Menu\Programs\File Explorer.lnk' }, @{ Name = 'Windows Terminal'; SourceType = 'PackagedAppId'; Value = 'Microsoft.WindowsTerminal_8wekyb3d8bbwe!App' }, @{ Name = 'Paint'; SourceType = 'PackagedAppId'; Value = 'Microsoft.Paint_8wekyb3d8bbwe!App' }, @{ Name = 'Photos'; SourceType = 'PackagedAppId'; Value = 'Microsoft.Windows.Photos_8wekyb3d8bbwe!App' }, @{ Name = 'Quick Assist'; SourceType = 'PackagedAppId'; Value = 'MicrosoftCorporationII.QuickAssist_8wekyb3d8bbwe!App' }, @{ Name = 'Sticky Notes'; SourceType = 'PackagedAppId'; Value = 'Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe!App' }, @{ Name = 'Windows Security'; SourceType = 'PackagedAppId'; Value = 'Microsoft.SecHealthUI_8wekyb3d8bbwe!SecHealthUI' }, @{ Name = 'Outlook for Windows'; SourceType = 'PackagedAppId'; Value = 'Microsoft.OutlookForWindows_8wekyb3d8bbwe!Microsoft.OutlookforWindows' }, @{ Name = 'Command Prompt'; SourceType = 'DesktopAppLink'; Value = '%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Command Prompt.lnk' }, @{ Name = 'Windows PowerShell'; SourceType = 'DesktopAppLink'; Value = '%APPDATA%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk' } ) foreach ($app in $apps) { New-SldAppCandidate -Name $app.Name -SourceType $app.SourceType -Value $app.Value -Category 'Common' } } function ConvertTo-SldEnvironmentPath { param([Parameter(Mandatory)][string]$Path) $appData = [Environment]::GetFolderPath('ApplicationData') $programData = [Environment]::GetFolderPath('CommonApplicationData') if ($Path.StartsWith($appData, [StringComparison]::OrdinalIgnoreCase)) { return $Path.Replace($appData, '%APPDATA%') } if ($Path.StartsWith($programData, [StringComparison]::OrdinalIgnoreCase)) { return $Path.Replace($programData, '%ALLUSERSPROFILE%') } $Path } function Get-SldDesktopShortcutApps { $paths = @( [Environment]::GetFolderPath('Programs'), [Environment]::GetFolderPath('CommonPrograms') ) | Where-Object { $_ -and (Test-Path -LiteralPath $_) } foreach ($path in $paths) { Get-ChildItem -LiteralPath $path -Filter '*.lnk' -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $linkPath = ConvertTo-SldEnvironmentPath -Path $_.FullName $iconPath = Get-SldShortcutIconPath -Path $_.FullName New-SldAppCandidate -Name $_.BaseName -SourceType 'DesktopAppLink' -Value $linkPath -IconPath $iconPath -Category 'Desktop shortcut' } } } function Get-SldPackagedApps { if (-not (Get-Command Get-StartApps -ErrorAction SilentlyContinue)) { return } Get-StartApps | Where-Object { $_.AppID -and $_.Name } | Sort-Object Name | ForEach-Object { $sourceType = if ($_.AppID -match '^.+_.+!.+$') { 'PackagedAppId' } else { 'DesktopApplicationId' } $category = if ($sourceType -eq 'PackagedAppId') { 'Packaged app' } else { 'Desktop app (AUMID)' } New-SldAppCandidate -Name $_.Name -SourceType $sourceType -Value $_.AppID -Category $category } } function Get-SldCandidateApps { param( [switch]$IncludePackagedApps, [switch]$IncludeDesktopShortcuts, [switch]$IncludeCommonWindowsApps ) $seen = @{} $apps = New-Object System.Collections.Generic.List[object] foreach ($app in @( if ($IncludeCommonWindowsApps) { Get-SldCommonWindowsApps } if ($IncludeDesktopShortcuts) { Get-SldDesktopShortcutApps } if ($IncludePackagedApps) { Get-SldPackagedApps } )) { $key = '{0}|{1}' -f $app.SourceType, $app.Value if (-not $seen.ContainsKey($key)) { $seen[$key] = $true [void]$apps.Add($app) } } Merge-SldCandidateApps -App @($apps.ToArray()) | Sort-Object Category, Name } |