microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.38k stars 1.46k forks source link

Adding include-available option to winget export #4793

Open aabuhasna opened 2 months ago

aabuhasna commented 2 months ago

Description of the new feature / enhancement

To make the report more dynamic and contains more data is there a chance to add include-available option to the exported json file for example winget export -o c:\temp\winget.json --include-versions -- include-available the exported json file will contain something like this help admins and developers a like for automation

{
PackageIdentifier" : "Microsoft.VisualStudio.2022.Community",
"Version" : "17.11.1",
"Avialbalble": "17.11.2"
},

Proposed technical implementation details

No response

stephengillie commented 2 months ago

This essentially records that there was an upgrade available for the package at the time of export. What would be the use-case - how often would you use this switch, and what would you be working on? Would you use it often enough that a line in settings.json would work better?

aabuhasna commented 2 months ago

Hi @stephengillie

At the moment I am using an automation script to convert the string output to a JSON to help us with automation to save a lot of time for our helpdesk team, we are generating a daily report to make sure all partners' and employees' applications are up to date.

mdanish-kh commented 2 months ago

@aabuhasna Have you tried out WinGet's PowerShell module? Would you find more value in a command like:

Get-WinGetPackage | Select Id, AvailableVersions, InstalledVersion, IsUpdateAvailable | ConvertTo-Json > output.json

This saves the output in a JSON file output.json as:

[
  {
    "Id": "7zip.7zip",
    "AvailableVersions": [
      "24.08",
      "24.07",
      "24.06",
      "24.05",
      .....
    ],
    "InstalledVersion": "24.08",
    "IsUpdateAvailable": false
  },
  {
    "Id": "CPUID.CPU-Z",
    "AvailableVersions": [
      "2.10",
      "2.09",
      "2.08",
      .....
    ],
    "InstalledVersion": "2.06",
    "IsUpdateAvailable": true
  },
aabuhasna commented 2 months ago

Hi @mdanish-kh

Thank you for your advise, Unfortunately, the command is not working as expected, I tried uninstalling and installing Cobalt but it did not resolve the issue

 Get-WinGetPackage | Select-Object -Property Id, AvailableVersions, InstalledVersion, IsUpdateAvailable | ConvertTo-Json
Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within the string.
Parameter name: length"
At C:\Program Files\WindowsPowerShell\Modules\Cobalt\0.4.0\Cobalt.psm1:741 char:33
+ ...             $_.SubString($versionIndex,$versionEndIndex-$versionIndex ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

You cannot call a method on a null-valued expression.
At C:\Program Files\WindowsPowerShell\Modules\Cobalt\0.4.0\Cobalt.psm1:741 char:33
+ ...             $_.SubString($versionIndex,$versionEndIndex-$versionIndex ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Exception calling "Substring" with "2" argument(s): "startIndex cannot be larger than length of string.
Parameter name: startIndex"
At C:\Program Files\WindowsPowerShell\Modules\Cobalt\0.4.0\Cobalt.psm1:751 char:37
+ ...             $_.SubString($availableIndex,$sourceIndex-$availableIndex ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

You cannot call a method on a null-valued expression.
At C:\Program Files\WindowsPowerShell\Modules\Cobalt\0.4.0\Cobalt.psm1:751 char:37
+ ...             $_.SubString($availableIndex,$sourceIndex-$availableIndex ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

[
    {
        "ID":  "Microsoft.VisualStudio.2022.Community",
        "AvailableVersions":  null,
        "InstalledVersion":  null,
        "IsUpdateAvailable":  null
    },
    {
        "ID":  "3A48D7FC-AEE2-4CBC-91D1-0007951B8006_a",
        "AvailableVersions":  null,
        "InstalledVersion":  null,
        "IsUpdateAvailable":  null
    }
    ]
mdanish-kh commented 2 months ago

@aabuhasna Ah, I should've clarified. Even though the minimum version on PowerShell gallery says 5.1, I believe the module doesn't yet work well with "Windows PowerShell" (though I could run the same command fine on my end in Windows PowerShell). I believe work on this is being tracked in:

Is there any chance you can run the same command on PowerShell 7?

aabuhasna commented 2 months ago

@mdanish-kh, unfortunately, I can't upgrade the version of PowerShell to version 7 due to several internal factors.

mdanish-kh commented 2 months ago

Actually.... it looks like that you're using another module Cobalt, which seems to be a wrapper module over Microsoft.WinGet.Client, and may be overriding the execution of above commands. Can you check if you are able to run the command successfully after uninstalling Cobalt?

This is what I see when I try to install Cobalt

 ~ sudo Install-Module -Name Cobalt
PackageManagement\Install-Package : The following commands are already available on this system:'Find-WinGetPackage,Get
-WinGetPackage,Get-WinGetSource,Install-WinGetPackage,Uninstall-WinGetPackage,Update-WinGetPackage'. This module
'Cobalt' may override the existing commands. If you still want to install this module 'Cobalt', use -AllowClobber
parameter.
mdanish-kh commented 2 months ago

@aabuhasna I was able to successfully run the same command in Windows Sandbox environment in Windows PowerShell. I used the following commands

Install-Module -Name Microsoft.WinGet.Client
Repair-WinGetPackageManager
Get-WinGetPackage | Select-Object -Property Id, AvailableVersions, InstalledVersion, IsUpdateAvailable | ConvertTo-Json
aabuhasna commented 2 months ago

@mdanish-kh Thank you for your update, it's working now as expected, I had to tweak the first command you provided since the module already exists and relies on winget application, the tweaked command is Install-Module -Name Microsoft.WinGet.Client -AllowClobber. a question is there a way to get the application name via PS module?

EDIT: The PowerShell module only works when you run it as an administrator, unlike winget cli

mdanish-kh commented 2 months ago

You shouldn't be needing -AllowClobber if you got rid of the conflicting package though. As for getting the application name you can add the Name property in the Select-Object cmdlet

Get-WinGetPackage | Select-Object -Property Id, Name, AvailableVersions, InstalledVersion, IsUpdateAvailable | ConvertTo-Json

Get-WinGetPackage | Get-Member shows you what the response object looks like for other properties, or methods you may be interested in

mdanish-kh commented 2 months ago

EDIT: The PowerShell module only works when you run it as an administrator, unlike winget cli

Are you sure it's not the Install-Module command requiring administrator? I believe if you installed the module with Install-Module Microsoft.WinGet.Client -Scope CurrentUser, the module would install in a location accessible by a normal user