Query WinGet software installer data with PowerShell

Light
Dark

I’m a big fan of WinGet, and the software available in their ecosystem is growing daily. Still, I’m always curious about what WinGet will download and how it does the silent install of the specified software. In this blog post, I will show you an easy way of retrieving that data 🙂

What is WinGet?

“The WinGet command line tool enables users to discover, install, upgrade, remove and configure applications on Windows 10 and Windows 11 computers. This tool is the client interface to the Windows Package Manager service.”

Source: https://learn.microsoft.com/en-us/windows/package-manager/winget/

The WinGet repository and YAML

The WinGet client uses a GitHub repository to query for software, its installation links, and installation commands. That repository can be found here. There, you will find the manifests folder, in which all the software is structured per letter and version. For example, the latest Adobe Acrobat Reader 64-bit version is in the “a/Adobe/Acrobat/Reader/64-bit/24.003.20180” folder. That made me think I could find software based on the name and version using the WinGet PowerShell Module and read the YAML file inside the correct folder to see all the installation details.

An example YAML file, the one from the Adobe Acrobat Reader as mentioned above, looks like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Created using wingetcreate 1.6.5.0
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json
PackageIdentifier: Adobe.Acrobat.Reader.64-bit
PackageVersion: 24.003.20180
MinimumOSVersion: 10.0.0.0
InstallerType: exe
Scope: machine
InstallModes:
- interactive
- silent
- silentWithProgress
InstallerSwitches:
Silent: /sAll /rs /rps /l /re
SilentWithProgress: /sAll /rs /rps /l /re
UpgradeBehavior: install
FileExtensions:
- pdf
- pdfa
- pdfx
- xfx
ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}'
AppsAndFeaturesEntries:
- DisplayName: Adobe Acrobat DC (64-bit)
Publisher: Adobe
ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}'
InstallerType: msi
Installers:
- Architecture: x64
InstallerUrl: https://ardownload2.adobe.com/pub/adobe/acrobat/win/AcrobatDC/2400320180/AcroRdrDCx642400320180_MUI.exe
InstallerSha256: 8DDE05B5A2F4E8550D54CD071BB9D57D273813B92E22E82124C18C8B948FF609
ManifestType: installer
ManifestVersion: 1.6.0
# Created using wingetcreate 1.6.5.0 # yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json PackageIdentifier: Adobe.Acrobat.Reader.64-bit PackageVersion: 24.003.20180 MinimumOSVersion: 10.0.0.0 InstallerType: exe Scope: machine InstallModes: - interactive - silent - silentWithProgress InstallerSwitches: Silent: /sAll /rs /rps /l /re SilentWithProgress: /sAll /rs /rps /l /re UpgradeBehavior: install FileExtensions: - pdf - pdfa - pdfx - xfx ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}' AppsAndFeaturesEntries: - DisplayName: Adobe Acrobat DC (64-bit) Publisher: Adobe ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}' InstallerType: msi Installers: - Architecture: x64 InstallerUrl: https://ardownload2.adobe.com/pub/adobe/acrobat/win/AcrobatDC/2400320180/AcroRdrDCx642400320180_MUI.exe InstallerSha256: 8DDE05B5A2F4E8550D54CD071BB9D57D273813B92E22E82124C18C8B948FF609 ManifestType: installer ManifestVersion: 1.6.0
# Created using wingetcreate 1.6.5.0
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json

PackageIdentifier: Adobe.Acrobat.Reader.64-bit
PackageVersion: 24.003.20180
MinimumOSVersion: 10.0.0.0
InstallerType: exe
Scope: machine
InstallModes:
- interactive
- silent
- silentWithProgress
InstallerSwitches:
  Silent: /sAll /rs /rps /l /re
  SilentWithProgress: /sAll /rs /rps /l /re
UpgradeBehavior: install
FileExtensions:
- pdf
- pdfa
- pdfx
- xfx
ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}'
AppsAndFeaturesEntries:
- DisplayName: Adobe Acrobat DC (64-bit)
  Publisher: Adobe
  ProductCode: '{AC76BA86-1033-FF00-7760-BC15014EA700}'
  InstallerType: msi
Installers:
- Architecture: x64
  InstallerUrl: https://ardownload2.adobe.com/pub/adobe/acrobat/win/AcrobatDC/2400320180/AcroRdrDCx642400320180_MUI.exe
  InstallerSha256: 8DDE05B5A2F4E8550D54CD071BB9D57D273813B92E22E82124C18C8B948FF609
ManifestType: installer
ManifestVersion: 1.6.0

How the script works

As shown above, the information is in YAML format, so I can use the PowerShell-YAML module to parse that information and create a little report of one or more packages. The script will prompt you to enter the packages that you want to query and if you want the output on your screen (Default in List format, but ConsoleGridView and GridView are available. You can also output the results to a .csv or .xlsx file if needed. All the modules for the script will be installed automatically if required.

The Parameters that you can use when running the Get-WinGetData.ps1 script:

  • ApplicationName is the default and mandatory Parameter in which you can specify one or more applications you want to query. For example, Get-WinGetData.ps1 -ApplicationName Notepad, Adobe will list all the NotePad and Adobe applications in a ConsoleGridView pane in which you can select the ones that you want by selecting them with the spacebar and hitting Enter. (It will show two different ConsoleGridView panes, one for Notepad and one for Adobe)
  • Output is the Parameter with the ConsoleGridView, GridView, and List (Which is the default) values. For example, Get-WinGetData.ps1 -ApplicationName Notepad, Adobe -Output ConsoleGridView will show the results in a searchable Console GridView. It can be combined with the FilenameParameter.
  • Filename is the parameter to specify a .csv or .xlsx file to which to output the results. For example, Get-WinGetData.ps1 -ApplicationName Notepad, Adobe -Filename c:\temp\WinGet.xlsx will export the results to c:\temp\WinGet.xlsx. It can be combined with the Output Parameter, and the results will be appended to an Excel file if they already exist.

Note: Because I use the ConsoleGridView module, you can only run this script in PowerShell v7.

Running the script

Below is an example where I specify Adobe and Notepad as a query. I will select a few results for both and show the output on the screen and in the Excel file WinGet.xlsx. I did this by running:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
.\Get-WinGetData.ps1 -ApplicationName Adobe, Notepad -Filename C:\Temp\WinGet.xlsx
.\Get-WinGetData.ps1 -ApplicationName Adobe, Notepad -Filename C:\Temp\WinGet.xlsx
.\Get-WinGetData.ps1 -ApplicationName Adobe, Notepad -Filename C:\Temp\WinGet.xlsx

In the first screen, I can select the desired Adobe software from the WinGet repository by choosing the items using the spacebar and hitting Enter:

I selected Adobe Acrobat Reader DC (64-bit) and Acrobat Pro (64-bit). On the next screen (After hitting Enter to Accept these two choices), I selected Notepad++ and XML Notepad and hit Enter to Accept those two:

It will show the progress of the four applications and output the information on the screen and where it saved the Excel file (c:\temp\WinGet.xlsx).:

As you can see, not all the software has all the information. Sometimes, the silent and silent with progress switches are unavailable (Depending on the type of software), or not all information was supplied in the YAML file.

The Excel file looks like this:

Wrapping up

In this blog post, I showed you how to query the WinGet repository and output the information about how it installs software on your system. It is easy for creating packages and an excellent reference for install links and installation switches 🙂

The script

Below are the contents of the Get-WinGetData.ps1 script. Save it to c:\scripts, for example, and use it to retrieve all the installation data available through the WinGet repository.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
param (
[Parameter(Mandatory = $true)][string[]]$ApplicationName,
[Parameter(Mandatory = $false)][validateset('ConsoleGridView', 'GridView', 'List')][string]$Output = 'List',
[Parameter(Mandatory = $false)][string]$Filename
)
#Check if the required modules are installed
foreach ($module in 'Microsoft.WinGet.Client', 'Microsoft.PowerShell.ConsoleGuiTools', 'powershell-yaml') {
if (-not (Get-Module -Name $module -ListAvailable)) {
try {
Write-Warning ("The required module {0} was not found, installing now..." -f $module)
Install-Module -Name $module -Scope CurrentUser -ErrorAction Stop
Import-Module -Name $module -ErrorAction Stop
}
catch {
Write-Warning ("Error installing/importing required {0} module, exiting..." -f $module)
return
}
}
else {
try {
Import-Module -Name $module -ErrorAction Stop
}
catch {
Write-Warning ("Error importing required $module module, exiting...")
return
}
}
}
#Check $applicationname, select the application the from Out-ConsoleGridView
$Applications = foreach ($Application in $ApplicationName) {
try {
$results = Find-WinGetPackage $Application -Source WinGet -ErrorAction Stop | Out-ConsoleGridView -Title "Select the application from the list for selected $($Application) query" -OutputMode Multiple
foreach ($result in $results) {
[PSCustomObject]@{
ID = $result.ID
Version = $result.Version
}
}
}
catch {
Write-Warning ("The application(details) could not be found, exiting...")
return
}
}
#Loop through the applications and collect the details, exit if no applications were found or selected
if ($null -ne $Applications) {
$total = foreach ($item in $Applications | Sort-Object ID) {
Write-Host ("Processing {0}..." -f $item.ID) -ForegroundColor Green
try {
$ApplicationYAML = Invoke-RestMethod ("https://raw.githubusercontent.com/microsoft/winget-pkgs/refs/heads/master/manifests/{0}/{1}/{2}/$($Item.ID).installer.yaml" -f $Item.ID.Substring(0, 1).ToLower(), $Item.ID.Replace('.', '/'), $Item.version) -UseBasicParsing -Method Get -ErrorAction Stop | ConvertFrom-Yaml -ErrorAction Stop
foreach ($installer in $ApplicationYAML.Installers) {
$applicationdetails = Get-WinGetPackageInfo -Id $item.ID -ErrorAction Stop
[PSCustomObject]@{
'Name' = $item.ID
'Author' = if ($applicationdetails.Author) { $applicationdetails.Author } else { "Not found" }
'Version' = [version]$item.Version
'Release Date' = if ($applicationdetails.'Release Date') { $applicationdetails.'Release Date' } else { "Not found" }
'Install Modes' = if ($ApplicationYAML.InstallModes) { $ApplicationYAML.InstallModes -join ', ' } else { "Not found" }
'Installer Architecture' = if ($installer.Architecture) { $installer.Architecture } else { "Not found" }
'Silent switches' = if ($applicationYAML.InstallerSwitches.Silent) { $applicationYAML.InstallerSwitches.Silent } else { "Not found" }
'SilentWithProgress switches' = if ($applicationYAML.InstallerSwitches.SilentWithProgress) { $applicationYAML.InstallerSwitches.SilentWithProgress } else { "Not found" }
'Installer Type' = if ($applicationYAML.InstallerType) { $applicationYAML.InstallerType } else { "Not found" }
'Installer URL' = if ($installer.Installerurl) { $installer.Installerurl } else { "Not found" }
'HomePage' = if ($applicationdetails.HomePage) { $applicationdetails.HomePage } else { "Not found" }
}
}
}
catch {
Write-Warning ("Error retrieving details for {0}" -f $item.id)
}
}
}
else {
Write-Warning ("No applications were found or selected, exiting...")
return
}
#If $total has items, output it to display or file
if ($null -ne $total) {
#Display $total to the chosen $ouput value if $FileName was not used
if ($Output) {
switch ($Output) {
ConsoleGridView {
try {
$total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-ConsoleGridView -Title 'WinGet Information'
}
catch {
Write-Warning ("Error sending information to Out-ConsoleGridview, exiting...")
return
}
}
GridView {
try {
$total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-GridView -Title 'WinGet Information'
}
catch {
Write-Warning ("Error sending information to Out-Gridview, exiting...")
return
}
}
List {
try {
$total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Format-List
}
catch {
Write-Warning ("Error sending information to Format-List, exiting...")
return
}
}
}
}
#Export to file if $FileName was specified
if ($Filename) {
if ($Filename.EndsWith('csv')) {
try {
$total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Csv -Path $Filename -Encoding UTF8 -NoTypeInformation -Delimiter ';' -Append:$true -Force:$true -ErrorAction Stop
Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green
}
catch {
Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename)
return
}
}
if ($Filename.EndsWith('xlsx')) {
if (-not (Get-Module ImportExcel -ListAvailable)) {
try {
Install-Module ImportExcel -Scope CurrentUser -ErrorAction Stop
Import-Module ImportExcel -ErrorAction Stop
Write-Host ('Installed missing PowerShell Module ImportExcel which is needed for XLSX output') -ForegroundColor Green
}
catch {
Write-Warning ('Could not install missing PowerShell Module ImportExcel which is needed for XLSX output, exiting...')
return
}
}
try {
$total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Excel -Path $Filename -AutoSize -AutoFilter -Append:$true -ErrorAction Stop
Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green
}
catch {
Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename)
return
}
}
}
}
else {
Write-Warning ('Specified application(s) were not found, exiting...')
return
}
param ( [Parameter(Mandatory = $true)][string[]]$ApplicationName, [Parameter(Mandatory = $false)][validateset('ConsoleGridView', 'GridView', 'List')][string]$Output = 'List', [Parameter(Mandatory = $false)][string]$Filename ) #Check if the required modules are installed foreach ($module in 'Microsoft.WinGet.Client', 'Microsoft.PowerShell.ConsoleGuiTools', 'powershell-yaml') { if (-not (Get-Module -Name $module -ListAvailable)) { try { Write-Warning ("The required module {0} was not found, installing now..." -f $module) Install-Module -Name $module -Scope CurrentUser -ErrorAction Stop Import-Module -Name $module -ErrorAction Stop } catch { Write-Warning ("Error installing/importing required {0} module, exiting..." -f $module) return } } else { try { Import-Module -Name $module -ErrorAction Stop } catch { Write-Warning ("Error importing required $module module, exiting...") return } } } #Check $applicationname, select the application the from Out-ConsoleGridView $Applications = foreach ($Application in $ApplicationName) { try { $results = Find-WinGetPackage $Application -Source WinGet -ErrorAction Stop | Out-ConsoleGridView -Title "Select the application from the list for selected $($Application) query" -OutputMode Multiple foreach ($result in $results) { [PSCustomObject]@{ ID = $result.ID Version = $result.Version } } } catch { Write-Warning ("The application(details) could not be found, exiting...") return } } #Loop through the applications and collect the details, exit if no applications were found or selected if ($null -ne $Applications) { $total = foreach ($item in $Applications | Sort-Object ID) { Write-Host ("Processing {0}..." -f $item.ID) -ForegroundColor Green try { $ApplicationYAML = Invoke-RestMethod ("https://raw.githubusercontent.com/microsoft/winget-pkgs/refs/heads/master/manifests/{0}/{1}/{2}/$($Item.ID).installer.yaml" -f $Item.ID.Substring(0, 1).ToLower(), $Item.ID.Replace('.', '/'), $Item.version) -UseBasicParsing -Method Get -ErrorAction Stop | ConvertFrom-Yaml -ErrorAction Stop foreach ($installer in $ApplicationYAML.Installers) { $applicationdetails = Get-WinGetPackageInfo -Id $item.ID -ErrorAction Stop [PSCustomObject]@{ 'Name' = $item.ID 'Author' = if ($applicationdetails.Author) { $applicationdetails.Author } else { "Not found" } 'Version' = [version]$item.Version 'Release Date' = if ($applicationdetails.'Release Date') { $applicationdetails.'Release Date' } else { "Not found" } 'Install Modes' = if ($ApplicationYAML.InstallModes) { $ApplicationYAML.InstallModes -join ', ' } else { "Not found" } 'Installer Architecture' = if ($installer.Architecture) { $installer.Architecture } else { "Not found" } 'Silent switches' = if ($applicationYAML.InstallerSwitches.Silent) { $applicationYAML.InstallerSwitches.Silent } else { "Not found" } 'SilentWithProgress switches' = if ($applicationYAML.InstallerSwitches.SilentWithProgress) { $applicationYAML.InstallerSwitches.SilentWithProgress } else { "Not found" } 'Installer Type' = if ($applicationYAML.InstallerType) { $applicationYAML.InstallerType } else { "Not found" } 'Installer URL' = if ($installer.Installerurl) { $installer.Installerurl } else { "Not found" } 'HomePage' = if ($applicationdetails.HomePage) { $applicationdetails.HomePage } else { "Not found" } } } } catch { Write-Warning ("Error retrieving details for {0}" -f $item.id) } } } else { Write-Warning ("No applications were found or selected, exiting...") return } #If $total has items, output it to display or file if ($null -ne $total) { #Display $total to the chosen $ouput value if $FileName was not used if ($Output) { switch ($Output) { ConsoleGridView { try { $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-ConsoleGridView -Title 'WinGet Information' } catch { Write-Warning ("Error sending information to Out-ConsoleGridview, exiting...") return } } GridView { try { $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-GridView -Title 'WinGet Information' } catch { Write-Warning ("Error sending information to Out-Gridview, exiting...") return } } List { try { $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Format-List } catch { Write-Warning ("Error sending information to Format-List, exiting...") return } } } } #Export to file if $FileName was specified if ($Filename) { if ($Filename.EndsWith('csv')) { try { $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Csv -Path $Filename -Encoding UTF8 -NoTypeInformation -Delimiter ';' -Append:$true -Force:$true -ErrorAction Stop Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green } catch { Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename) return } } if ($Filename.EndsWith('xlsx')) { if (-not (Get-Module ImportExcel -ListAvailable)) { try { Install-Module ImportExcel -Scope CurrentUser -ErrorAction Stop Import-Module ImportExcel -ErrorAction Stop Write-Host ('Installed missing PowerShell Module ImportExcel which is needed for XLSX output') -ForegroundColor Green } catch { Write-Warning ('Could not install missing PowerShell Module ImportExcel which is needed for XLSX output, exiting...') return } } try { $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Excel -Path $Filename -AutoSize -AutoFilter -Append:$true -ErrorAction Stop Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green } catch { Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename) return } } } } else { Write-Warning ('Specified application(s) were not found, exiting...') return }
param (
    [Parameter(Mandatory = $true)][string[]]$ApplicationName,
    [Parameter(Mandatory = $false)][validateset('ConsoleGridView', 'GridView', 'List')][string]$Output = 'List',
    [Parameter(Mandatory = $false)][string]$Filename
)
    
#Check if the required modules are installed
foreach ($module in 'Microsoft.WinGet.Client', 'Microsoft.PowerShell.ConsoleGuiTools', 'powershell-yaml') {
    if (-not (Get-Module -Name $module -ListAvailable)) {
        try {
            Write-Warning ("The required module {0} was not found, installing now..." -f $module) 
            Install-Module -Name $module -Scope CurrentUser -ErrorAction Stop
            Import-Module -Name $module -ErrorAction Stop
        }
        catch {
            Write-Warning ("Error installing/importing required {0} module, exiting..." -f $module)
            return
        }
    }
    else {    
        try {
            Import-Module -Name $module -ErrorAction Stop
        }
        catch {
            Write-Warning ("Error importing required $module module, exiting...")
            return
        }
    }
}
    
#Check $applicationname, select the application the from Out-ConsoleGridView
$Applications = foreach ($Application in $ApplicationName) {
    try {
        $results = Find-WinGetPackage $Application -Source WinGet -ErrorAction Stop | Out-ConsoleGridView -Title "Select the application from the list for selected $($Application) query" -OutputMode Multiple
        foreach ($result in $results) {
            [PSCustomObject]@{
                ID      = $result.ID
                Version = $result.Version
            }
        }
    }
    catch {
        Write-Warning ("The application(details) could not be found, exiting...")
        return
    }
}
    
#Loop through the applications and collect the details, exit if no applications were found or selected
if ($null -ne $Applications) {    
    $total = foreach ($item in $Applications | Sort-Object ID) {
        Write-Host ("Processing {0}..." -f $item.ID) -ForegroundColor Green
        try {
            $ApplicationYAML = Invoke-RestMethod ("https://raw.githubusercontent.com/microsoft/winget-pkgs/refs/heads/master/manifests/{0}/{1}/{2}/$($Item.ID).installer.yaml" -f $Item.ID.Substring(0, 1).ToLower(), $Item.ID.Replace('.', '/'), $Item.version) -UseBasicParsing -Method Get -ErrorAction Stop | ConvertFrom-Yaml -ErrorAction Stop
            foreach ($installer in $ApplicationYAML.Installers) {
                $applicationdetails = Get-WinGetPackageInfo -Id $item.ID -ErrorAction Stop
                [PSCustomObject]@{
                    'Name'                        = $item.ID
                    'Author'                      = if ($applicationdetails.Author) { $applicationdetails.Author } else { "Not found" }
                    'Version'                     = [version]$item.Version
                    'Release Date'                = if ($applicationdetails.'Release Date') { $applicationdetails.'Release Date' } else { "Not found" }
                    'Install Modes'               = if ($ApplicationYAML.InstallModes) { $ApplicationYAML.InstallModes -join ', ' } else { "Not found" }
                    'Installer Architecture'      = if ($installer.Architecture) { $installer.Architecture } else { "Not found" }
                    'Silent switches'             = if ($applicationYAML.InstallerSwitches.Silent) { $applicationYAML.InstallerSwitches.Silent } else { "Not found" }
                    'SilentWithProgress switches' = if ($applicationYAML.InstallerSwitches.SilentWithProgress) { $applicationYAML.InstallerSwitches.SilentWithProgress } else { "Not found" }
                    'Installer Type'              = if ($applicationYAML.InstallerType) { $applicationYAML.InstallerType } else { "Not found" }
                    'Installer URL'               = if ($installer.Installerurl) { $installer.Installerurl } else { "Not found" }
                    'HomePage'                    = if ($applicationdetails.HomePage) { $applicationdetails.HomePage } else { "Not found" }
                }
            }
        }
        catch {
            Write-Warning ("Error retrieving details for {0}" -f $item.id)
        }
    }
}
else {
    Write-Warning ("No applications were found or selected, exiting...")
    return
}
    
#If $total has items, output it to display or file
if ($null -ne $total) {
    #Display $total to the chosen $ouput value if $FileName was not used
    if ($Output) {
        switch ($Output) {
            ConsoleGridView {
                try {
                    $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-ConsoleGridView -Title 'WinGet Information'
                }
                catch {
                    Write-Warning ("Error sending information to Out-ConsoleGridview, exiting...")
                    return
                }
            }
            GridView { 
                try {
                    $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Out-GridView -Title 'WinGet Information'
                }
                catch {
                    Write-Warning ("Error sending information to Out-Gridview, exiting...")
                    return
                }
            }
            List { 
                try {
                    $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Format-List
                }
                catch {
                    Write-Warning ("Error sending information to Format-List, exiting...")
                    return
                }
            }
        }
    }

    #Export to file if $FileName was specified
    if ($Filename) {
        if ($Filename.EndsWith('csv')) {
            try {
                $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Csv -Path $Filename -Encoding UTF8 -NoTypeInformation -Delimiter ';' -Append:$true -Force:$true -ErrorAction Stop
                Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green
            }
            catch {
                Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename)
                return
            }
        }
        if ($Filename.EndsWith('xlsx')) {
            if (-not (Get-Module ImportExcel -ListAvailable)) {
                try {
                    Install-Module ImportExcel -Scope CurrentUser -ErrorAction Stop
                    Import-Module ImportExcel -ErrorAction Stop
                    Write-Host ('Installed missing PowerShell Module ImportExcel which is needed for XLSX output') -ForegroundColor Green
                }
                catch {
                    Write-Warning ('Could not install missing PowerShell Module ImportExcel which is needed for XLSX output, exiting...')
                    return
                }
            }
            try {
                $total | Sort-Object Name, Author, Version, 'Release Date', 'Installer Architecture' | Export-Excel -Path $Filename -AutoSize -AutoFilter -Append:$true -ErrorAction Stop
                Write-Host ('Exported WinGet package information to {0}' -f $Filename) -ForegroundColor Green
            }
            catch {
                Write-Warning ('Could not write {0}, check path and permissions. Exiting...' -f $Filename)
                return
            }
        }
    }
}
else {
    Write-Warning ('Specified application(s) were not found, exiting...')
    return
}

Download the script(s) and the Excel file from GitHub here.

2 thoughts on “Query WinGet software installer data with PowerShell

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.