Reputation: 1722
On many occasions I have needed a path to an executable or command line tool, for example: notepad
or kubectl
. Whilst using PowerShell, the executable is available, but the physical location of the file has not always been easy to find.
One way is to search every folder on the PATH, or even worse the system ( gci -r | % { $_ ...}
), but this is not the most efficient use of time, to re-code every time. Is there a better way?
Upvotes: 7
Views: 13250
Reputation: 1
The 'Get-Command' or "where.exe' are too restrictive, they can't be use for all programms ... Bellow 2 functions that work fine, one to get ShortCut informations, one to get Application information that I use in all my scripts :
Function Get-ShortCut {
param (
[string]$StringToSearch,
[array]$Directories = @(
"${Env:PROGRAMDATA}\Microsoft\Windows\Start Menu\Programs"
"${Env:APPDATA}\Microsoft\Windows\Start Menu\Programs"
),
[string]$TypeTargetFile = "exe"
)
$ShortCutArray = @()
$shellObject = New-Object -ComObject WScript.Shell
foreach ($Directory in $Directories) {
$shortcuts = Get-ChildItem -Path $Directory -Recurse -Filter *.lnk
foreach ($shortcut in $shortcuts) {
$ShortcutObject = $shellObject.CreateShortcut($shortcut.FullName)
if (($ShortcutObject.TargetPath -like "*$StringToSearch*.$TypeTargetFile") -or ($shortcut.BaseName -like "*$StringToSearch*")) {
$ShortCutArray += [PSCustomObject]@{
Name = $shortcut.BaseName
Path = $shortcut.FullName
TargetPath = $ShortcutObject.TargetPath
Arguments = $ShortcutObject.Arguments
WorkingDirectory = $ShortcutObject.WorkingDirectory
IconLocation = $ShortcutObject.IconLocation
Description = $ShortcutObject.Description
WindowStyle = $ShortcutObject.WindowStyle
Hotkey = $ShortcutObject.Hotkey
}
}
}
}
Return $ShortCutArray
} }
Function Get-Application {
param (
[string]$StringToSearch
)
$hives = @(
"HKLM"
"HKCU"
)
$RegistryKeys = @(
"\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
"\SOFTWARE\Wow6432node\Microsoft\Windows\CurrentVersion\Uninstall"
)
$ApplicationArray = @()
ForEach ($hive in $hives) {
ForEach ($RegistryKey in $RegistryKeys) {
if (Test-Path "${hive}:${RegistryKey}" -ErrorAction SilentlyContinue) {
$Applications = Get-ChildItem "${hive}:${RegistryKey}" | ForEach-Object { Get-ItemProperty $_.PsPath } | Select DisplayName,DisplayVersion,InstallDate,UninstallString | Where-Object {$_.DisplayName -match "$StringToSearch"}
ForEach ($Application in $Applications) {
$DisplayName = $Application.DisplayName
$DisplayVersion = $Application.DisplayVersion
$UninstallString = $Application.UninstallString -Replace "`"",""
$InstallDate = $Application.InstallDate
$ApplicationShortCuts = Get-ShortCut $StringToSearch
if ($ApplicationShortCuts.Count -gt 1) {
$WorkingDirectory = $ApplicationShortCuts.WorkingDirectory[0]
$TargetPath = $ApplicationShortCuts.TargetPath[0]
$Arguments = $ApplicationShortCuts.Arguments[0]
} else {
$WorkingDirectory = $ApplicationShortCuts.WorkingDirectory
$TargetPath = $ApplicationShortCuts.TargetPath
$Arguments = $ApplicationShortCuts.Arguments
}
if ((-not $WorkingDirectory) -and $TargetPath) {$WorkingDirectory = Split-Path -Path $TargetPath -Parent}
$ApplicationArray += [PSCustomObject]@{
Name = $DisplayName
Version = $DisplayVersion
InstallDate = $InstallDate
Directory = $WorkingDirectory
Command = $TargetPath
Arguments = $Arguments
UninstallCommand = $UninstallString
}
}
}
}
}
if (-not $ApplicationArray) {
$ApplicationShortCuts = Get-ShortCut $StringToSearch
forEach($ApplicationShortCut in $ApplicationShortCuts) {
$ApplicationName = $ApplicationShortCut.Name
$WorkingDirectory = $ApplicationShortCut.WorkingDirectory
$TargetPath = $ApplicationShortCut.TargetPath
$Arguments = $ApplicationShortCut.Arguments
if ((-not $WorkingDirectory) -and $TargetPath) {$WorkingDirectory = Split-Path -Path $TargetPath -Parent}
$ApplicationArray += [PSCustomObject]@{
Name = $ApplicationName
Version = $Null
InstallDate = $Null
Directory = $WorkingDirectory
Command = $TargetPath
Arguments = $Arguments
UninstallCommand = $Null
}
}
}
Return $ApplicationArray
}
Example :
Get-Application Edge
Name : MSEdgeRedirect
Version : 0.7.4.0 InstallDate : 20230830 Directory : C:\Program Files (x86)\Microsoft\Edge\Application Command : C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe Arguments : UninstallCommand : C:\Program Files\MSEdgeRedirect\MSEdgeRedirect.exe /uninstall
Name : Microsoft Edge Version : InstallDate : 20230612 Directory : C:\Program Files (x86)\Microsoft\Edge\Application Command : C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe Arguments : UninstallCommand : C:\Program Files (x86)\Microsoft\Edge\Application\Installer\setup.exe --uninstall --msedge --channel=stable --system-level --verbose-logging
Name : Microsoft Edge Update Version : 1.3.175.29 InstallDate : Directory : C:\Program Files (x86)\Microsoft\Edge\Application Command : C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe Arguments : UninstallCommand :
Upvotes: 0
Reputation: 10764
Get-Command
will return an object that contains several fields with the pathname. For example, if I type Get-Command notepad
on my system, I get
PS Z:\> Get-Command notepad
CommandType Name Version Source
----------- ---- ------- ------
Application notepad.exe 10.0.18... C:\WINDOWS\system32\notepad.exe
and if I type Get-Command notepad | Select-Object *
I will get
PS Z:\> Get-Command notepad | Select-Object *
HelpUri :
FileVersionInfo : File: C:\WINDOWS\system32\notepad.exe
InternalName: Notepad
OriginalFilename: NOTEPAD.EXE.MUI
FileVersion: 10.0.18362.1 (WinBuild.160101.0800)
FileDescription: Notepad
Product: Microsoft® Windows® Operating System
ProductVersion: 10.0.18362.1
Debug: False
Patched: False
PreRelease: False
PrivateBuild: False
SpecialBuild: False
Language: English (United States)
Path : C:\WINDOWS\system32\notepad.exe
Extension : .exe
Definition : C:\WINDOWS\system32\notepad.exe
Source : C:\WINDOWS\system32\notepad.exe
Version : 10.0.18362.1316
Visibility : Public
OutputType : {System.String}
Name : notepad.exe
CommandType : Application
ModuleName :
Module :
RemotingCapability : PowerShell
Parameters :
ParameterSets :
Upvotes: 13
Reputation: 1722
I recently discovered Where.exe
is available to PowerShell.
> Where.exe kubectl
C:\Program Files\Docker\Docker\resources\bin\kubectl.exe
This is compatible with PowerShell variables so can be used whilst scripting:
$path = where.exe notepad
Upvotes: 5