How can I launch an application via PowerShell in Windows using FolderItem Object [duplicate] - powershell

I am currently trying to get a list of all installed applications and would like to build a feature that can launch those.
I'm using these PowerShell commands:
gci HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | % { Get-ItemProperty $_.PsPath } | Select DisplayName,InstallLocation
gci HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | % { Get-ItemProperty $_.PsPath } | Select DisplayName,InstallLocation
in conjunction with ConvertTo-Json in order to get a good stdout I can work with.
Now, this only gives me the InstallPath without any executables.
Is there any easy way to get the main executable of the applications i nthe list?
Expected Result (Name of the key does not matter):
// ...
{
"DisplayName": "Microsoft Edge",
"InstallLocation": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application",
"LaunchApplication": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\msedge.exe",
},
{
"DisplayName": "Audacity 2.4.2",
"InstallLocation": "C:\\Program Files (x86)\\Audacity\\",
"LaunchApplication": "C:\\Program Files (x86)\\Audacity\\audacity.exe"
},
// ...

Like others have pointed out in the comments, there isn't a conventional way of getting the executable paths of certain programs.
To answer your indirect question of building an app launch method, we can make use of a few things. Fortunately for us, PowerShell has a Get-StartApps cmdlet that produces an output of the current users installed apps:
Name AppID
---- -----
3D Viewer Microsoft.Microsoft3DViewer_8wekyb3d8bbwe!Microsoft.Microsoft3DViewer
AdGuard AdGuard
Adobe Acrobat DC {6D809377-6AF0-444B-8957-A3773F02200E}\Adobe\Acrobat DC\Acrobat\Acrobat.exe
Battle.net {7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\Battle.net\Battle.net Launcher.exe
Blend for Visual Studio 2022 Blend.d58ce8bb
Calculator Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
Calendar microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
There are 2 properties that are displayed:
Name
AppID.
This becomes important due to the AppID being the value needed for shell: to execute/launch the program. Given the above output of Get-StartApps, you can launch "Adobe Acrobat DC" by passing the AppID to shell:\AppsFolder\"AppID".
Start-Process shell:AppsFolder\"{6D809377-6AF0-444B-8957-A3773F02200E}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Using #zett42's approach, we can query your start menu, along with the system start menu folder paths for .lnk's retrieving its target path using the WScript COM object:
$paths = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs","$env:APPDATA\Microsoft\Windows\Start Menu"
Get-ChildItem -Path $paths -Filter "*.lnk" -File -Recurse |
ForEach-Object -Begin {
$WScriptShell = New-Object -ComObject "WScript.Shell"
} -Process {
[PSCustomObject]#{
Name = $_.BaseName
Path = $WScriptShell.CreateShortcut($_.FullName).TargetPath
}
} -End {
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($WScriptShell) #release COM object
}
which will output:
Name Path
---- ----
Adobe Acrobat DC C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe
Blend for Visual Studio 2022 C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Blend.exe
Firefox C:\Program Files\Mozilla Firefox\firefox.exe
Google Chrome C:\Program Files\Google\Chrome\Application\chrome.exe
Microsoft Edge C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
TechPowerUp GPU-Z C:\Program Files (x86)\GPU-Z\GPU-Z.exe
Not entirely sure this is what you're after, but it may be of help to others.

Related

script Outlook with PowerShell 7

I've had a script that I've been using for a long time with PowerShell 5 accessing Outlook. It leverages this:
Add-type -assembly "Microsoft.Office.Interop.Outlook"
I can't seem to find an equivalent for PowerShell 7 (.NET Core). Anyone know what I can use in it's place? I have a script written in 7 that I would like to leverage Outlook for. Thanks
As I understand it, Add-Type in PS7 can add only .NET Core assemblies by name alone, so you'll have to find a path to the file and use -LiteralPath. You can start by looking in one of the following paths:
C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Interop.Outlook\
C:\Program Files (x86)\Microsoft Office\root\Office16\ADDINS\
You could look for the latest version with something like:
$SearchPath = 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Interop.Outlook'
$SearchFilter = 'Microsoft.Office.Interop.Outlook.dll'
$PathToAssembly = Get-ChildItem -LiteralPath $SearchPath -Filter $SearchFilter -Recurse |
Select-Object -ExpandProperty FullName -Last 1
And add the assembly with:
if ($PathToAssembly) {
Add-Type -LiteralPath $PathToAssembly
}
else {
throw "Could not find '$SearchFilter'"
}

Powershell script to find applications that come with their own Java versions

I am looking for a way to find out from all installed applications, one that comes with its own java version. There are scripts online to see the version installed on PCs but not the one to get the applications that uses Java and what versions of java they have.
I found something close with using system explorer where I can view all running processes but what i want is a script that can find such applications with the java versions they use and then export the result as csv file or something.
Get-Childitem –Path c:\ -Include java.exe -Recurse -ErrorAction SilentlyContinue | select FullName
I have also written a one line code that kind of shows few applications (2 in my case) but I know there are more.
Some java.exe files may be buried inside hidden folders. To also list those, add the -Force switch. Something like this:
Get-Childitem -Path 'C:\' -Filter 'java.exe' -Recurse -Force -ErrorAction SilentlyContinue | ForEach-Object {
[PsCustomObject]#{
'Path' = $_.FullName
'Version' = (Get-Command java | Select-Object -ExpandProperty Version)
'ExeVersion' = $_.VersionInfo.ProductVersion
}
}

powershell script for getting extended file property list and signer details inside a directory/path

I want the signer info of a file along with extended properties for the entire directory arranged columnwise in csv format and using the following powershell script to achieve it:
Get-ChildItem "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE" -Recurse |Select-Object -ExpandProperty VersionInfo | select-object FileDescription, OriginalFilename, FileVersion | Get-AuthenticodeSignature "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE" | Export-Csv C:\Users\abc\Documents\c.csv
I get a 0 bytes CSV file on running this script, don't understand if I'm wrong/right because the script doesn't give error on execution

Run PowerShell script (installation of .exe file in silient model) in Vagrant box

I have script which installs software (.exe file) via PowerShell
Get-ChildItem "D:\" -Filter *.exe | Where Name -NotMatch '.*NoDB\.exe$' | % {
New-Object psobject -Property #{
No = [int]([regex]::Match($_.Name, '(?<=CL)\d+').Value)
Name = $_.FullName
}
} | Sort No -Descending | Select -ExpandProperty Name -First 1 |
Foreach { & $_ -s2 -sp"-SilentInstallation=standalone- UpdateMaterials=yestoall -UpgradeDBIfRequired=yes"}
I need to run this script via PowerShell so I created a script for this
# copy installation script to Vagrant folder
Copy-Item -Path "C:\Users\Username\Desktop\Scripts\Installation_Ortho.ps1" -Destination "C:\VagrantBoxes\Win8"
# Navigate to vagrant folder
CD "C:\VagrantBoxes\Win8"
#vagrant powershell
vagrant.exe powershell
# navigate to the folder which is shared with Vagrant
CD "C:\vagrant"
Unfortunately I receive an error
C:\VagrantBoxes\Win8> vagrant powershell
==> default: Detecting if a remote PowerShell connection can be made with the guest...
default: Creating powershell session to 127.0.0.1:55985
default: Username: vagrant
Oops, something went wrong. Please report this bug with the details below.
Report on GitHub: https://github.com/lzybkr/PSReadLine/issues/new
Last 0 Keys:
Exception:
System.IO.IOException: The handle is invalid.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
at Microsoft.PowerShell.PSConsoleReadLine.Initialize(Runspace runspace, EngineIntrinsics engineIntrinsics)
at Microsoft.PowerShell.PSConsoleReadLine.ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics)
I am looking for solution which helps me:
1) Navigate through PowerShell to a folder inside Vagrant box where script is placed;
2) Execute a PowerShell script inside Vagrant box and receive installed software in Vagrant boxe.

Using Powershell to Register a file in the Gac

Is there a simple way to in PowerShell (I imagine using gacutil.exe) to read from a text document a path\assembly and register it in the GAC? So for example a .txt file that looks like:
c:\test\myfile.dll
c:\myfile2.dll
d:\gac\gacthisfile.dll
The PowerShell script would read that into a stream and then run gacutil on each of those assemblies found? I guess it would be something like:
#read files into array?
foreach ($file in Get-ChildItem -Filter "*.dll" )
{
Write-Host $file.Name
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\gacutil.exe /nologo /i $file.Name
}
How about let the .Net worry about gacutil?
# load System.EnterpriseServices assembly
[Reflection.Assembly]::LoadWithPartialName("System.EnterpriseServices") > $null
# create an instance of publish class
[System.EnterpriseServices.Internal.Publish] $publish = new-object System.EnterpriseServices.Internal.Publish
# load and add to gac :)
get-content fileOfDlls.txt | ?{$_ -like "*.dll"} | Foreach-Object {$publish.GacInstall($_)}
If you sort out your text file such that the each dll is on a separate line, you could use the Get-Content command and pipe each to a filter that did your command:
filter gac-item { C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\gacutil.exe /nologo /i $_}
get-content fileOfDlls.txt | ?{$_ -like "*.dll"} | gac-item
I would suggest calling the function to add an assembly to the GAC something following PowerShell guidelines like Add-GacItem. Also the location of gacutil.exe varies based on your system. If you have VS 2008 installed, it should be at the location shown below.
function Add-GacItem([string]$path) {
Begin {
$gacutil="$env:ProgramFiles\Microsoft SDKs\Windows\v6.0A\bin\gacutil.exe"
function AddGacItemImpl([string]$path) {
"& $gacutil /nologo /i $path"
}
}
Process {
if ($_) { AddGacItemImpl $_ }
}
End {
if ($path) { AddGacItemImpl $path }
}
}
Get-Content .\dlls.txt | Split-String | Add-GacItem
Note that the Split-String cmdlet comes from Pscx. The function isn't super robust (no wildcard support doesn't check for weird types like DateTime) but at least it can handle regular invocation and pipeline invocation.
Do you want to replace gacutil.exe? If not, why not use gacutil's included /il switch?
From the gacutil /h:
/il <assembly_path_list_file> [ /r <...> ] [ /f ]
Installs one or more assemblies to the global assembly cache.
<assembly_list_file> is the path to a text file that contains a list of
assembly manifest file paths. Individual paths in the text file must be
separated by CR/LF.
Example: /il MyAssemblyList.txt /r FILEPATH c:\projects\myapp.exe "My App"
myAssemblyList.txt content:
myAsm1.dll
myAsm2.dll
If you create an alias in your profile (just type $profile at a ps prompt to determine this file location) like so new-alias "gac" ($env:ProgramFiles+"\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe") then you can use gac like so:
get-childitem $basedirectory "*$filter.dll" | foreach-object -process{ WRITE-HOST -FOREGROUND GREEN "Processing $_"; gac /i $_.FullName /f}
the last part is the most important. it calls gacutil with the switches you want.
Hope this helps.
This PowerShell script will add assemblies to the GAC without using GacUtil. http://blog.goverco.com/2012/04/use-powershell-to-put-your-assemblies.html
After downloading the Add-AssemblyToGlobalAssemblyCache.ps1 you can deploy to the gac.
Usage example for adding multiple assemblies Dir C:\MyWorkflowAssemblies | % {$_.Fullname} | .\Add-AssemblyToGlobalAssemblyCache.ps1
See the full documentation by running Get-Help .\Add-AssemblyToGlobalAssemblyCache.ps1 -Detailed
Not wanting to install the Windows 8 SDK on all machines I needed to put assemblies in the GAC to get gacutil, I've written a powershell module using the GAC API. It works with any .Net version. With PowerShell GAC you can do it like so:
Get-Content ListOfAssemblies.txt | Add-GacAssembly