Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerShell cmdlets #1407

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from
Draft

PowerShell cmdlets #1407

wants to merge 23 commits into from

Conversation

@denelon
Copy link
Contributor

@denelon denelon commented Aug 28, 2021


#674

Microsoft Reviewers: Open in CodeFlow
@denelon denelon requested a review from as a code owner Aug 28, 2021
@github-actions

This comment has been hidden.

@github-actions

This comment has been hidden.

@github-actions

This comment has been hidden.

@github-actions

This comment has been hidden.

Copy link

@megamorf megamorf left a comment

Added my feedback 👍

doc/specs/#674 - PowerShell cmdlets.md Outdated Show resolved Hide resolved
doc/specs/#674 - PowerShell cmdlets.md Show resolved Hide resolved

```PowerShell
Get-WinGetSource | convertto-json -compress

Since this would entirely rely on the output object structure this approach could break easily. It might make more sense to handle this via a -Raw parameter, e.g.

Get-WinGetSource -Raw

Copy link

@doctordns doctordns Aug 29, 2021

The cmdlets should emit .NET Objects (for consumption by other PowerShell cmdlets) along with JSON only where necessary.

NOte - if the intention is to handle cmdlets using Crescendo - then this can be met, provided the team do a good job at writing the necessary output handelers. And for the record, with Cresendo, this is NOT an easy task unless you are outstandingly good with regular expressions.

With that said, the cmdlets must emit objects - and some of those objects can contain json where json is relevant.

doc/specs/#674 - PowerShell cmdlets.md Show resolved Hide resolved
```
**Parameters**

-Output

-Path and -LiteralPath might be better parameter names for -Output. See Export-Csv

Copy link
Contributor Author

@denelon denelon Aug 30, 2021

@megamorf what is the difference between the two?

Copy link

@jantari jantari Aug 30, 2021

Per convention, -Path accepts and interprets wildcards and globs. LiteralPath does not. There's probably official docs for this as it's very standard

Correct. The official documentation says the following:

Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, use single quotation marks. Single quotation marks tell PowerShell not to interpret any characters as escape sequences.

Why is that important? Let's consider that you have a folder with square brackets or an asterisk in its name. -Path will treat that as an expression rather than a true representantion of the path. Users have learned to use -LiteralPath when they literally want PowerShell to treat the user specified path as it is.

Copy link
Contributor Author

@denelon denelon Aug 31, 2021

OK, so rather than "-Output" I believe what I'm reading is we should support both "-Path" and "-LiteralPath". Is it safe to assume PowerShell handles the wildcards when "-Path" is used?

So far as I can recall, -Path takes a wildcarded string and the cmdlet does the variable expansion.

Copy link

@jantari jantari Sep 20, 2021

OK, so rather than "-Output" I believe what I'm reading is we should support both "-Path" and "-LiteralPath". Is it safe to assume PowerShell handles the wildcards when "-Path" is used?

AFAIK the -Path string is passed to the so called "provider" and the interpretation of wildcards is up to the implementation of that provider. PowerShells "path-related" cmdlets can interact with multiple providers, e.g. the Certificate Store, ActiveDirectory, the registry OR the filesystem. So the meaning of * may be different for an NTFS filesystem path / provider implementation than for the registry or for an ActiveDirectory LDAP path. It would be best to speak to the professionals, PowerShell team, about their preference here. Another existing cmdlet that creates a file and writes content to it is Set-Content - it too supports -Path and -LiteralPath but when trying to use it with a registry-path I got an error that the functionality is not implemented by the provider - similar to how winget wouldn't support exporting a packageset to the registry or certificate store I imagine:

Set-Content -path "HKCU:\Software\XD" -Value 'kek'
Set-Content: Cannot use interface. The IContentCmdletProvider interface is not implemented by this provider.

doc/specs/#674 - PowerShell cmdlets.md Outdated Show resolved Hide resolved
>Note: The current behavior for `winget show vscode` would look like the example below.
```PowerShell
Find-WinGetPackage -Moniker vscode | Get-WinGetPackageVersion -Detail
```

>Note: The current behavior for `winget show vscode --versions` would look like the example below.
```PowerShell
Find-WinGetPackage -Moniker vscode | Get-WinGetPackageVersion -All
```

This is valid PowerShell code but needlessly complicated from a user experience perspective. Many users will expect these actions to be done with a single command. It'll be interesting to see what feedback you'll get here :-)

Find-Package should, uhh, find packages and return all the information. C/F Find-Module. Please do not introduce needless complexity where it can be avoided.

Copy link

@jantari jantari Aug 29, 2021

I disagree. AFAIK winget repositories use a cached index to speed up searches. It makes a ton of sense to return only the minimal, cached set of data first and then get all the information (which is an expensive operation) only for the package you're really interested in. Other existing cmdlets such as Get-ADUser and Get-WindowsDriver take a similar approach for performance and server-load reasons.

If the approach is to return a minimal amount of properties, then two things:

  1. The Find-WinGetPackage should return enough properties, by default, to be useful. As you mantion, like Get-ADuser etc.
  2. If there are more properties not returned by default - then use a -Property parameter to specify which optional properties to return.
    In this case, I'd argue that the version of a package is important and probably should be returned by default.

There are two issues therefore: what properties get returned by default and how to get more. I do not support adding cmdlets in the proposed manner.

Just checking, since it's not in this spec file, these cmdlets will be targeting Windows PowerShell (5.1), not PowerShell Core, right? We can't guarantee that PowerShell Core is installed since it's not shipped with Windows (and it isn't usually installed on systems that aren't used for development unless you work at a really hip company).

I sure hope not. It would be crazy, this long after PowerShell 7 has shipped to be so backwards as to ONLY target WIndows PowerShell.

I sure hope not. It would be crazy, this long after PowerShell 7 has shipped to be so backwards as to ONLY target WIndows PowerShell.

I'd disagree. For all that Microsoft want PowerShell 7 to be the future, I don't know a single enterprise that's using it, precisely because it's not a backwards compatible, drop in replacement for PowerShell 5. In every current, supported version of Windows, PowerShell 7 is a side by side addon and the chance of MS actually ever releasing an in place upgrade from PS5 to PS7+ is slim to none, so PowerShell 5 is going to continue to be what is used by enterprise admins for years to come.
So yeah, IMHO this module absolutely needs to be PS 5.1 compatible.

Copy link
Contributor

@Karl-WE Karl-WE Sep 5, 2021

@JustSomeGuyNZ I agree with your point that there are companies that will never allow PS 7 to be deployed. I do not get the reason to be honest. I consult customers to deploy it widely just for the same of improved commandlets like test-connection etc.
It's an MSI package, easy to deploy with a small mst. What is their issues with PS 7? Do you have more information about it? I just know it is a controversy because of patchmanagement.org and also some ConfigMgr MEMCM pals.

It's not a drop in replacement, and it breaks backwards compatibility. In my experience enterprise IT is pretty resistant to change that breaks backwards compatibility and unforced changes lol.

I've been engaging the PowerShell team in the discussions with our design, and the crescendo team to aid in rapid prototyping. We will follow their guidance with respect to which versions of PowerShell behave differently so we can maintain the greatest compatibility level. I am certainly not a PowerShell expert, so I'm learning from the experts on that front. I wanted to get this draft out quickly so we could get community feedback. I'm building on the list of concerns brought up here so they can be clearly addressed in the document.

This is excellent news and much to be welcomed. Knowing what I do, Crescendo should provide a good way forward and helps to move this forward and makes the best out of the decision to do this all in C++. But we are where we are, and Crescendo does look promising as a way forward. It also gives the winget team to re-write certain cmdlets in C# where that makes business sense.

As I stated a while ago, creating the object model is very important. With Crescendo, as I understand it, you use regular expressions to create objects that the Crescendo-generated cmdlet emits. As I have said elsewhere, this is going to be a very difficult task to do well and completely - string to object translation is not an exact science. Thus my first concern is the objects emitted. It should be a goal for winget-ps to emit objects that are as rich and functional as those emitted by other modules and usable in rich cross-silo scenarios.

The second concern is over verb usage. As mentioned a long time ago, the subcommand of winget do not line up completely with PowerShell standard verb naming. For example, the show command in winget should probably be get. And hash should be something else. I would like to see the command to verb translation table - and please, please, please only uses approved verbs in all cmdlets.

I look forward to seeing how this progresses.

Copy link
Contributor Author

@denelon denelon Sep 17, 2021

I've been going through the process of learning the PowerShell verbs and continuing to expand the draft to others so we can get a sense of the best verbs and behaviors. First impressions are very valuable in this area. There is definitely some impedance to overcome between the .exe cli syntax and PowerShell. We're heads down on the v1.1 release, and then I'll have more time to dedicate to fleshing this out. We have been discussing the rich object model needed for a good PowerShell experience.

The verb choice is a vital component of the sacred vow. IT Pros would expect to use certain verbs and certain parameter names names. To create a truly great Powershell module means using approved verbs. :-)

@jantari
Copy link

@jantari jantari commented Aug 28, 2021

Looks like a solid first draft overall.

I have noticed there is no mention of ParameterSets, but some cmdlets parameters should probably be mutually exclusive e.g. these three wherever they are used:

-PackageIdentifier
-Name
-Moniker

I think a user should not be able to specify more than one of these for any given command.

@jedieaston
Copy link
Contributor

@jedieaston jedieaston commented Aug 29, 2021

Just checking, since it's not in this spec file, these cmdlets will be targeting Windows PowerShell (5.1), not PowerShell Core, right? We can't guarantee that PowerShell Core is installed since it's not shipped with Windows (and it isn't usually installed on systems that aren't used for development unless you work at a really hip company).

@doctordns
Copy link

@doctordns doctordns commented Aug 30, 2021

Just checking, since it's not in this spec file, these cmdlets will be targeting Windows PowerShell (5.1), not PowerShell Core, right? We can't guarantee that PowerShell Core is installed since it's not shipped with Windows (and it isn't usually installed on systems that aren't used for development unless you work at a really hip company).

These cmdlets should be validated and fully tested for both Windows PowerShell and PowerShell 7.x and should NOT rely on the PowerShell 7 compatibility mechanism. MUCH more importantly, the team should not use techniques that only work with Windows PowerShell. The WSUS team's cmdlets and a few others, use classes that exist in .NET Framework, but don't in (open source) .NET. That makes it much more complex for IT Pros who do use PowerShell 7 when it doesn't need to be that way. Please ensure the cmdlets can run on both versions of PowerShell.

That is not to say that many (most?) users at first would be using Windows PowerShell. But PowerShell 7 has been around for a couple of years (7.0, 7.1, and very soon 7.2). But if my book sales are anything to go by, there are many IT pros investigating and moving across to PowerShell 7 and it would be wrong to just not to take advantage. And in enterprise arenas, there are many PowerShell 7 features that would be useful in a Package Management Scenairo.

@jedieaston
Copy link
Contributor

@jedieaston jedieaston commented Aug 30, 2021

MUCH more importantly, the team should not use techniques that only work with Windows PowerShell.

I agree with this.

there are many IT pros investigating and moving across to PowerShell 7 and it would be wrong to just not to take advantage.

Kind of off-topic, but why the heck isn't it shipped with Windows then? I don't mind the changes in Core, but I don't use it because I can't guarantee it will be there when I run something. I can guarantee Windows PowerShell is there, and if I need to install a language, why not one I like? (I kid. but something like PowerShell needs to be in the box to be of the best use).

And in enterprise arenas, there are many PowerShell 7 features that would be useful in a Package Management Scenairo.

Which ones are you thinking of? Just curious.

@doctordns
Copy link

@doctordns doctordns commented Aug 30, 2021

Kind of off-topic, but why the heck isn't it shipped with Windows then? I don't mind the changes in Core, but I don't use it because I can't guarantee it will be there when I run something. I can guarantee Windows PowerShell is there, and if I need to install a language, why not one I like? (I kid. but something like PowerShell needs to be in the box to be of the best use).

I can only agree, but if it were that simple, they would have done it a long time ago. I suspect it's mainly due to licensing. .NET and PowerShell are both open source and not a proprietary Microsoft Product. I can only imagine the number of lawyers it would take to get this done. I suspect it will happen, just not soon. There is also t;he issue of support - if it;s in the box, MSFT needs to support it. So NOT simple - In the meantime, there are numerous ways to install it (including WInget). And despite this, I hope that the team doesn't do anything that would stop winget's ability to work with PowerShell 7.

And in enterprise arenas, there are many PowerShell 7 features that would be useful in a Package Management Scenairo.

Which ones are you thinking of? Just curious.

Using Foreach-Object -Parallel to install or even update a set of packages. You can therefore install individual packages potentially in parallel.

@denelon denelon changed the title Power shell cmdlets PowerShell cmdlets Aug 30, 2021
@denelon
Copy link
Contributor Author

@denelon denelon commented Aug 30, 2021

Parallel install is a challenge. MSIX supports up to five concurrent installs (I believe). MSI is a singleton scenario due to msiexec. We also don't know what would happen with parallel installs in a dependency required scenario.

Get-WinGetPackageVersion
```

-Detail
Copy link
Member

@JamesWTruher JamesWTruher Aug 30, 2021

it would be good to elaborate what these different parameters do. since the name of the cmdlet includes version i'm a little puzzled why you need a version parameter

@denelon
Copy link
Contributor Author

@denelon denelon commented Aug 31, 2021

I think a user should not be able to specify more than one of these for any given command.

This is an interesting position. If I think about this in text, it seemed logical for one to say "I want software by Adobe with Acrobat in the name". This seems counter to that proposal. It would also be a breaking change to implement this mutual exclusion in the command line interface. I'd like to avoid breaking changes until we're ready to make a 2.0 release. I also want to clarify it's not a function of a date on a calendar, but more about the right time to take in a series of breaking changes. We should ensure that the 1.x versions are stable enough to go into a bug fix support mode when we make a semantically different release.

@jantari
Copy link

@jantari jantari commented Sep 15, 2021

This is an interesting position. If I think about this in text, it seemed logical for one to say "I want software by Adobe with Acrobat in the name". This seems counter to that proposal. It would also be a breaking change to implement this mutual exclusion in the command line interface. I'd like to avoid breaking changes until we're ready to make a 2.0 release. I also want to clarify it's not a function of a date on a calendar, but more about the right time to take in a series of breaking changes. We should ensure that the 1.x versions are stable enough to go into a bug fix support mode when we make a semantically different release.

I, uh, wasn't even aware you could currently do a query like this: winget search --moniker vscode --name insider --id Microsoft. I do want to say that your usecase of "I want software by Adobe with Acrobat in the name" hinges entirely on people including the software publisher in the id-string of their packages, which is not mandatory and is also not really the point of an ID (companies/publishers change names, an ID is supposed to stay unique and ideally constant so that automation doesn't break). I am not sure why the package ID wasn't just forced to be a GUID in the schema, but it's too late for that now I guess... Once we have PowerShell cmdlets we can filter packages properly by their publisher without the need to rely on magic conventions in ID-strings anyway, so we really don't need to (and should not encourage) the use of multiple of these parameters together (--id and --name for example). The proper way to do it would be Get-WingetPackage -Name "*code*" | Where-Object { $_.Publisher -eq 'Microsoft' }, and we maybe shouldn't permit nonsensical parameter-combinations in v1 if we know we're going to remove it in v2 again. There is no expectation of the PowerShell cmdlets working exactly the same way as the winget.exe command, in fact if that was the case we wouldn't need them - the point is that they're a better (and windows-native) interface to wingets features than the existing winget.exe. my opinion though.

@doctordns
Copy link

@doctordns doctordns commented Sep 16, 2021

A better approach might be to do this:

Get-WingetPackage -Filter {Name -Like "*code*"  -And Publisher -Eq 'Microsoft' } 

@doctordns
Copy link

@doctordns doctordns commented Sep 17, 2021

Parallel install is a challenge. MSIX supports up to five concurrent installs (I believe). MSI is a singleton scenario due to msiexec. We also don't know what would happen with parallel installs in a dependency required scenario.

True - but you could (again in an Enterprise scenairo) install packages on multiple systems in parallel - and given that the actual installation time is the bottle neck, updating multiple machines at once could deliver significantly faster installations.

@jantari
Copy link

@jantari jantari commented Sep 19, 2021

A better approach might be to do this:

Get-WingetPackage -Filter {Name -Like "*code*"  -And Publisher -Eq 'Microsoft' } 

That'd be quite a lot of extra work, to implement a (proprietary) querying and filtering syntax for winget. The exe doesn't have something like this either currently and the specific syntax you proposed also doesn't make a ton of sense if we dig into it: The filter should probably be a string instead of a scriptblock and as a query language something like JMESPath would make a lot of sense because the winget packages are in JSON-compatible YAML format already. Azure CLI also uses JMESPath expressions, and there are ready-made libraries for it. Your syntax looks similar to the one the ActiveDirectory module implemented (albeit with a ScriptBlock as opposed to a string for the filter), but that's something entirely different and that filter-implementation was likely entirely custom (aka a lot of work). WMI and CIM also have their own query language ( WQL ) that looks like this -Filter 'Name LIKE "%search%"' - I say enough with the proprietary syntaxes, just give us JMESPath support in winget v2 - this -Filter parameter and it's .exe CLI-equivalent could be introduced at any point later and doesn't have to be in v1.

Parallel install is a challenge. MSIX supports up to five concurrent installs (I believe). MSI is a singleton scenario due to msiexec. We also don't know what would happen with parallel installs in a dependency required scenario.

True - but you could (again in an Enterprise scenairo) install packages on multiple systems in parallel - and given that the actual installation time is the bottle neck, updating multiple machines at once could deliver significantly faster installations.

Respectfully, I think you're getting lost and arguing about details that don't actually matter. Even the old versions of PowerShell can run arbitrary commands against a list of computers in parallel just using the old Invoke-Command cmdlet. There is no need for foreach -parallel or a new PowerShell version to be able to do this.


Let's focus on getting a good and extensible v1 of the winget PowerShell cmdlets finalized before we dive into fantasies about what non-essential functionality we could possibly tack on in the future. The cmdlets should align somewhat with the capabilities of the winget.exe program and there should probably not be too much custom functionality directly embedded into them that the exe doesn't have. - just for consitency. Anything else we can use the existing capabilities of PowerShell for to accomplish, e.g. parallel runs on many computers, complex filter logic or runspaces or whatever.

@doctordns
Copy link

@doctordns doctordns commented Sep 19, 2021

Yes, the filter parameter is based on existing methods built into PowerShell (and referencing late vs early filtering). The Get-ChildItem cmdlet, for example, uses a -Filter parameter, although it uses a string vs a script block, A string, as you mention, is a better choice especially as a string is serializable which might be relevant for cross-host action. If we are building PowerShell cmdlets, I would like to see the filter cmdlet follow PowerShell syntax - it's less for the IT Pro to learn and is an approach in keeping with the sacred vow. While Other query mechanisms might be interesting, they impose a learning curve which can be avoided).,

I also take the point about v1 vs v2. I agree totally with getting a decent set of cmdlets out to begin with and improve them in V2.

How about this - a) make sure that V1` produce all the properties necessary to pass to Where-Object et al (ie later filtering). And define a -Filter parameter that does filtering in V2. The PowerShell team might be able to point to some of the similar code as a head start on the coding.

I do not know Crescendo enough, but could the filter be inserted into the crescendo module and NOT into the exe itself?

@Karl-WE
Copy link
Contributor

@Karl-WE Karl-WE commented Sep 19, 2021

In the context of PowerShell commandlets for WinGet will there be a method to following scenario?

  • having an input file as text with one line per application
  • having an input file as text formatted as CSV
  • having an input file as formatted as XML

Winget can read the import file
I imagine this could be a pipe command like Get-Content or similar that pipes the input file to winget.
Alternatively, winget has own commandlets to specify such an import file

txt file:
get-content -path c:\inputfile.txt -encoding Unicode | Install-WinGetPackage -ErrorAction SilentlyContinue

example of inputfile.txt:

inputfile.txt
OpenWhisperSystems.Signal
CPUID.CPU-Z
CrystalDewWorld.CrystalDiskInfo
KCSoftwares.SUMo
Logitech.Options
Nlitesoft.NTLite
WiresharkFoundation.Wireshark
Intel.IntelDriverAndSupportAssistant
Microsoft.VC++2015-2019Redist-x64
GitHub.cli
Zoom.Zoom
Microsoft.PowerToys
Microsoft.VisualStudioCode
Microsoft.dotnetRuntime.5-x64

CSV file
import-csv -path c:\inputfile.csv -encoding Unicode | Install-WinGetPackage -ErrorAction SilentlyContinue

XML file:
import-clixml -path c:\inputfile.xml | Install-WinGetPackage -ErrorAction SilentlyContinue

Result: this will install (or alternatively) upgrade all packages that contained in the file.
It will continue on error.

Usecase:
automated installation of software based on an input file / central distribution / standardized installation and application patch management

@denelon
Copy link
Contributor Author

@denelon denelon commented Sep 20, 2021

In the context of PowerShell commandlets for WinGet will there be a method to following scenario?

  • having an input file as text with one line per application
  • having an input file as text formatted as CSV
  • having an input file as formatted as XML

Winget can read the import file
I imagine this could be a pipe command like Get-Content or similar that pipes the input file to winget.
Alternatively, winget has own commandlets to specify such an import file

txt file:
get-content -path c:\inputfile.txt -encoding Unicode | Install-WinGetPackage -ErrorAction SilentlyContinue

example of inputfile.txt:

inputfile.txt
OpenWhisperSystems.Signal
CPUID.CPU-Z
CrystalDewWorld.CrystalDiskInfo
KCSoftwares.SUMo
Logitech.Options
Nlitesoft.NTLite
WiresharkFoundation.Wireshark
Intel.IntelDriverAndSupportAssistant
Microsoft.VC++2015-2019Redist-x64
GitHub.cli
Zoom.Zoom
Microsoft.PowerToys
Microsoft.VisualStudioCode
Microsoft.dotnetRuntime.5-x64

CSV file
import-csv -path c:\inputfile.csv -encoding Unicode | Install-WinGetPackage -ErrorAction SilentlyContinue

XML file:
import-clixml -path c:\inputfile.xml | Install-WinGetPackage -ErrorAction SilentlyContinue

Result: this will install (or alternatively) upgrade all packages that contained in the file.
It will continue on error.

Usecase:
automated installation of software based on an input file / central distribution / standardized installation and application patch management

I'm not a PowerShell expert, but I would expect you could iterate over the list and run the install command for each of them. The "import" format for a collection of packages is JSON with a schema, so that is the "current" preferred method, but I believe PowerShell will open up a myriad of new possibilities.

**PowerShell Cmdlet**

```PowerShell
Uninstall-WinGetPackage
Copy link

@jantari jantari Sep 20, 2021

The Uninstall-WingetPackage cmdlet should definitely make use of PowerShells' ShouldProcess feature wherein you are asked to confirm every processed object (package) by default unless you pre-approve all operations with the -Confirm:$False parameter. Especially because of scenarios like the below example: Get-WingetPackage xbox | Uninstall-WingetPackage, because wingets' package name searching and matching often yields unexpected results a user could easily uninstall more packages than intended if no confirmation prompt occurs.

In a perfect world, Install-WinGetPackage AND Uninstall-WInGetPackage` would support all the common parameters, including both -WhatIfand-Confirm``.

What I don't know is how that would work with Crescendo. The Crescendo wrapper may be able to say "We are going to call winget now" but the internal winget processing probably would not be easy to expose to the ShouldProcess mechanism.

```
**Parameters**

-Output
Copy link

@jantari jantari Sep 20, 2021

OK, so rather than "-Output" I believe what I'm reading is we should support both "-Path" and "-LiteralPath". Is it safe to assume PowerShell handles the wildcards when "-Path" is used?

AFAIK the -Path string is passed to the so called "provider" and the interpretation of wildcards is up to the implementation of that provider. PowerShells "path-related" cmdlets can interact with multiple providers, e.g. the Certificate Store, ActiveDirectory, the registry OR the filesystem. So the meaning of * may be different for an NTFS filesystem path / provider implementation than for the registry or for an ActiveDirectory LDAP path. It would be best to speak to the professionals, PowerShell team, about their preference here. Another existing cmdlet that creates a file and writes content to it is Set-Content - it too supports -Path and -LiteralPath but when trying to use it with a registry-path I got an error that the functionality is not implemented by the provider - similar to how winget wouldn't support exporting a packageset to the registry or certificate store I imagine:

Set-Content -path "HKCU:\Software\XD" -Value 'kek'
Set-Content: Cannot use interface. The IContentCmdletProvider interface is not implemented by this provider.

-Exact

-Interactive

Copy link

@jantari jantari Sep 20, 2021

-Silent and -Interactive is another opportunity for mutually exclusive parametersets

A string-parameter with a validateset would also be an option, e.g. -InstallationMode Silent vs -InstallationMode Interactive but I have no strong preference. If the parameter was an enum it could be combined with Log to allow logic-OR-ing the flags or providing multiple in a list that are then OR-ed internally: -InstallationMode Silent, Log

Are multiple parameter sets possible with Crescendo?

Copy link
Contributor Author

@denelon denelon Sep 20, 2021

Yes, that's my current understanding.

Copy link

@leoniDEV leoniDEV Oct 5, 2021

Maybe for -Silent and -Interactive would be better to have a single switch parameter

@doctordns
Copy link

@doctordns doctordns commented Sep 20, 2021

In the context of PowerShell commandlets for WinGet will there be a method to following scenario?

  • having an input file as text with one line per application
  • having an input file as text formatted as CSV
  • having an input file as formatted as XML

I would expect Install-WingetPackage to have a -Name parameter which is of the type [string[]].

Rather than ask Winget to worry about XML, CSV,(and probably JSON, let me workout where the strings come from and just pass them to the cmdlet as strings.

@denelon
Copy link
Contributor Author

@denelon denelon commented Oct 11, 2021

I'm going to try and update this PR and convert to a draft.

@denelon denelon marked this pull request as draft Oct 11, 2021
@denelon
Copy link
Contributor Author

@denelon denelon commented Oct 11, 2021

Here is the Fork/Branch with the "Fix, Hack, Learn" project for a PowerShell module. This is where I'm doing some learnings.

https://github.com/denelon/winget-cli/tree/PowerShellFHL/PowerShell

@denelon
Copy link
Contributor Author

@denelon denelon commented Oct 14, 2021

@doctordns & community

We've been working on building some of the cmdlets out. At lest one of the team members feels strongly that we should be using the "get" verb and not necessarily the "find" verb for winget show. We've been considering a few options:

Get-WinGetPackage

Find-WinGetPackage

Get-WingetInstalledPackage

Find-WingetInstalledPackage

I think one of the challenges is when we execute winget show, we're essentially trying to find a manifest for a particular package and logically doing a bit of a "what if" to show the subset of the manifest that would apply for the users locale, architecture, and scope. We have a different set of cmdlets in mind for getting a "complete" manifest (still debating if that represents the latest/specified version, or all available versions of a package).

The concerns are whether one verb or another makes better sense in the context of "I want to find something installed on my machine" and "I want to find something I could install on my machine".

The differing opinions on this are whether the "Find" verb is used often enough to justify having both "Find" and "Get". One of the options considered was also having an alias from one to the other.

winget list

Options:

  1. Get-WinGetPackage -id Microsoft.PowerToys -installed
  2. Get-WingetInstalledPackage -id Microsoft.PowerToys
  3. Find-WinGetPackage -id Microsoft.PowerToys -installed
  4. Find-WinGetInstalledPackage -id Microsoft.PowerToys

winget search

  1. Get-WinGetPackage -id Microsoft.PowerToys
  2. Find-WinGetPackage -id Microsoft.PowerToys

winget show

  1. Get-WinGetPackage -id Microsoft.PowerToys

Hopefully I've provided enough context, and you are familiar enough with the current behavior for the Windows Package Manager commands. Maybe your "what if" suggestion is a better paradigm:

Install-WinGetPackage -id Microsoft.PowerToys -WhatIf
Upgrade-WinGetPackage -id Microsoft.PowerToys -WhatIf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

9 participants