From 3891c07fc1353dc6ddd9ab54a26e78eccd3360a6 Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 09:43:45 -0800 Subject: [PATCH 01/17] First drafted client cmdlets from Hackathon 221 --- .../crescendo/Get-WinGetVersion.json | 68 +++++ .../WindowsPackageManager.format.ps1xml | 26 ++ .../crescendo/WindowsPackageManager.psd1 | 139 ++++++++++ .../crescendo/WindowsPackageManager.psm1 | 196 +++++++++++++++ .../Microsoft.WinGet.Client/doc/README.md | 1 + .../src/Library/Add-WinGetSource.ps1 | 65 +++++ .../Library/Disable-WinGetLocalManifest.ps1 | 46 ++++ .../src/Library/Edit-WinGetClientSetting.ps1 | 36 +++ .../Library/Enable-WinGetLocalManifest.ps1 | 41 +++ .../src/Library/Find-WinGetPackage.ps1 | 142 +++++++++++ .../src/Library/Get-WinGetPackage.ps1 | 133 ++++++++++ .../src/Library/Get-WinGetSource.ps1 | 80 ++++++ .../src/Library/Get-WinGetVersion.ps1 | 32 +++ .../src/Library/Install-WinGetPackage.ps1 | 174 +++++++++++++ .../src/Library/Invoke-WinGetCommand.ps1 | 238 ++++++++++++++++++ .../src/Library/Remove-WinGetSource.ps1 | 37 +++ .../src/Library/Reset-WinGetSource.ps1 | 42 ++++ .../src/Library/Uninstall_WinGetPackage.ps1 | 89 +++++++ .../src/Library/Upgrade-WinGetPackage.ps1 | 185 ++++++++++++++ .../src/Library/Write-LogEntry.ps1 | 55 ++++ .../src/Microsoft.WinGet.Client.psd1 | 123 +++++++++ .../src/Microsoft.WinGet.Client.psm1 | 12 + .../Microsoft.WinGet.Client/test/README.md | 1 + .../PowerShell/Microsoft.WinGet/doc/README.md | 1 + .../src/Microsoft.WinGet.psd1 | 133 ++++++++++ .../src/Microsoft.WinGet.psm1 | 4 + .../Microsoft.WinGet/test/README.md | 1 + tools/PowerShell/README.md | 171 +++++++++++++ 28 files changed, 2271 insertions(+) create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/crescendo/Get-WinGetVersion.json create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.format.ps1xml create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psm1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/doc/README.md create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Remove-WinGetSource.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Reset-WinGetSource.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psd1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 create mode 100644 tools/PowerShell/Microsoft.WinGet.Client/test/README.md create mode 100644 tools/PowerShell/Microsoft.WinGet/doc/README.md create mode 100644 tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psd1 create mode 100644 tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psm1 create mode 100644 tools/PowerShell/Microsoft.WinGet/test/README.md create mode 100644 tools/PowerShell/README.md diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/Get-WinGetVersion.json b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/Get-WinGetVersion.json new file mode 100644 index 0000000000..f9247e461e --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/Get-WinGetVersion.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://aka.ms/crescendo/schema.json", + "Commands": [ + { + "Verb": "Get", + "Noun": "WinGetVersion", + "OriginalName": "winget", + "OriginalCommandElements": [ + "--version" + ], + "OutputHandlers": [ + { + "ParameterSetName": "default", + "StreamOutput": true, + "HandlerType": "Inline", + "Handler": "$Input.trimstart('v') -as [version]" + } + ] + }, + { + "Verb": "Get", + "Noun": "WinGetSource", + "OriginalName": "winget", + "DefaultParameterSetName": "default", + "Parameters": [ + { + "Name": "Export", + "ParameterSetName": ["export"], + "ParameterType": "switch", + "OriginalName": "Export" + }, + { + "Name": "default", + "ParameterSetName": ["default"], + "ParameterType": "switch", + "OriginalName": "default" + } + ], + "OriginalCommandElements": [ + "source", "export" + ], + "OutputHandlers": [ + { + "ParameterSetName": "default", + "StreamOutput": true, + "HandlerType": "Inline", + "Handler": "$Input | ConvertFrom-Json | add-member -pass -typename WinGetSource" + } + ] + }, + { + "Verb": "Get", + "Noun": "WinGetSource", + "OriginalName": "winget", + "OriginalCommandElements": [ + "source", "export" + ], + "OutputHandlers": [ + { + "ParameterSetName": "default", + "StreamOutput": true, + "HandlerType": "Inline", + "Handler": "$Input | ConvertFrom-Json | add-member -pass -typename WinGetSource" + } + ] + } + ] +} \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.format.ps1xml b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.format.ps1xml new file mode 100644 index 0000000000..6b42692259 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.format.ps1xml @@ -0,0 +1,26 @@ + + + + WinGetSourceTable + + WinGetSource + + + + + + + + + + + Name + Arg + + + + + + + + diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 new file mode 100644 index 0000000000..a134f9dfef --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 @@ -0,0 +1,139 @@ +# +# Module manifest for module 'WindowsPackageManager' +# +# Generated by: denelon +# +# Generated on: 10/12/2021 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'WindowsPackageManager.psm1' + +# Version number of this module. +ModuleVersion = '0.0.1' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = '79355747-76a0-4d6d-b182-4a8715b8fc59' + +# Author of this module +Author = 'denelon' + +# Company or vendor of this module +CompanyName = 'Unknown' + +# Copyright statement for this module +Copyright = '(c) denelon. All rights reserved.' + +# Description of the functionality provided by this module +# Description = '' + +# Minimum version of the PowerShell engine required by this module +PowerShellVersion = '5.1.0' + +# Name of the PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# ClrVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# Functions to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = 'Get-WinGetVersion', 'Get-WinGetSource' + +# Cmdlets to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @() + +# Variables to export from this module +# VariablesToExport = @() + +# Aliases to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = 'CrescendoBuilt' + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + # Prerelease = '' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + # ExternalModuleDependencies = @() + + } # End of PSData hashtable + + + # CrescendoVersion + CrescendoVersion = '0.6.1' + + # CrescendoGenerated + CrescendoGenerated = '10/12/2021 13:21:52' + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} + diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psm1 b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psm1 new file mode 100644 index 0000000000..321a55152e --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psm1 @@ -0,0 +1,196 @@ +# Module created by Microsoft.PowerShell.Crescendo +class PowerShellCustomFunctionAttribute : System.Attribute { + [bool]$RequiresElevation + [string]$Source + PowerShellCustomFunctionAttribute() { $this.RequiresElevation = $false; $this.Source = "Microsoft.PowerShell.Crescendo" } + PowerShellCustomFunctionAttribute([bool]$rElevation) { + $this.RequiresElevation = $rElevation + $this.Source = "Microsoft.PowerShell.Crescendo" + } +} + + + +function Get-WinGetVersion +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( ) + +BEGIN { + $__PARAMETERMAP = @{} + $__outputHandlers = @{ + default = @{ StreamOutput = $True; Handler = { $Input.trimstart('v') -as [version] } } + } +} + +PROCESS { + $__commandArgs = @( + '--version' + ) + $__boundparms = $PSBoundParameters + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)}) + if ($PSBoundParameters["Debug"]){wait-debugger} + foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $PSBoundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } } + elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value } + else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}} + } + } + $__commandArgs = $__commandArgs|Where-Object {$_} + if ($PSBoundParameters["Debug"]){wait-debugger} + if ( $PSBoundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget $__commandArgs")) { + if ( $__handlerInfo.StreamOutput ) { + & "winget" $__commandArgs | & $__handler + } + else { + $result = & "winget" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager v1.1.12702 +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [] [] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Upgrades the given package + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget + +#> +} + + + + +function Get-WinGetSource +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( ) + +BEGIN { + $__PARAMETERMAP = @{} + $__outputHandlers = @{ + default = @{ StreamOutput = $True; Handler = { $Input | ConvertFrom-Json | add-member -pass -typename WinGetSource } } + } +} + +PROCESS { + $__commandArgs = @( + 'source' + 'export' + ) + $__boundparms = $PSBoundParameters + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)}) + if ($PSBoundParameters["Debug"]){wait-debugger} + foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $PSBoundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } } + elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value } + else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}} + } + } + $__commandArgs = $__commandArgs|Where-Object {$_} + if ($PSBoundParameters["Debug"]){wait-debugger} + if ( $PSBoundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget $__commandArgs")) { + if ( $__handlerInfo.StreamOutput ) { + & "winget" $__commandArgs | & $__handler + } + else { + $result = & "winget" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager v1.1.12702 +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [] [] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Upgrades the given package + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget + +#> +} + + diff --git a/tools/PowerShell/Microsoft.WinGet.Client/doc/README.md b/tools/PowerShell/Microsoft.WinGet.Client/doc/README.md new file mode 100644 index 0000000000..d0b1722291 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/doc/README.md @@ -0,0 +1 @@ +Placeholder for PlatyPS generated help files diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 new file mode 100644 index 0000000000..b4b484d94f --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 @@ -0,0 +1,65 @@ +Function Add-WinGetSource +{ + <# + .SYNOPSIS + Adds a source to the Windows Package Manager. + + .DESCRIPTION + By running this cmdlet with the will add a new source to the Windows Package Manager. + + .PARAMETER Name + Used to specify the Name of the source + + .PARAMETER Arg + Used to specify the URL for the source + + .PARAMETER Type + Used to specify the Type of source to add + Currently the only two valid values are "Microsoft.Rest" and "Microsoft.PreIndexed.Package" + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + .PARAMETER AcceptSourceAgreement + Used to explicitly accept any agreement required by the source. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .EXAMPLE + Add-WinGetSource -Name "custom" -Argument "https://contoso.com/" -Type "Microsoft.Rest" + + This example adds a new source to the Windows Package Manager named "custom" + + .EXAMPLE + Add-WinGetSource -Name "custom" -Argument "https://contoso.com/" -Type "Microsoft.Rest" -Header "string" + + This example adds a new source to the Windows Package Manager named "custom" and passes the value "string" in the Windows-Package-Manager HTTP header to the source. + #> + + PARAM( + [Parameter(Mandatory=$true)] [string] $Name, + [Parameter(Mandatory=$true)] [string] $Argument, + [Parameter(Mandatory=$true)] [ValidateSet("Microsoft.Rest", "Microsoft.PreIndexed.Package")] [string] $Type, + [Parameter()] [ValidateLength(1, 1024)] $Header, + [Parameter()] [switch] $AcceptSourceAgreement + ) + BEGIN + { + [string[]] $WinGetArgs = "Source", "Add" + $WinGetArgs += "--Name", $Name + $WinGetArgs += "--Arg", $Argument + $WinGetArgs += "--Type", $Type + } + PROCESS + { + #[string[]]$WinGetSourceListRaw = & "WinGet" $WingetArgs | out-string -stream | foreach-object{$_ -replace ("$([char]915)$([char]199)$([char]170)", "$([char]199)")} + & "WinGet" $WingetArgs + } + END + { + return + } +} + +Export-ModuleMember -Function Add-WinGetSource \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 new file mode 100644 index 0000000000..40f7531285 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 @@ -0,0 +1,46 @@ +Function Disable-WinGetLocalManifest +{ + <# + .SYNOPSIS + Disables the Windows Package Manager to work with local manifest files. + + .DESCRIPTION + By running this cmdlet the Windows Package Manager will configured not to support working with manifests on the file system. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .EXAMPLE + Disable-WinGetLocalManifest + + This cmdlet must be executed in an administrative terminal. + #> + PARAM { + [Parameter()] [switch] $VerboseLog + + } + BEGIN + { + ## We might move this code to a utility function rather than duplicate it everywhere it's needed + ## We also need to look for a better way to make sure the terminal is elevated + function Test-IsAdmin + { + + $windowsIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() + $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $windowsIdentity + if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $true } else { $false } + + } + + [string[]] $WinGetArgs = "Settings", "--disable", "LocalManifestFiles" + $WinGetArgs += "--Verbose-Logs", $VerboseLog + } + PROCESS{ + & "WinGet" $WingetArgs + } + END{ + return + } +} + +Export-ModuleMember -Function Disable-WinGetLocalManifest \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 new file mode 100644 index 0000000000..56d53f8973 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 @@ -0,0 +1,36 @@ +Function Edit-WinGetClientSetting +{ + <# + .SYNOPSIS + Opens the Windows Package Manager settings.json file in the default editor. + + .DESCRIPTION + By running this cmdlet will open the Windows Package Manager settings.json in the application configured for editing JSON files. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .EXAMPLE + Edit-WinGetClientSetting + + The settings.json file for the Windows Package Manager will be opened in the default .json editor + #> + + + PARAM { + [Parameter()] [switch] $VerboseLog + } + BEGIN + { + [string[]] $WinGetArgs = "Settings" + $WinGetArgs += "--Verbose-Logs", $VerboseLog + } + PROCESS{ + & "WinGet" $WingetArgs + } + END{ + return + } +} + +Export-ModuleMember -Function Edit-WinGetClientSetting \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 new file mode 100644 index 0000000000..2883d2dd6c --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 @@ -0,0 +1,41 @@ +Function Enable-WinGetLocalManifest +{ + <# + .SYNOPSIS + Enables the Windows Package Manager to work with local manifest files. + + .DESCRIPTION + By running this cmdlet the Windows Package Manager will configured to support working with manifests on the file system. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + #> + + PARAM { + [Parameter()] [switch] $VerboseLog + } + BEGIN + { + ## We might move this code to a utility function rather than duplicate it everywhere it's needed + ## We also need to look for a better way to make sure the terminal is elevated + function Test-IsAdmin + { + + $windowsIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() + $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $windowsIdentity + if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $true } else { $false } + + } + + [string[]] $WinGetArgs = "Settings", "--enable", "LocalManifestFiles" + $WinGetArgs += "--Verbose-Logs", $VerboseLog + } + PROCESS{ + & "WinGet" $WingetArgs + } + END{ + return + } +} + +Export-ModuleMember -Function Enable-WinGetLocalManifest \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 new file mode 100644 index 0000000000..ace8794db7 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 @@ -0,0 +1,142 @@ +Function Find-WinGetPackage{ + <# + .SYNOPSIS + Searches for a package on configured sources. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system. + + .PARAMETER Filter + Used to search across multiple fields of the package. + + .PARAMETER Id + Used to specify the Id of the package + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER Moniker + Used to specify the Moniker of the package + + .PARAMETER Tag + Used to specify the Tag of the package + + .PARAMETER Command + Used to specify the Command of the package + + .PARAMETER Exact + Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. + + .PARAMETER Source + Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name + + .PARAMETER Count + Used to specify the maximum number of packages to return + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .PARAMETER AcceptSourceAgreement + Used to accept any source agreement required for the source. + + .EXAMPLE + Find-WinGetPackage -id "Publisher.Package" + + This example searches for a package containing "Publisher.Package" as a valid identifier on all configured sources. + + .EXAMPLE + Find-WinGetPackage -id "Publisher.Package" -source "Private" + + This example searches for a package containing "Publisher.Package" as a valid identifier from the source named "Private". + + .EXAMPLE + Find-WinGetPackage -Name "Package" + + This example searches for a package containing "Package" as a valid name on all configured sources. + #> + PARAM( + [Parameter(Position=0)] $Filter, + [Parameter()] $Id, + [Parameter()] $Name, + [Parameter()] $Moniker, + [Parameter()] $Tag, + [Parameter()] $Command, + [Parameter()] [switch] $Exact, + [Parameter()] $Source, + [Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count, + [Parameter()] [ValidateLength(1, 1024)]$Header, + [Parameter()] [switch] $VerboseLog, + [Parameter()] [switch] $AcceptSourceAgreements + ) + BEGIN + { + [string[]] $WinGetArgs = @("Search") + + if($Filter){ + ## Search across Name, ID, moniker, and tags + $WinGetArgs += $Filter + } + if($Id){ + ## Search for the ID + $WinGetArgs += "--Id", $Id.Replace("…", "") + } + if($Name){ + ## Search for the Name + $WinGetArgs += "--Name", $Name.Replace("…", "") + } + if($Moniker){ + ## Search for the Moniker + $WinGetArgs += "--Moniker", $Moniker.Replace("…", "") + } + if($Tag){ + ## Search for the Tag + $WinGetArgs += "--Tag", $Tag.Replace("…", "") + } + if($Command){ + ## Search for the Moniker + $WinGetArgs += "--Command", $Command.Replace("…", "") + } + if($Exact){ + ## Search using exact values specified (case sensitive) + $WinGetArgs += "--Exact" + } + if($Source){ + ## Search for the Source + $WinGetArgs += "--Source", $Source.Replace("…", "") + } + if($Count){ + ## Specify the number of results to return + $WinGetArgs += "--Count", $Count + } + if($Header){ + ## Pass the value specified as the Windows-Package-Manager HTTP header + $WinGetArgs += "--header", $Header + } + if($VerboseLog){ + ## Search using exact values specified (case sensitive) + $WinGetArgs += "--VerboseLog", $VerboseLog + } + if($AcceptSourceAgreements){ + ## Accept source agreements + $WinGetArgs += "--accept-source-agreements" + } + } + PROCESS + { + $List = Invoke-WinGetCommand -WinGetArgs $WinGetArgs -IndexTitles $IndexTitles + + foreach ($Obj in $List) { + $Result += [WinGetPackage]::New($Obj) + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Find-WinGetPackage \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 new file mode 100644 index 0000000000..b71bf6d516 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 @@ -0,0 +1,133 @@ +Function Get-WinGetPackage{ + <# + .SYNOPSIS + Gets installed packages on the local system. displays the packages installed on the system, as well as whether an update is available. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system. + + .PARAMETER Filter + Used to search across multiple fields of the package. + + .PARAMETER Id + Used to specify the Id of the package + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER Moniker + Used to specify the Moniker of the package + + .PARAMETER Tag + Used to specify the Tag of the package + + .PARAMETER Command + Used to specify the Command of the package + + .PARAMETER Count + Used to specify the maximum number of packages to return + + .PARAMETER Exact + Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. + + .PARAMETER Source + Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + .PARAMETER AcceptSourceAgreements + Used to accept any source agreements required by a REST source. + + .EXAMPLE + Get-WinGetPackage -id "Publisher.Package" + + This example expects only a single configured REST source with a package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Get-WinGetPackage -id "Publisher.Package" -source "Private" + + This example expects the REST source named "Private" with a package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Get-WinGetPackage -Name "Package" + + This example expects the REST source named "Private" with a package containing "Package" as a valid name. + #> + + PARAM( + [Parameter(Position=0)] $Filter, + [Parameter()] $Name, + [Parameter()] $Id, + [Parameter()] $Moniker, + [Parameter()] $Tag, + [Parameter()] $Source, + [Parameter()] $Command, + [Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count, + [Parameter()] [switch]$Exact, + [Parameter()] [ValidateLength(1, 1024)]$Header, + [Parameter()] [switch]$AcceptSourceAgreements + ) + BEGIN + { + [string[]] $WinGetArgs = @("List") + [WinGetPackage[]]$Result = @() + [string[]] $IndexTitles = @("Name", "Id", "Version", "Available", "Source") + + if($Filter){ + ## Search across Name, ID, moniker, and tags + $WinGetArgs += $Filter + } + if($Name){ + ## Search for the Name + $WinGetArgs += "--Name", $Name.Replace("…", "") + } + if($Id){ + ## Search for the ID + $WinGetArgs += "--Id", $Id.Replace("…", "") + } + if($Moniker){ + ## Search for the Moniker + $WinGetArgs += "--Moniker", $Moniker.Replace("…", "") + } + if($Tag){ + ## Search for the Tag + $WinGetArgs += "--Tag", $Tag.Replace("…", "") + } + if($Source){ + ## Search for the Source + $WinGetArgs += "--Source", $Source.Replace("…", "") + } + if($Count){ + ## Specify the number of results to return + $WinGetArgs += "--Count", $Count + } + if($Exact){ + ## Search using exact values specified (case sensitive) + $WinGetArgs += "--Exact" + } + if($Header){ + ## Pass the value specified as the Windows-Package-Manager HTTP header + $WinGetArgs += "--header", $Header + } + if($AcceptSourceAgreements){ + ## Accept source agreements + $WinGetArgs += "--accept-source-agreements" + } + } + PROCESS + { + $List = Invoke-WinGetCommand -WinGetArgs $WinGetArgs -IndexTitles $IndexTitles + + foreach ($Obj in $List) { + $Result += [WinGetPackage]::New($Obj) + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Get-WinGetPackage \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 new file mode 100644 index 0000000000..068da1247d --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 @@ -0,0 +1,80 @@ +Function Get-WinGetSource +{ + <# + .SYNOPSIS + Gets the configured sources. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the will retrieve the sources configured on the local system. + + .PARAMETER Filter + Used to search for the source by name. + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .EXAMPLE + Get-WinGetSource "winget" + + This example returns the configured source named "winget". + + .EXAMPLE + Get-WinGetSource "winget" -Name "msstore" + + This example returns the configured source named "msstore". + + .EXAMPLE + Find-WinGetPackage -Name "Package" + + This example searches for a package containing "Package" as a valid name on all configured sources. + #> + + PARAM( + [Parameter()] [string] $Name, + [Parameter()] [switch] $VerboseLog + ) + BEGIN + { + [string[]] $WinGetArgs = "Source", "Export" + [WinGetSource[]] $Result = @() + [string[]] $IndexTitles = @("Name", "Argument") + + if($Filter){ + ## Search for the Name + $WinGetArgs += "--Filter", $Filter.Replace("…", "") + } + if($Name){ + ## Search for the Name + $WinGetArgs += "--Name", $Name.Replace("…", "") + } + if($VerboseLog){ + ## Search for the Name + $WinGetArgs += "--Verbose-Logs" + } + } + PROCESS + { + $List = Invoke-WinGetCommand -WinGetArgs $WinGetArgs -IndexTitles $IndexTitles -JSON + + foreach ($Obj in $List) { + #$Result += [WinGetSource]::New($Obj.Name, $Obj.Argument) + $Result += @{ + Name = $Obj.Name + Argument = $Obj.Arg + Data = $Obj.Data + Identifier = $Obj.Identifier + Type = $Obj.Type + } + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Get-WinGetSource \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 new file mode 100644 index 0000000000..730d26587e --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 @@ -0,0 +1,32 @@ +Function Get-WinGetVersion { + <# + .SYNOPSIS + Gets the version from the Windows Package Manager. + + .DESCRIPTION + By running this cmdlet, it will retrieve the version of the Windows Package Manager installed on the local system. + + .EXAMPLE + Get-WinGetVersion + #> + + BEGIN + { + [string[]] $WinGetArgs = "--version" + [version]$Result = "0.0.0.0" + } + PROCESS + { + try { + $Result = [version](& "winget" $WinGetArgs).trimstart("v") + } + catch { + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Get-WinGetVersion \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 new file mode 100644 index 0000000000..105e85ab57 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -0,0 +1,174 @@ +Function Install-WinGetPackage +{ + <# + .SYNOPSIS + Installs a package on the local system. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system. + + .PARAMETER Filter + Used to search across multiple fields of the package. + + .PARAMETER Id + Used to specify the Id of the package + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER Moniker + Used to specify the Moniker of the package + + .PARAMETER Tag + Used to specify the Tag of the package + + .PARAMETER Command + Used to specify the Command of the package + + .PARAMETER Scope + Used to specify install scope (user or machine) + + .PARAMETER Exact + Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. + + .PARAMETER Source + Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name + + .PARAMETER Interactive + Used to specify the installer should be run in interactive mode. + + .PARAMETER Silent + Used to specify the installer should be run in silent mode with no user input. + + .PARAMETER Locale + Used to specify the locale for localized package installer. + + .PARAMETER Log + Used to specify the location for the log location if it is supported by the package installer. + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + .PARAMETER Version + Used to specify the Version of the package + + .PARAMETER Channel + Used to specify the Channel for the package. Note the Windows Package Manager as of version 1.1.0 does not support channels. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .PARAMETER AcceptPackageAgreement + Used to accept any package agreement required for the package. + + .PARAMETER AcceptSourceAgreement + Used to explicitly accept any agreement required by the source. + + .EXAMPLE + Install-WinGetPackage -id "Publisher.Package" + + This example expects only a single package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Install-WinGetPackage -id "Publisher.Package" -source "Private" + + This example expects the source named "Private" contains a package with "Publisher.Package" as a valid identifier. + + .EXAMPLE + Install-WinGetPackage -Name "Package" + + This example expects the source named "Private" contains a package with "Package" as a valid name. + #> + + PARAM( + [Parameter(Position=0)] $Filter, + [Parameter()] $Name, + [Parameter()] $Id, + [Parameter()] $Moniker, + [Parameter()] $Source, + [Parameter()] [ValidateSet("User", "Machine")] $Scope, + [Parameter()] [switch] $Interactive, + [Parameter()] [switch] $Silent, + [Parameter()] [string] $Version, + [Parameter()] [switch] $Exact, + [Parameter()] [switch] $Override, + [Parameter()] [string] $Location, + [Parameter()] [switch] $Force, + [Parameter()] [ValidatePattern("^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$")] [string] $Locale, + [Parameter()] [string] $Log, ## This is a path of where to create a log. + [Parameter()] [switch] $AcceptSourceAgreements + ) + BEGIN + { + [string[]] $WinGetArgs = "Install" + IF($Filter){ + $WinGetArgs += "--Manifest", $Filter + } + IF($Name){ + $WinGetArgs += "--Name", $Name + } + IF($Id){ + $WinGetArgs += "--Id", $Id + } + IF($Moniker){ + $WinGetArgs += "--Moniker", $Moniker + } + IF($Source){ + $WinGetArgs += "--Source", $Source + } + IF($Scope){ + $WinGetArgs += "--Scope", $Scope + } + IF($Interactive){ + $WinGetArgs += "--Interactive" + } + IF($Silent){ + $WinGetArgs += "--Silent" + } + IF($Locale){ + $WinGetArgs += "--locale", $Locale + } + if($Version){ + $WinGetArgs += "--Version", $Version + } + if($Exact){ + $WinGetArgs += "--Exact" + } + if($Log){ + $WinGetArgs += "--Log", $Log + } + if($Override){ + $WinGetArgs += "--override", $Override + } + if($Location){ + $WinGetArgs += "--Location", $Location + } + if($Force){ + $WinGetArgs += "--Force" + } + } + PROCESS + { + ## Exact, ID and Source - Talk with Demitrius tomorrow to better understand this. + $Result = Find-WinGetPackage -Filter $Filter -Name $Name -Id $Id -Moniker $Moniker -Tag $Tag -Command $Command -Source $Source + + if($Result.count -eq 1) { + & "WinGet" $WingetArgs + $Result = "" + } + elseif($Result.count -lt 1){ + Write-Host "Unable to locate package for installation" + $Result = "" + } + else { + Write-Host "Multiple packages found matching input criteria. Please refine the input." + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Install-WinGetPackage \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 new file mode 100644 index 0000000000..adee40ba8b --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 @@ -0,0 +1,238 @@ +class WinGetSource +{ + [string] $Name + [string] $Argument + [string] $Data + [string] $Identifier + [string] $Type + + WinGetSource () + { } + + WinGetSource ([string]$a, [string]$b, [string]$c, [string]$d, [string]$e) + { + $this.Name = $a.TrimEnd() + $this.Argument = $b.TrimEnd() + $this.Data = $c.TrimEnd() + $this.Identifier = $d.TrimEnd() + $this.Type = $e.TrimEnd() + } + + WinGetSource ([string[]]$a) + { + $this.name = $a[0].TrimEnd() + $this.Argument = $a[1].TrimEnd() + $this.Data = $a[2].TrimEnd() + $this.Identifier = $a[3].TrimEnd() + $this.Type = $a[4].TrimEnd() + } + + WinGetSource ([WinGetSource]$a) + { + $this.Name = $a.Name.TrimEnd() + $this.Argument = $a.Argument.TrimEnd() + $this.Data = $a.Data.TrimEnd() + $this.Identifier = $a.Identifier.TrimEnd() + $this.Type = $a.Type.TrimEnd() + + } + + [WinGetSource[]] Add ([WinGetSource]$a) + { + $FirstValue = [WinGetSource]::New($this) + $SecondValue = [WinGetSource]::New($a) + + [WinGetSource[]] $Combined = @([WinGetSource]::New($FirstValue), [WinGetSource]::New($SecondValue)) + + Return $Combined + } + + [WinGetSource[]] Add ([String[]]$a) + { + $FirstValue = [WinGetSource]::New($this) + $SecondValue = [WinGetSource]::New($a) + + [WinGetSource[]] $Combined = @([WinGetSource]::New($FirstValue), [WinGetSource]::New($SecondValue)) + + Return $Combined + } +} + +class WinGetPackage +{ + [string]$Name + [string]$Id + [string]$Version + [string]$Available + [string]$Source + [string]$Match + + WinGetPackage ([string] $a, [string]$b, [string]$c, [string]$d, [string]$e) + { + $this.Name = $a.TrimEnd() + $this.Id = $b.TrimEnd() + $this.Version = $c.TrimEnd() + $this.Available = $d.TrimEnd() + $this.Source = $e.TrimEnd() + } + + WinGetPackage ([WinGetPackage] $a) { + $this.Name = $a.Name + $this.Id = $a.Id + $this.Version = $a.Version + $this.Available = $a.Available + $this.Source = $a.Source + + } + WinGetPackage ([psobject] $a) { + $this.Name = $a.Name + $this.Id = $a.Id + $this.Version = $a.Version + $this.Available = $a.Available + $this.Source = $a.Source + } + + WinGetSource ([string[]]$a) + { + $this.name = $a[0].TrimEnd() + $this.Id = $a[1].TrimEnd() + $this.Version = $a[2].TrimEnd() + $this.Available = $a[3].TrimEnd() + $this.Source = $a[4].TrimEnd() + } + + + [WinGetPackage[]] Add ([WinGetPackage] $a) + { + $FirstValue = [WinGetPackage]::New($this) + $SecondValue = [WinGetPackage]::New($a) + + [WinGetPackage[]]$Result = @([WinGetPackage]::New($FirstValue), [WinGetPackage]::New($SecondValue)) + + Return $Result + } + + [WinGetPackage[]] Add ([String[]]$a) + { + $FirstValue = [WinGetPackage]::New($this) + $SecondValue = [WinGetPackage]::New($a) + + [WinGetPackage[]] $Combined = @([WinGetPackage]::New($FirstValue), [WinGetPackage]::New($SecondValue)) + + Return $Combined + } +} +Function Invoke-WinGetCommand +{ + PARAM( + [Parameter(Position=0, Mandatory=$true)] [string[]]$WinGetArgs, + [Parameter(Position=0, Mandatory=$true)] [string[]]$IndexTitles, + [Parameter()] [switch] $JSON + ) + BEGIN + { + $Index = @() + $Result = @() + $i = 0 + $IndexTitlesCount = $IndexTitles.Count + $Offset = 0 + $Found = $false + + ## Remove two characters from the string length and add "..." to the end (only if there is the three below characters present). + [string[]]$WinGetSourceListRaw = & "WinGet" $WingetArgs | out-string -stream | foreach-object{$_ -replace ("$([char]915)$([char]199)$([char]170)", "$([char]199)")} + } + PROCESS + { + if($JSON){ + ## If expecting JSON content, return the object + return $WinGetSourceListRaw | ConvertFrom-Json + } + + ## Gets the indexing of each title + $rgex = $IndexTitles -join "|" + for ($Offset=0; $Offset -lt $WinGetSourceListRaw.Length; $Offset++) { + if($WinGetSourceListRaw[$Offset].Split(" ")[0].Trim() -match $rgex) { + $Found = $true + break + } + } + if(!$Found) { + Write-Error -Message "No results were found." -TargetObject $WinGetSourceListRaw + return + } + + foreach ($IndexTitle in $IndexTitles) { + ## Creates an array of titles and their string location + $IndexStart = $WinGetSourceListRaw[$Offset].IndexOf($IndexTitle) + $IndexEnds = "" + + IF($IndexStart -ne "-1") { + $Index += [pscustomobject]@{ + Title = $IndexTitle + Start = $IndexStart + Ends = $IndexEnds + } + } + } + + ## Orders the Object based on Index value + $Index = $Index | Sort-Object Start + + ## Sets the end of string value + while ($i -lt $IndexTitlesCount) { + $i ++ + + ## Sets the End of string value (if not null) + if($Index[$i].Start) { + $Index[$i-1].Ends = ($Index[$i].Start -1) - $Index[$i-1].Start + } + } + + ## Builds the WinGetSource Object with contents + $i = $Offset + 2 + while($i -lt $WinGetSourceListRaw.Length) { + $row = $WinGetSourceListRaw[$i] + try { + [bool] $TestNotTitles = $WinGetSourceListRaw[0] -ne $row + [bool] $TestNotHyphenLine = $WinGetSourceListRaw[1] -ne $row -and !$Row.Contains("---") + [bool] $TestNotNoResults = $row -ne "No package found matching input criteria." + } + catch {Wait-Debugger} + + if(!$TestNotNoResults) { + Write-LogEntry -LogEntry "No package found matching input criteria." -Severity 1 + } + + ## If this is the first pass containing titles or the table line, skip. + if($TestNotTitles -and $TestNotHyphenLine -and $TestNotNoResults) { + $List = @{} + + foreach($item in $Index) { + if($Item.Ends) { + #try { + $List[$Item.Title] = $row.SubString($item.Start,$Item.Ends) + #} + #catch { + # Wait-Debugger + #} + #Wait-Debugger + + } + else { + $List[$item.Title] = $row.SubString($item.Start, $row.Length - $Item.Start) + } + } + + $result += [pscustomobject]$list + } + $i++ + } + } + END + { + return $Result + } +} + +#winget list --name windows |out-string -stream | %{$_ -replace ([char]0xe2 + [char]0x80 + [char]0xa6)} + diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Remove-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Remove-WinGetSource.ps1 new file mode 100644 index 0000000000..24a5ed375f --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Remove-WinGetSource.ps1 @@ -0,0 +1,37 @@ +Function Remove-WinGetSource +{ + <# + .SYNOPSIS + Removes a source from the Windows Package Manager. + + .DESCRIPTION + By running this cmdlet will remove an existing source from the Windows Package Manager. + + .PARAMETER Name + Used to specify the Name of the source + + .EXAMPLE + Remove-WinGetSource -Name "Private" + + This will remove the source named "Private" from the Windows Package Manager + #> + + PARAM( + [Parameter(Mandatory=$true)] [string] $Name + ) + BEGIN + { + [string[]] $WinGetArgs = "Source", "remove" + $WinGetArgs += "--Name", $Name + } + PROCESS + { + WinGet $WingetArgs + } + END + { + return + } +} + +Export-ModuleMember -Function Remove-WinGetSource \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Reset-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Reset-WinGetSource.ps1 new file mode 100644 index 0000000000..0864d2b54b --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Reset-WinGetSource.ps1 @@ -0,0 +1,42 @@ +Function Reset-WinGetSource +{ + <# + .SYNOPSIS + Resets the sources for the Windows Package Manager. + + .DESCRIPTION + By running this cmdlet will reset sources for the Windows Package Manager. + + .PARAMETER Name + Used to specify the Name of the source + + .EXAMPLE + Reset-WinGetSource + + This will reset the default sources for the Windows Package Manager + + .EXAMPLE + Reset-WinGetSource -Name "Private" + + This will reset the source named "Private" for the Windows Package Manager + #> + + PARAM( + [Parameter()] [string] $Name + ) + BEGIN + { + [string[]] $WinGetArgs = "Source", "reset" + $WinGetArgs += "--Name", $Name + } + PROCESS + { + WinGet $WingetArgs + } + END + { + return + } +} + +Export-ModuleMember -Function Reset-WinGetSource \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 new file mode 100644 index 0000000000..4a9e70dfd5 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 @@ -0,0 +1,89 @@ +Function Uninstall-WinGetPackage{ + <# + .SYNOPSIS + Uninstalls a package from the local system. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the required inputs, it will uninstall a package installed on the local system. + + .PARAMETER Filter + Used to search across multiple fields of the package. + + .PARAMETER Id + Used to specify the Id of the package + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER Moniker + Used to specify the Moniker of the package + + .PARAMETER Version + Used to specify the Version of the package + + .PARAMETER Exact + Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. + + .PARAMETER Channel + Used to specify the Channel for the package. Note the Windows Package Manager as of version 1.1.0 does not support channels. + + .PARAMETER Source + Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name + + .PARAMETER Manifest + Used to specify the Manifest of the package + + .PARAMETER Interactive + Used to specify the installer should be run in interactive mode. + + .PARAMETER Silent + Used to specify the installer should be run in silent mode with no user input. + + .PARAMETER Log + Used to specify the location for the log location if it is supported by the package uninstaller. + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + + .PARAMETER AcceptSourceAgreement + Used to explicitly accept any agreement required by the source. + + .EXAMPLE + Get-WinGetManifest -id "Publisher.Package" + + This example expects only a single configured REST source with a package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Get-WinGetManifest -id "Publisher.Package" -source "Private" + + This example expects the REST source named "Private" with a package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Get-WinGetManifest -Name "Package" + + This example expects the REST source named "Private" with a package containing "Package" as a valid name. + #> + + PARAM{ + + } + BEGIN + { + + } + PROCESS + { + + } + END + { + + } +} + +Export-ModuleMember -Function Uninstall-WinGetPackage \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 new file mode 100644 index 0000000000..7050344b12 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 @@ -0,0 +1,185 @@ +Function Upgrade-WinGetPackage +{ + <# + .SYNOPSIS + Upgrades a package on the local system. + Additional options can be provided to filter the output, much like the search command. + + .DESCRIPTION + By running this cmdlet with the required inputs, it will retrieve the packages installed on the local system. + + .PARAMETER Filter + Used to search across multiple fields of the package. + + .PARAMETER Id + Used to specify the Id of the package + + .PARAMETER Name + Used to specify the Name of the package + + .PARAMETER Moniker + Used to specify the Moniker of the package + + .PARAMETER Tag + Used to specify the Tag of the package + + .PARAMETER Command + Used to specify the Command of the package + + .PARAMETER Channel + Used to specify the channel of the package. Note this is not yet implemented in Windows Package Manager as of version 1.1.0. + + .PARAMETER Scope + Used to specify install scope (user or machine) + + .PARAMETER Exact + Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. + + .PARAMETER Source + Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name + + .PARAMETER Manifest + Path to the manifest on the local file system. Requires local manifest setting to be enabled. + + .PARAMETER Interactive + Used to specify the installer should be run in interactive mode. + + .PARAMETER Silent + Used to specify the installer should be run in silent mode with no user input. + + .PARAMETER Locale + Used to specify the locale for localized package installer. + + .PARAMETER Log + Used to specify the location for the log location if it is supported by the package installer. + + .PARAMETER Override + Used to override switches passed to installer. + + .PARAMETER Force + Used to force the upgrade when the Windows Package Manager would ordinarily not upgrade the package. + + .PARAMETER Location + Used to specify the location for the package to be upgraded. + + .PARAMETER Header + Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. + + .PARAMETER Version + Used to specify the Version of the package + + .PARAMETER VerboseLog + Used to provide verbose logging for the Windows Package Manager. + + .PARAMETER AcceptPackageAgreement + Used to accept any source package required for the package. + + .PARAMETER AcceptSourceAgreement + + .EXAMPLE + Install-WinGetPackage -id "Publisher.Package" + + This example expects only a single package containing "Publisher.Package" as a valid identifier. + + .EXAMPLE + Install-WinGetPackage -id "Publisher.Package" -source "Private" + + This example expects the source named "Private" contains a package with "Publisher.Package" as a valid identifier. + + .EXAMPLE + Install-WinGetPackage -Name "Package" + + This example expects the source named "Private" contains a package with "Package" as a valid name. + #> + + PARAM( + [Parameter(Position=0)] $Filter, + [Parameter()] $Name, + [Parameter()] $Id, + [Parameter()] $Moniker, + [Parameter()] $Source, + [Parameter()] [ValidateSet("User", "Machine")] $Scope, + [Parameter()] [switch] $Interactive, + [Parameter()] [switch] $Silent, + [Parameter()] [string] $Version, + [Parameter()] [switch] $Exact, + [Parameter()] [switch] $Override, + [Parameter()] [string] $Location, + [Parameter()] [switch] $Force, + [Parameter()] [ValidatePattern("^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$")] [string] $Locale, + [Parameter()] [string] $Log, ## This is a path of where to create a log. + [Parameter()] [switch] $AcceptSourceAgreements + ) + BEGIN + { + [string[]] $WinGetArgs = "Install" + IF($Filter){ + $WinGetArgs += "--Manifest", $Filter + } + IF($Name){ + $WinGetArgs += "--Name", $Name + } + IF($Id){ + $WinGetArgs += "--Id", $Id + } + IF($Moniker){ + $WinGetArgs += "--Moniker", $Moniker + } + IF($Source){ + $WinGetArgs += "--Source", $Source + } + IF($Scope){ + $WinGetArgs += "--Scope", $Scope + } + IF($Interactive){ + $WinGetArgs += "--Interactive" + } + IF($Silent){ + $WinGetArgs += "--Silent" + } + IF($Locale){ + $WinGetArgs += "--locale", $Locale + } + if($Version){ + $WinGetArgs += "--Version", $Version + } + if($Exact){ + $WinGetArgs += "--Exact" + } + if($Log){ + $WinGetArgs += "--Log", $Log + } + if($Override){ + $WinGetArgs += "--override", $Override + } + if($Location){ + $WinGetArgs += "--Location", $Location + } + if($Force){ + $WinGetArgs += "--Force" + } + } + PROCESS + { + ## Exact, ID and Source - Talk with Demitrius tomorrow to better understand this. + $Result = Find-WinGetPackage -Filter $Filter -Name $Name -Id $Id -Moniker $Moniker -Tag $Tag -Command $Command -Source $Source + + if($Result.count -eq 1) { + & "WinGet" $WingetArgs + $Result = "" + } + elseif($Result.count -lt 1){ + Write-Host "Unable to locate package for installation" + $Result = "" + } + else { + Write-Host "Multiple packages found matching input criteria. Please refine the input." + } + } + END + { + return $Result + } +} + +Export-ModuleMember -Function Install-WinGetPackage \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 new file mode 100644 index 0000000000..18ea97bddd --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 @@ -0,0 +1,55 @@ +Function Write-LogEntry +{ + PARAM( + [Parameter(Position=0, Mandatory=$true)] [string] $LogEntry, + [Parameter(Position=1, Mandatory=$false)] [int] $Severity=1, + [Parameter(Position=2, Mandatory=$false)] [string] $FontColor="", + [Parameter(Position=3, Mandatory=$false)] [int] $Indent = 0, + [Parameter(Position=4, Mandatory=$false)] [switch] $NoNewLine + ) + BEGIN + { + if($FontColor -eq "") { + switch ($Severity) { + "1" { + ## Informational Response + $FontColor = "White" + $MessagePreFix = "" + } + "2" { + ## Warning Response + $FontColor = "Yellow" + $MessagePreFix = "WARNING: " + } + "3" { + ## Error Response + $FontColor = "Red" + $MessagePreFix = "ERROR: " + } + } + } + ## Combines the logging message and the message type as a prefix + $LogEntry = $MessagePreFix + $LogEntry + + ## Indents the message when viewed on the screen. + $LogIndent = " " + while ($Indent -gt 0) { + $LogEntry = $LogIndent + $LogEntry + $Indent -= 1 + } + } + PROCESS + { + ## Writes logging to the screen + if($NoNewLine) { + Write-Host -Object $LogEntry -ForegroundColor $FontColor -NoNewline + } + else { + Write-Host -Object $LogEntry -ForegroundColor $FontColor + } + } + END + { + return + } +} \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psd1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psd1 new file mode 100644 index 0000000000..0dd90dc0f3 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psd1 @@ -0,0 +1,123 @@ +# +# Module manifest for module 'WindowsPackageManager' +# +# Generated on: 10/12/2021 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'Microsoft.WinGet.Client.psm1' + +# Version number of this module. +ModuleVersion = '0.1.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'b22b7711-6329-420a-87fd-bc47ad9951c7' + +# Author of this module +# Author = '' + +# Company or vendor of this module +CompanyName = 'Microsoft' + +# Copyright statement for this module +Copyright = '(c) 2021 Microsoft. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'This module provides support for working with the Windows Package Manager. It was built as a Hackathon project for the Windows Package Manager.' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '5.1' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# Functions to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = @("Get-WinGetPackage", "Get-WinGetSource", "Get-WinGetVersion", "Add-WinGetSource") + +# Cmdlets to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @() + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases to export from this module, for best performance, do not use wild cards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @("winget") + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/microsoft/winget-cli' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + PreRelease = 'alpha' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} + diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 new file mode 100644 index 0000000000..2aa1f652d8 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 @@ -0,0 +1,12 @@ +. $PSScriptRoot\Library\Get-WinGetVersion.ps1 + +$RequiredVersion = "1.1.12653" + +$version = Get-WinGetVersion +if ($version -lt $RequiredVersion) { + # Need to do localization + Write-Host "Windows Package Manager is missing. For more information on installing the Windows Package Manager. `n Visit: https://github.com/microsoft/winget-cli#installing-the-client" + throw "Requires Windows Package Manager $RequiredVersion or later to be installed." +} + +Get-ChildItem -Path $PSScriptRoot\Library -Filter *.ps1 | foreach-object { . $_.FullName } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/test/README.md b/tools/PowerShell/Microsoft.WinGet.Client/test/README.md new file mode 100644 index 0000000000..2323f662dd --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet.Client/test/README.md @@ -0,0 +1 @@ +Placeholder for test collateral \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet/doc/README.md b/tools/PowerShell/Microsoft.WinGet/doc/README.md new file mode 100644 index 0000000000..d0b1722291 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet/doc/README.md @@ -0,0 +1 @@ +Placeholder for PlatyPS generated help files diff --git a/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psd1 b/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psd1 new file mode 100644 index 0000000000..66ae9b67a3 --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psd1 @@ -0,0 +1,133 @@ +# +# Module manifest for module 'Microsoft.WinGet' +# +# Generated by: denelon +# +# Generated on: 10/15/2021 +# + +@{ + + # Script module or binary module file associated with this manifest. + RootModule = '.\Microsoft.WinGet.psm1' + + # Version number of this module. + ModuleVersion = '0.1.0' + + # Supported PSEditions + # CompatiblePSEditions = @() + + # ID used to uniquely identify this module + GUID = 'd9b4b2a9-11c0-4b64-bde2-e1938f81e82a' + + # Author of this module + # Author = '' + + # Company or vendor of this module + CompanyName = 'Microsoft' + + # Copyright statement for this module + Copyright = '(c) Microsoft. All rights reserved.' + + # Description of the functionality provided by this module + Description = 'This module provides support for working with the Windows Package Manager. It was built as a Hackathon project for the Windows Package Manager.' + + # Minimum version of the PowerShell engine required by this module + PowerShellVersion = '5.1' + + # Name of the PowerShell host required by this module + # PowerShellHostName = '' + + # Minimum version of the PowerShell host required by this module + # PowerShellHostVersion = '' + + # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # DotNetFrameworkVersion = '' + + # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. + # ClrVersion = '' + + # Processor architecture (None, X86, Amd64) required by this module + # ProcessorArchitecture = '' + + # Modules that must be imported into the global environment prior to importing this module + # RequiredModules = @() + + # Assemblies that must be loaded prior to importing this module + # RequiredAssemblies = @() + + # Script files (.ps1) that are run in the caller's environment prior to importing this module. + # ScriptsToProcess = @() + + # Type files (.ps1xml) to be loaded when importing this module + # TypesToProcess = @() + + # Format files (.ps1xml) to be loaded when importing this module + # FormatsToProcess = @() + + # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess + # NestedModules = @() + + # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. + FunctionsToExport = @() + + # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. + CmdletsToExport = @() + + # Variables to export from this module + VariablesToExport = '*' + + # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. + AliasesToExport = @() + + # DSC resources to export from this module + # DscResourcesToExport = @() + + # List of all modules packaged with this module + ModuleList = @("Microsoft.WinGet.Client", "Microsoft.WinGet.Create", "Microsoft.WinGet.Source") + + # List of all files packaged with this module + # FileList = @() + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @("winget", "wingetcreate") + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/microsoft/winget-cli' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + Prerelease = 'alpha' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + # ExternalModuleDependencies = @() + + } # End of PSData hashtable + + } # End of PrivateData hashtable + + # HelpInfo URI of this module + # HelpInfoURI = '' + + # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. + # DefaultCommandPrefix = '' + + } + + \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psm1 b/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psm1 new file mode 100644 index 0000000000..9ca6db43ab --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet/src/Microsoft.WinGet.psm1 @@ -0,0 +1,4 @@ + +Import-Module -Name Microsoft.WinGet.Client -Global -MaximumVersion 0.99.99 +Import-Module -Name Microsoft.WinGet.Create -Global -MaximumVersion 0.99.99 +Import-Module -Name Microsoft.WinGet.Source -Global -MaximumVersion 0.99.99 \ No newline at end of file diff --git a/tools/PowerShell/Microsoft.WinGet/test/README.md b/tools/PowerShell/Microsoft.WinGet/test/README.md new file mode 100644 index 0000000000..2323f662dd --- /dev/null +++ b/tools/PowerShell/Microsoft.WinGet/test/README.md @@ -0,0 +1 @@ +Placeholder for test collateral \ No newline at end of file diff --git a/tools/PowerShell/README.md b/tools/PowerShell/README.md new file mode 100644 index 0000000000..4a89920a2e --- /dev/null +++ b/tools/PowerShell/README.md @@ -0,0 +1,171 @@ +# Windows Package Manager PowerShell Modules + +## History +This set of PowerShell modules was originally built as a Microsoft Hackathon project in 2021. + +We started this project as an exploration to design the right set of cmdlets with PowerShell approved nouns and verbs. As we began to explore wrapping the Windows Package Manager we identified several areas of complexity. Rather than slow down progress on building PowerShell cmdlets, we decided to forge ahead and call out the areas where the experience with pipelines is sub-optimal. + +For example, the Windows Package Manager (later referenced as just CLI) CLI was designed for displaying output in the standard width Windows Terminal. As such, long package names and "Id"s are truncated with a single width ellipsis character. Users wanting to use the PowerShell pipeline to pass values to another cmdlet will likely encounter undesired behavior due to this truncation. We have decided to declare the "Microsoft.WinGet" module as an alpha release until these problems have been resolved. We are planning to change the status of "PreRelease" to beta once we believe we have addressed the issues related to piping the output to other cmdlets. + +The module and associated cmdlets in the 0.1.0 directory were essentially handcrafted as the Hackathon team came up to speed with PowerShell idioms. The module and associated cmdlets in the crescendo directory were crafted using the "Microsoft.PowerShell.Crescendo" module. Several manual changes were applied to these files as well, but the idea was to leverage crescendo to speed up development. + +As we continued, we also identified work being done in support of private REST sources. We decided to create separate modules to speed up development in that are of the product as well as standardizing some of the module work. + +The "Microsoft.WinGet" module is a top level module to organize the others. They child modules are "Microsoft.WinGet.Client" intended to represent the [native PowerShell module](https://github.com/microsoft/winget-cli/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) feature request. The "Microsoft.WinGet.Create" module is expected to support building and modifying manifests in private sources (related to the Windows Package Manager Manifest Creator [REST support feature](https://github.com/microsoft/winget-create/issues/3)). The third module "Microsoft.WinGet.Source" is intended to simplify working the private REST sources like the [reference implementation](https://github.com/microsoft/winget-cli-restsource). + +## Terms and Conventions used + +### Package +The term "package" is used to reference an application or program. For example, Windows Terminal is a package. It's identifier "Microsoft.WindowsTerminal" is available in the [Windows Package Manager Community App Repository](https://github.com/microsoft/winget-pkgs). + + +### Manifest +The term "manifest" is used to reference the metadata about an application or program. In the [Windows Package Manager Community App Repository](https://github.com/microsoft/winget-pkgs) manifests are represented as YAML files. In a REST source, manifests are represented as JSON structured data. For the sake of transparency, the manifests downloaded by the Windows Package Manager from the default "**winget**" source, the manifests are taken from the GitHub repository and merged into a single YAML file per package version. + + +### Conventions +We attempted to make use of the approved verbs for PowerShell. In areas where the verb may have been contentious, we decided to at least be consistent with ourselves. The Open verb is used to open a directory in file explorer (Windows Package Manager Manifest Creator installer cache). The Edit verb is used to open the settings.json file for the Windows Package Manager Manifest Creator and the Windows Package Manager. + +--- +## WinGet Modules +* Microsoft.Winget +* Microsoft.WinGet.Client +* Microsoft.WinGet.Create +* Microsoft.WinGet.Source + +## Microsoft.WinGet.Client cmdlets + +### Add-WinGetSource +Adds a source for the Windows Package Manager to use + +### Disable-WinGetLocalManifest +>This must be run in administrator mode + +### Edit-WinGetClientSetting +Open Windows Package Manager settings file + +### Enable-WinGetLocalManifest +>This must be run in administrator mode + +### Find-WinGetPackage +Searches for packages in configured sources + +### Get-WinGetPackage +Displays the list of packages installed on the local system + +### Get-WinGetSource +Displays the list of sources configured for the Windows Package Manager + +### Get-WinGetVersion +Gets the version for the Windows Package Manager Manifest Creator + +### Install-WinGetPackage +Installs the given package + +### Remove-WinGetSource +Removes a configured source from the Windows Package Manager + +### Reset-WinGetSource +Resets the default sources for the Windows Package Manager + +### Uninstall-WinGetPackage +Uninstalls a package from the local system + +### Upgrade-WinGetPackage +Upgrades a package installed on the local system + +### Get-WinGetInstaller (ToDo) +Displays the installer Install-WinGetPackage would select for the local system + +--- +## Microsoft.WinGet.Create Module cmdlets + +### Get-WinGetCreateVersion (ToDo) +Gets the version for the Windows Package Manager Manifest Creator + +### Edit-WinGetCreateSetting (ToDo) +Open Windows Package Manager Manifest Creator settings file + +### New-WinGetManifest -Path (ToDo) +Creates a new Manifest + +### Set-WinGetManifest - Path (ToDo) +Updates fields of an existing manifest + +### Submit-WinGetManifest -Path (ToDo) +Submits a manifest to the Windows Package Manager App Repository for validation + +### Add-WinGetManifestVersion (ToDo) +Adds a version to an existing manifest + +### Test-WinGetManifest (ToDo) +Validates a manifest + +### Open-WinGetCreateCache (ToDo) +Opens the cache folder storing the downloaded installers + +### Get-WinGetCreateCache (ToDo) +Lists out all the downloaded installers stored in cache + +### Clear-WinGetCreateCache (ToDo) +Deletes all downloaded installers in the cache folder + +--- +## Microsoft.WinGet.Source Module cmdlets + +** Focus on Private Repository (Rest), If there is time.. then we can look at future support of Public WinGet Source. + +### Add-WinGetManifest +Example: Add-WinGetManifest -Path "C:\Folder\File.json" -Source PrivateRepo +* Submit a Manifest to a repository +* -Version: Returns only a specific version of the Manifest as a manifest. +* If Version not specified, then return the latest version only as part of the manifest. + +### Get-WinGetManifest +Example: Get-WinGetManifest -Id Microsoft.PowerToys -Source PrivateRepo +* Gets a Manifest +* Needs to have the returned results "Beautified" when shown to the screen. + +### Set-WinGetManifestVersion +Set-WinGetManifestVersion [-Id] Microsoft.PowerToys [--Source] PrivateRepo --ShortDescription "New Description" [--Version] "33.0.0.0" +--Source {(PrivateRepo)} + +### Add-WinGetManifestVersion + Does not overwrite previously existing values. User must run "Set" to modify. + +### Get-WinGetManifestVersion +Example: Get-WinGetManifestVersion [-Id] Microsoft.PowerToys -Version 3.0.0.0 +Returns the values of a specific version in a Manifest + +### Remove-WinGetManifestVersion +This will remove manifest versions from a manifest located in the Private Source only. + +### Remove-WinGetManifest +This will remove manifests from the Private Source only. + +--- + +## ToDo + +This is not an exhaustive list, but is here as guide for work that needs to be performed. + +* Localization Support +* Handle error messages from the client in several scenarios +* Handle Group Policy messages +* Header is only valid in the context of a single source parameter. We may want to validate in the cmdlet +* Validation needs to be built +* The Modules should be moved to a new GitHub repository patterned after [Crescendo](https://www.powershellgallery.com/packages/PSPackageProject/0.1.18) +* Ultimately, the child modules will be moved to their respective GitHub repositories and the parent will stay in it's own repository. +* Validation should be implemented +* A CI Pipeline should be built to sign and publish the modules to the PowerShell gallery +* Packaging with [PSPackageProject](https://www.powershellgallery.com/packages/PSPackageProject/0.1.18) +* Documentation with [platyPS](https://www.powershellgallery.com/packages/platyPS/0.14.2) +* Support changes from https://github.com/microsoft/winget-cli/issues/1597 + +--- + +## Parking Lot + +PowerShell modules should provide at least parity with the Windows Package Manager + +The CLI is inefficient at returning multiple versions / installers. If we expand beyond what it can do, when we inevitably switch over to the CLI as the tool for running, then the community will see this as a loss of functionality. \ No newline at end of file From cf4659be9a940c6d9ac07b0f45934b9bf2069dd0 Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 10:45:29 -0800 Subject: [PATCH 02/17] spelling --- .github/actions/spelling/expect.txt | 16 ++++++++++++++++ tools/PowerShell/README.md | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index a879b1b9df..88f7782cce 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -10,6 +10,7 @@ aicli AICLIC ajor alreadyinstalled +amd amrutha anonymized APARTMENTTHREADED @@ -49,6 +50,7 @@ blogs bluetooth bomgar BOMs +boundparms brk Buf BUILTINS @@ -96,6 +98,7 @@ dirs diskfull dnld Dobbeleer +dsc dustojnikhummer dvinns dw @@ -137,6 +140,8 @@ GHS gity Globals Google +hackathon +hashtable helplib helplibrary hhx @@ -210,6 +215,7 @@ LTDA lw lz malware +maxvalue MBH megamorf memcpy @@ -245,6 +251,7 @@ nonetwork normer NOSEPARATOR NOTAPROPERTY +notmatch npp nsis nuffing @@ -254,6 +261,7 @@ objbase ofile Packagedx packageinuse +parametermap pathparts pathpaths Patil @@ -267,11 +275,15 @@ pkgmgr pkindex PMS positionals +powershellgallery powertoys pri processthreads productcode +pscustomobject pseudocode +psm +psobject pvk pvm pwabuilder @@ -291,6 +303,7 @@ Redist regexes REGSAM restsource +rgex rhs roblox rosoft @@ -342,6 +355,7 @@ Tlg tombstoned tpl transitioning +trimstart UCase ucasemap UChars @@ -380,6 +394,7 @@ Webserver website WERSJA wesome +whatif windir windowsdeveloper winerror @@ -397,5 +412,6 @@ WZDNCRFJ XPLATSTR xsi yamlcreateps +ype Zanollo zy diff --git a/tools/PowerShell/README.md b/tools/PowerShell/README.md index 4a89920a2e..aead3b428c 100644 --- a/tools/PowerShell/README.md +++ b/tools/PowerShell/README.md @@ -7,11 +7,11 @@ We started this project as an exploration to design the right set of cmdlets wit For example, the Windows Package Manager (later referenced as just CLI) CLI was designed for displaying output in the standard width Windows Terminal. As such, long package names and "Id"s are truncated with a single width ellipsis character. Users wanting to use the PowerShell pipeline to pass values to another cmdlet will likely encounter undesired behavior due to this truncation. We have decided to declare the "Microsoft.WinGet" module as an alpha release until these problems have been resolved. We are planning to change the status of "PreRelease" to beta once we believe we have addressed the issues related to piping the output to other cmdlets. -The module and associated cmdlets in the 0.1.0 directory were essentially handcrafted as the Hackathon team came up to speed with PowerShell idioms. The module and associated cmdlets in the crescendo directory were crafted using the "Microsoft.PowerShell.Crescendo" module. Several manual changes were applied to these files as well, but the idea was to leverage crescendo to speed up development. +The module and associated cmdlets were essentially handcrafted as the Hackathon team came up to speed with PowerShell idioms. The module and associated cmdlets in the Microsoft.WinGet.Client/crescendo directory were crafted using the "Microsoft.PowerShell.Crescendo" module. Several manual changes were applied to these files as well, but the idea was to leverage crescendo to speed up development. As we continued, we also identified work being done in support of private REST sources. We decided to create separate modules to speed up development in that are of the product as well as standardizing some of the module work. -The "Microsoft.WinGet" module is a top level module to organize the others. They child modules are "Microsoft.WinGet.Client" intended to represent the [native PowerShell module](https://github.com/microsoft/winget-cli/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) feature request. The "Microsoft.WinGet.Create" module is expected to support building and modifying manifests in private sources (related to the Windows Package Manager Manifest Creator [REST support feature](https://github.com/microsoft/winget-create/issues/3)). The third module "Microsoft.WinGet.Source" is intended to simplify working the private REST sources like the [reference implementation](https://github.com/microsoft/winget-cli-restsource). +The "Microsoft.WinGet" module is a top level module to organize the others. They child modules are "Microsoft.WinGet.Client" intended to represent the [native PowerShell module](https://github.com/microsoft/winget-cli/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) feature request. The "Microsoft.WinGet.Create" module in the [winget-cli-restsource repository](https://github.com/microsoft/winget-cli-restsource) is expected to support building and modifying manifests in private sources (related to the Windows Package Manager Manifest Creator [REST support feature](https://github.com/microsoft/winget-create/issues/3)). The third module "Microsoft.WinGet.Source" is intended to simplify working the private REST sources like the [reference implementation](https://github.com/microsoft/winget-cli-restsource). A fourth module may be created for the [winget create tool](https://github.com/microsoft/wingetcreate). ## Terms and Conventions used @@ -26,7 +26,15 @@ The term "manifest" is used to reference the metadata about an application or pr ### Conventions We attempted to make use of the approved verbs for PowerShell. In areas where the verb may have been contentious, we decided to at least be consistent with ourselves. The Open verb is used to open a directory in file explorer (Windows Package Manager Manifest Creator installer cache). The Edit verb is used to open the settings.json file for the Windows Package Manager Manifest Creator and the Windows Package Manager. +### Status +The modules should be treated as experimental at this stage of development. They are essentially calling the Windows Package Manager executable and attempting to parse text output that wasn't designed for PowerShell. + +### Future +We expect to enhance the COM interface to support JSON output in the future so the client module can provide rich PowerShell objects. + --- +>Drafted in October and preserved for context. + ## WinGet Modules * Microsoft.Winget * Microsoft.WinGet.Client From 897514e1ff03546fbca6c5ab184c811fedb4cd4a Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 10:55:49 -0800 Subject: [PATCH 03/17] spelling --- .github/actions/spelling/expect.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 88f7782cce..6c2f7eeef7 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -20,6 +20,7 @@ apiset appinstallertest appname Archs +arget argumentlist ARMNT arp From ea120177b349f4c880548f80d3c04736b21b9efa Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 14:22:24 -0800 Subject: [PATCH 04/17] fixed filename --- .../{Uninstall_WinGetPackage.ps1 => Uninstall-WinGetPackage.ps1} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/PowerShell/Microsoft.WinGet.Client/src/Library/{Uninstall_WinGetPackage.ps1 => Uninstall-WinGetPackage.ps1} (100%) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 similarity index 100% rename from tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall_WinGetPackage.ps1 rename to tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 From ca7b76466d1eecbd691622bb958cc7d5669849f4 Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 16:11:39 -0800 Subject: [PATCH 05/17] Update tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 Co-authored-by: Kaleb Luedtke --- .../src/Library/Install-WinGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 index 105e85ab57..2b3c3fc914 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -93,7 +93,7 @@ Function Install-WinGetPackage [Parameter()] [string] $Version, [Parameter()] [switch] $Exact, [Parameter()] [switch] $Override, - [Parameter()] [string] $Location, + [Parameter()] [System.IO.FileInfo] $Location, [Parameter()] [switch] $Force, [Parameter()] [ValidatePattern("^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$")] [string] $Locale, [Parameter()] [string] $Log, ## This is a path of where to create a log. From 9793fae8f626c558f385759acc9fb5ecca827747 Mon Sep 17 00:00:00 2001 From: denelon Date: Wed, 1 Dec 2021 16:12:14 -0800 Subject: [PATCH 06/17] Update tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 Co-authored-by: Kaleb Luedtke --- .../src/Library/Install-WinGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 index 2b3c3fc914..fd7e29f336 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -105,7 +105,7 @@ Function Install-WinGetPackage IF($Filter){ $WinGetArgs += "--Manifest", $Filter } - IF($Name){ + IF($PSBoundParameters.ContainsKey('Name')){ $WinGetArgs += "--Name", $Name } IF($Id){ From 35105116d269f1a36e5588d5f7ebd0dd87673549 Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 2 Dec 2021 10:41:44 -0600 Subject: [PATCH 07/17] Suggested changes from 1760 --- .gitignore | 1 + .../Library/Disable-WinGetLocalManifest.ps1 | 4 ++-- .../src/Library/Edit-WinGetClientSetting.ps1 | 4 ++-- .../Library/Enable-WinGetLocalManifest.ps1 | 4 ++-- .../src/Library/Find-WinGetPackage.ps1 | 8 +++++--- .../src/Library/Get-WinGetPackage.ps1 | 6 +++--- .../src/Library/Get-WinGetVersion.ps1 | 4 ++-- .../src/Library/Install-WinGetPackage.ps1 | 19 ++++++++++++++----- .../src/Library/Invoke-WinGetCommand.ps1 | 9 --------- .../src/Library/Uninstall-WinGetPackage.ps1 | 9 ++++++--- .../src/Library/Upgrade-WinGetPackage.ps1 | 10 +++++----- .../src/Library/Write-LogEntry.ps1 | 6 +----- .../src/Microsoft.WinGet.Client.psm1 | 6 +++++- 13 files changed, 48 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 3e759b75bf..20106aeb70 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.user *.userosscache *.sln.docstates +settings.json # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 index 40f7531285..4bf87035ba 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 @@ -15,10 +15,10 @@ Function Disable-WinGetLocalManifest This cmdlet must be executed in an administrative terminal. #> - PARAM { + PARAM ( [Parameter()] [switch] $VerboseLog - } + ) BEGIN { ## We might move this code to a utility function rather than duplicate it everywhere it's needed diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 index 56d53f8973..6f8047f092 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 @@ -17,9 +17,9 @@ Function Edit-WinGetClientSetting #> - PARAM { + PARAM ( [Parameter()] [switch] $VerboseLog - } + ) BEGIN { [string[]] $WinGetArgs = "Settings" diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 index 2883d2dd6c..2099831f57 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 @@ -11,9 +11,9 @@ Function Enable-WinGetLocalManifest Used to provide verbose logging for the Windows Package Manager. #> - PARAM { + PARAM ( [Parameter()] [switch] $VerboseLog - } + ) BEGIN { ## We might move this code to a utility function rather than duplicate it everywhere it's needed diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 index ace8794db7..788ec2038c 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 @@ -70,11 +70,13 @@ Function Find-WinGetPackage{ [Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count, [Parameter()] [ValidateLength(1, 1024)]$Header, [Parameter()] [switch] $VerboseLog, - [Parameter()] [switch] $AcceptSourceAgreements + [Parameter()] [switch] $AcceptSourceAgreement ) BEGIN { - [string[]] $WinGetArgs = @("Search") + [string[]] $WinGetArgs = @("Search") + [WinGetPackage[]] $Result = @() + [string[]] $IndexTitles = @("Name", "Id", "Version", "Available", "Source") if($Filter){ ## Search across Name, ID, moniker, and tags @@ -120,7 +122,7 @@ Function Find-WinGetPackage{ ## Search using exact values specified (case sensitive) $WinGetArgs += "--VerboseLog", $VerboseLog } - if($AcceptSourceAgreements){ + if($AcceptSourceAgreement){ ## Accept source agreements $WinGetArgs += "--accept-source-agreements" } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 index b71bf6d516..a9a2e74ec9 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 @@ -37,7 +37,7 @@ Function Get-WinGetPackage{ .PARAMETER Header Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. - .PARAMETER AcceptSourceAgreements + .PARAMETER AcceptSourceAgreement Used to accept any source agreements required by a REST source. .EXAMPLE @@ -67,7 +67,7 @@ Function Get-WinGetPackage{ [Parameter()] [ValidateRange(1, [int]::maxvalue)][int]$Count, [Parameter()] [switch]$Exact, [Parameter()] [ValidateLength(1, 1024)]$Header, - [Parameter()] [switch]$AcceptSourceAgreements + [Parameter()] [switch]$AcceptSourceAgreement ) BEGIN { @@ -111,7 +111,7 @@ Function Get-WinGetPackage{ ## Pass the value specified as the Windows-Package-Manager HTTP header $WinGetArgs += "--header", $Header } - if($AcceptSourceAgreements){ + if($AcceptSourceAgreement){ ## Accept source agreements $WinGetArgs += "--accept-source-agreements" } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 index 730d26587e..269aa8da8c 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 @@ -13,14 +13,14 @@ Function Get-WinGetVersion { BEGIN { [string[]] $WinGetArgs = "--version" - [version]$Result = "0.0.0.0" } PROCESS { try { - $Result = [version](& "winget" $WinGetArgs).trimstart("v") + $Result = [version](& "winget" $WinGetArgs).trimstart("v") } catch { + $Result = [version]"0.0.0.0" } } END diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 index fd7e29f336..de70131a56 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -65,6 +65,9 @@ Function Install-WinGetPackage .PARAMETER AcceptSourceAgreement Used to explicitly accept any agreement required by the source. + .PARAMETER Local + Used to install from a local manifest + .EXAMPLE Install-WinGetPackage -id "Publisher.Package" @@ -96,14 +99,18 @@ Function Install-WinGetPackage [Parameter()] [System.IO.FileInfo] $Location, [Parameter()] [switch] $Force, [Parameter()] [ValidatePattern("^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$")] [string] $Locale, - [Parameter()] [string] $Log, ## This is a path of where to create a log. - [Parameter()] [switch] $AcceptSourceAgreements + [Parameter()] [System.IO.FileInfo] $Log, ## This is a path of where to create a log. + [Parameter()] [switch] $AcceptSourceAgreements, + [Parameter()] [switch] $Local # This is for installing local manifests ) BEGIN { [string[]] $WinGetArgs = "Install" IF($Filter){ - $WinGetArgs += "--Manifest", $Filter + IF($Local) { + $WinGetArgs += "--Manifest" + } + $WinGetArgs += $Filter } IF($PSBoundParameters.ContainsKey('Name')){ $WinGetArgs += "--Name", $Name @@ -151,9 +158,11 @@ Function Install-WinGetPackage PROCESS { ## Exact, ID and Source - Talk with Demitrius tomorrow to better understand this. - $Result = Find-WinGetPackage -Filter $Filter -Name $Name -Id $Id -Moniker $Moniker -Tag $Tag -Command $Command -Source $Source + IF(!$Local) { + $Result = Find-WinGetPackage -Filter $Filter -Name $Name -Id $Id -Moniker $Moniker -Tag $Tag -Command $Command -Source $Source + } - if($Result.count -eq 1) { + if($Result.count -eq 1 -or $Local) { & "WinGet" $WingetArgs $Result = "" } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 index adee40ba8b..2be3476aa6 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 @@ -209,14 +209,7 @@ Function Invoke-WinGetCommand foreach($item in $Index) { if($Item.Ends) { - #try { $List[$Item.Title] = $row.SubString($item.Start,$Item.Ends) - #} - #catch { - # Wait-Debugger - #} - #Wait-Debugger - } else { $List[$item.Title] = $row.SubString($item.Start, $row.Length - $Item.Start) @@ -234,5 +227,3 @@ Function Invoke-WinGetCommand } } -#winget list --name windows |out-string -stream | %{$_ -replace ([char]0xe2 + [char]0x80 + [char]0xa6)} - diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 index 4a9e70dfd5..96c9537f8f 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 @@ -69,9 +69,9 @@ Function Uninstall-WinGetPackage{ This example expects the REST source named "Private" with a package containing "Package" as a valid name. #> - PARAM{ + PARAM( - } + ) BEGIN { @@ -86,4 +86,7 @@ Function Uninstall-WinGetPackage{ } } -Export-ModuleMember -Function Uninstall-WinGetPackage \ No newline at end of file +New-Alias -Name Remove-WinGetPackage -Value Uninstall-WinGetPackage + +Export-ModuleMember -Function Uninstall-WinGetPackage +Export-ModuleMember -Alias Remove-WinGetPackage diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 index 7050344b12..0b054332da 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 @@ -77,17 +77,17 @@ Function Upgrade-WinGetPackage .PARAMETER AcceptSourceAgreement .EXAMPLE - Install-WinGetPackage -id "Publisher.Package" + Upgrade-WinGetPackage -id "Publisher.Package" This example expects only a single package containing "Publisher.Package" as a valid identifier. .EXAMPLE - Install-WinGetPackage -id "Publisher.Package" -source "Private" + Upgrade-WinGetPackage -id "Publisher.Package" -source "Private" This example expects the source named "Private" contains a package with "Publisher.Package" as a valid identifier. .EXAMPLE - Install-WinGetPackage -Name "Package" + Upgrade-WinGetPackage -Name "Package" This example expects the source named "Private" contains a package with "Package" as a valid name. #> @@ -104,10 +104,10 @@ Function Upgrade-WinGetPackage [Parameter()] [string] $Version, [Parameter()] [switch] $Exact, [Parameter()] [switch] $Override, - [Parameter()] [string] $Location, + [Parameter()] [System.IO.FileInfo] $Location, [Parameter()] [switch] $Force, [Parameter()] [ValidatePattern("^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$")] [string] $Locale, - [Parameter()] [string] $Log, ## This is a path of where to create a log. + [Parameter()] [System.IO.FileInfo] $Log, ## This is a path of where to create a log. [Parameter()] [switch] $AcceptSourceAgreements ) BEGIN diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 index 18ea97bddd..7759e1293a 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Write-LogEntry.ps1 @@ -32,11 +32,7 @@ Function Write-LogEntry $LogEntry = $MessagePreFix + $LogEntry ## Indents the message when viewed on the screen. - $LogIndent = " " - while ($Indent -gt 0) { - $LogEntry = $LogIndent + $LogEntry - $Indent -= 1 - } + $LogEntry = $LogEntry.PadLeft($LogEntry.Length + (2 * $Indent) ) } PROCESS { diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 index 2aa1f652d8..6ca83875f3 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 @@ -6,7 +6,11 @@ $version = Get-WinGetVersion if ($version -lt $RequiredVersion) { # Need to do localization Write-Host "Windows Package Manager is missing. For more information on installing the Windows Package Manager. `n Visit: https://github.com/microsoft/winget-cli#installing-the-client" - throw "Requires Windows Package Manager $RequiredVersion or later to be installed." + throw [WinGetVersionMismatch]::new("Requires Windows Package Manager $RequiredVersion or later to be installed.") } Get-ChildItem -Path $PSScriptRoot\Library -Filter *.ps1 | foreach-object { . $_.FullName } + +class WinGetVersionMismatch : Exception { + WinGetVersionMismatch([string] $message) : base($message) {} +} From 92b395417ebb2cc57bb1f0bdc6ddc8a25eed7a0b Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 2 Dec 2021 10:53:54 -0600 Subject: [PATCH 08/17] Apply Additional Suggestions --- .../Library/Disable-WinGetLocalManifest.ps1 | 13 +--------- .../src/Library/Edit-WinGetClientSetting.ps1 | 2 +- .../Library/Enable-WinGetLocalManifest.ps1 | 13 +--------- .../src/Library/Find-WinGetPackage.ps1 | 20 ++++++++-------- .../src/Library/Get-WinGetPackage.ps1 | 14 +++++------ .../src/Library/Get-WinGetSource.ps1 | 4 ++-- .../src/Library/Get-WinGetVersion.ps1 | 2 +- .../src/Library/Install-WinGetPackage.ps1 | 20 ++++++++-------- .../src/Library/Upgrade-WinGetPackage.ps1 | 24 +++++++++---------- 9 files changed, 45 insertions(+), 67 deletions(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 index 4bf87035ba..a5e77e2fc8 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Disable-WinGetLocalManifest.ps1 @@ -16,22 +16,11 @@ Function Disable-WinGetLocalManifest This cmdlet must be executed in an administrative terminal. #> PARAM ( - [Parameter()] [switch] $VerboseLog + [Parameter()] [switch] $VerboseLog ) BEGIN { - ## We might move this code to a utility function rather than duplicate it everywhere it's needed - ## We also need to look for a better way to make sure the terminal is elevated - function Test-IsAdmin - { - - $windowsIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() - $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $windowsIdentity - if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $true } else { $false } - - } - [string[]] $WinGetArgs = "Settings", "--disable", "LocalManifestFiles" $WinGetArgs += "--Verbose-Logs", $VerboseLog } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 index 6f8047f092..e79eb0672c 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Edit-WinGetClientSetting.ps1 @@ -18,7 +18,7 @@ Function Edit-WinGetClientSetting PARAM ( - [Parameter()] [switch] $VerboseLog + [Parameter()] [switch] $VerboseLog ) BEGIN { diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 index 2099831f57..897bb92c8a 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Enable-WinGetLocalManifest.ps1 @@ -15,18 +15,7 @@ Function Enable-WinGetLocalManifest [Parameter()] [switch] $VerboseLog ) BEGIN - { - ## We might move this code to a utility function rather than duplicate it everywhere it's needed - ## We also need to look for a better way to make sure the terminal is elevated - function Test-IsAdmin - { - - $windowsIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() - $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $windowsIdentity - if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $true } else { $false } - - } - + { [string[]] $WinGetArgs = "Settings", "--enable", "LocalManifestFiles" $WinGetArgs += "--Verbose-Logs", $VerboseLog } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 index 788ec2038c..583fee866f 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Find-WinGetPackage.ps1 @@ -78,27 +78,27 @@ Function Find-WinGetPackage{ [WinGetPackage[]] $Result = @() [string[]] $IndexTitles = @("Name", "Id", "Version", "Available", "Source") - if($Filter){ + if($PSBoundParameters.ContainsKey('Filter')){ ## Search across Name, ID, moniker, and tags $WinGetArgs += $Filter } - if($Id){ + if($PSBoundParameters.ContainsKey('Id')){ ## Search for the ID $WinGetArgs += "--Id", $Id.Replace("…", "") } - if($Name){ + if($PSBoundParameters.ContainsKey('Name')){ ## Search for the Name $WinGetArgs += "--Name", $Name.Replace("…", "") } - if($Moniker){ + if($PSBoundParameters.ContainsKey('Moniker')){ ## Search for the Moniker $WinGetArgs += "--Moniker", $Moniker.Replace("…", "") } - if($Tag){ + if($PSBoundParameters.ContainsKey('Tag')){ ## Search for the Tag $WinGetArgs += "--Tag", $Tag.Replace("…", "") } - if($Command){ + if($PSBoundParameters.ContainsKey('Command')){ ## Search for the Moniker $WinGetArgs += "--Command", $Command.Replace("…", "") } @@ -106,19 +106,19 @@ Function Find-WinGetPackage{ ## Search using exact values specified (case sensitive) $WinGetArgs += "--Exact" } - if($Source){ + if($PSBoundParameters.ContainsKey('Source')){ ## Search for the Source $WinGetArgs += "--Source", $Source.Replace("…", "") } - if($Count){ + if($PSBoundParameters.ContainsKey('Count')){ ## Specify the number of results to return $WinGetArgs += "--Count", $Count } - if($Header){ + if($PSBoundParameters.ContainsKey('Header')){ ## Pass the value specified as the Windows-Package-Manager HTTP header $WinGetArgs += "--header", $Header } - if($VerboseLog){ + if($PSBoundParameters.ContainsKey('VerboseLog')){ ## Search using exact values specified (case sensitive) $WinGetArgs += "--VerboseLog", $VerboseLog } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 index a9a2e74ec9..7a4e0e5af6 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetPackage.ps1 @@ -79,27 +79,27 @@ Function Get-WinGetPackage{ ## Search across Name, ID, moniker, and tags $WinGetArgs += $Filter } - if($Name){ + if($PSBoundParameters.ContainsKey('Name')){ ## Search for the Name $WinGetArgs += "--Name", $Name.Replace("…", "") } - if($Id){ + if($PSBoundParameters.ContainsKey('Id')){ ## Search for the ID $WinGetArgs += "--Id", $Id.Replace("…", "") } - if($Moniker){ + if($PSBoundParameters.ContainsKey('Moniker')){ ## Search for the Moniker $WinGetArgs += "--Moniker", $Moniker.Replace("…", "") } - if($Tag){ + if($PSBoundParameters.ContainsKey('Tag')){ ## Search for the Tag $WinGetArgs += "--Tag", $Tag.Replace("…", "") } - if($Source){ + if($PSBoundParameters.ContainsKey('Source')){ ## Search for the Source $WinGetArgs += "--Source", $Source.Replace("…", "") } - if($Count){ + if($PSBoundParameters.ContainsKey('Count')){ ## Specify the number of results to return $WinGetArgs += "--Count", $Count } @@ -107,7 +107,7 @@ Function Get-WinGetPackage{ ## Search using exact values specified (case sensitive) $WinGetArgs += "--Exact" } - if($Header){ + if($PSBoundParameters.ContainsKey('Header')){ ## Pass the value specified as the Windows-Package-Manager HTTP header $WinGetArgs += "--header", $Header } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 index 068da1247d..9b31993678 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetSource.ps1 @@ -43,11 +43,11 @@ Function Get-WinGetSource [WinGetSource[]] $Result = @() [string[]] $IndexTitles = @("Name", "Argument") - if($Filter){ + if($PSBoundParameters.ContainsKey('Filter')){ ## Search for the Name $WinGetArgs += "--Filter", $Filter.Replace("…", "") } - if($Name){ + if($PSBoundParameters.ContainsKey('Name')){ ## Search for the Name $WinGetArgs += "--Name", $Name.Replace("…", "") } diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 index 269aa8da8c..375e414102 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Get-WinGetVersion.ps1 @@ -12,7 +12,7 @@ Function Get-WinGetVersion { BEGIN { - [string[]] $WinGetArgs = "--version" + [string[]] $WinGetArgs = "--version" } PROCESS { diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 index de70131a56..5bc80ba78d 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -106,7 +106,7 @@ Function Install-WinGetPackage BEGIN { [string[]] $WinGetArgs = "Install" - IF($Filter){ + IF($PSBoundParameters.ContainsKey('Filter')){ IF($Local) { $WinGetArgs += "--Manifest" } @@ -115,16 +115,16 @@ Function Install-WinGetPackage IF($PSBoundParameters.ContainsKey('Name')){ $WinGetArgs += "--Name", $Name } - IF($Id){ + IF($PSBoundParameters.ContainsKey('Id')){ $WinGetArgs += "--Id", $Id } - IF($Moniker){ + IF($PSBoundParameters.ContainsKey('Moniker')){ $WinGetArgs += "--Moniker", $Moniker } - IF($Source){ + IF($PSBoundParameters.ContainsKey('Source')){ $WinGetArgs += "--Source", $Source } - IF($Scope){ + IF($PSBoundParameters.ContainsKey('Scope')){ $WinGetArgs += "--Scope", $Scope } IF($Interactive){ @@ -133,22 +133,22 @@ Function Install-WinGetPackage IF($Silent){ $WinGetArgs += "--Silent" } - IF($Locale){ + IF($PSBoundParameters.ContainsKey('Locale')){ $WinGetArgs += "--locale", $Locale } - if($Version){ + if($PSBoundParameters.ContainsKey('Version')){ $WinGetArgs += "--Version", $Version } if($Exact){ $WinGetArgs += "--Exact" } - if($Log){ + if($PSBoundParameters.ContainsKey('Log')){ $WinGetArgs += "--Log", $Log } - if($Override){ + if($PSBoundParameters.ContainsKey('Override')){ $WinGetArgs += "--override", $Override } - if($Location){ + if($PSBoundParameters.ContainsKey('Location')){ $WinGetArgs += "--Location", $Location } if($Force){ diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 index 0b054332da..3db80f4b91 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Upgrade-WinGetPackage.ps1 @@ -113,22 +113,22 @@ Function Upgrade-WinGetPackage BEGIN { [string[]] $WinGetArgs = "Install" - IF($Filter){ - $WinGetArgs += "--Manifest", $Filter + IF($PSBoundParameters.ContainsKey('Filter')){ + $WinGetArgs += $Filter } - IF($Name){ + IF($PSBoundParameters.ContainsKey('Name')){ $WinGetArgs += "--Name", $Name } - IF($Id){ + IF($PSBoundParameters.ContainsKey('Id')){ $WinGetArgs += "--Id", $Id } - IF($Moniker){ + IF($PSBoundParameters.ContainsKey('Moniker')){ $WinGetArgs += "--Moniker", $Moniker } - IF($Source){ + IF($PSBoundParameters.ContainsKey('Source')){ $WinGetArgs += "--Source", $Source } - IF($Scope){ + IF($PSBoundParameters.ContainsKey('Scope')){ $WinGetArgs += "--Scope", $Scope } IF($Interactive){ @@ -137,22 +137,22 @@ Function Upgrade-WinGetPackage IF($Silent){ $WinGetArgs += "--Silent" } - IF($Locale){ + IF($PSBoundParameters.ContainsKey('Locale')){ $WinGetArgs += "--locale", $Locale } - if($Version){ + if($PSBoundParameters.ContainsKey('Version')){ $WinGetArgs += "--Version", $Version } if($Exact){ $WinGetArgs += "--Exact" } - if($Log){ + if($PSBoundParameters.ContainsKey('Log')){ $WinGetArgs += "--Log", $Log } - if($Override){ + if($PSBoundParameters.ContainsKey('Override')){ $WinGetArgs += "--override", $Override } - if($Location){ + if($PSBoundParameters.ContainsKey('Location')){ $WinGetArgs += "--Location", $Location } if($Force){ From dcc2103546e1cdf4e2d281beb90dbbee51b5fff9 Mon Sep 17 00:00:00 2001 From: denelon Date: Thu, 2 Dec 2021 09:49:19 -0800 Subject: [PATCH 09/17] Update tools/PowerShell/README.md Co-authored-by: Kaleb Luedtke --- tools/PowerShell/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/README.md b/tools/PowerShell/README.md index aead3b428c..228bef6c0b 100644 --- a/tools/PowerShell/README.md +++ b/tools/PowerShell/README.md @@ -11,7 +11,7 @@ The module and associated cmdlets were essentially handcrafted as the Hackathon As we continued, we also identified work being done in support of private REST sources. We decided to create separate modules to speed up development in that are of the product as well as standardizing some of the module work. -The "Microsoft.WinGet" module is a top level module to organize the others. They child modules are "Microsoft.WinGet.Client" intended to represent the [native PowerShell module](https://github.com/microsoft/winget-cli/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc) feature request. The "Microsoft.WinGet.Create" module in the [winget-cli-restsource repository](https://github.com/microsoft/winget-cli-restsource) is expected to support building and modifying manifests in private sources (related to the Windows Package Manager Manifest Creator [REST support feature](https://github.com/microsoft/winget-create/issues/3)). The third module "Microsoft.WinGet.Source" is intended to simplify working the private REST sources like the [reference implementation](https://github.com/microsoft/winget-cli-restsource). A fourth module may be created for the [winget create tool](https://github.com/microsoft/wingetcreate). +The "Microsoft.WinGet" module is a top level module to organize the others. They child modules are "Microsoft.WinGet.Client" intended to represent the [native PowerShell module](https://github.com/microsoft/winget-cli/issues/221) feature request. The "Microsoft.WinGet.Create" module in the [winget-cli-restsource repository](https://github.com/microsoft/winget-cli-restsource) is expected to support building and modifying manifests in private sources (related to the Windows Package Manager Manifest Creator [REST support feature](https://github.com/microsoft/winget-create/issues/3)). The third module "Microsoft.WinGet.Source" is intended to simplify working the private REST sources like the [reference implementation](https://github.com/microsoft/winget-cli-restsource). A fourth module may be created for the [winget create tool](https://github.com/microsoft/wingetcreate). ## Terms and Conventions used From 29af10e8436bf084916ff2b626df861dfac4caeb Mon Sep 17 00:00:00 2001 From: Kaleb Luedtke Date: Thu, 2 Dec 2021 14:25:59 -0600 Subject: [PATCH 10/17] Treat empty strings in constructors as null --- .../src/Library/Invoke-WinGetCommand.ps1 | 75 ++++++++++--------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 index 2be3476aa6..43f45fecc1 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Invoke-WinGetCommand.ps1 @@ -1,3 +1,8 @@ +filter Assert-WhiteSpaceIsNull { + IF ([string]::IsNullOrWhiteSpace($_)){$null} + ELSE {$_} +} + class WinGetSource { [string] $Name @@ -11,29 +16,29 @@ class WinGetSource WinGetSource ([string]$a, [string]$b, [string]$c, [string]$d, [string]$e) { - $this.Name = $a.TrimEnd() - $this.Argument = $b.TrimEnd() - $this.Data = $c.TrimEnd() - $this.Identifier = $d.TrimEnd() - $this.Type = $e.TrimEnd() + $this.Name = $a.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Argument = $b.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Data = $c.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Identifier = $d.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Type = $e.TrimEnd() | Assert-WhiteSpaceIsNull } WinGetSource ([string[]]$a) { - $this.name = $a[0].TrimEnd() - $this.Argument = $a[1].TrimEnd() - $this.Data = $a[2].TrimEnd() - $this.Identifier = $a[3].TrimEnd() - $this.Type = $a[4].TrimEnd() + $this.name = $a[0].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Argument = $a[1].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Data = $a[2].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Identifier = $a[3].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Type = $a[4].TrimEnd() | Assert-WhiteSpaceIsNull } WinGetSource ([WinGetSource]$a) { - $this.Name = $a.Name.TrimEnd() - $this.Argument = $a.Argument.TrimEnd() - $this.Data = $a.Data.TrimEnd() - $this.Identifier = $a.Identifier.TrimEnd() - $this.Type = $a.Type.TrimEnd() + $this.Name = $a.Name.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Argument = $a.Argument.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Data = $a.Data.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Identifier = $a.Identifier.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Type = $a.Type.TrimEnd() | Assert-WhiteSpaceIsNull } @@ -69,36 +74,36 @@ class WinGetPackage WinGetPackage ([string] $a, [string]$b, [string]$c, [string]$d, [string]$e) { - $this.Name = $a.TrimEnd() - $this.Id = $b.TrimEnd() - $this.Version = $c.TrimEnd() - $this.Available = $d.TrimEnd() - $this.Source = $e.TrimEnd() + $this.Name = $a.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Id = $b.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Version = $c.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Available = $d.TrimEnd() | Assert-WhiteSpaceIsNull + $this.Source = $e.TrimEnd() | Assert-WhiteSpaceIsNull } WinGetPackage ([WinGetPackage] $a) { - $this.Name = $a.Name - $this.Id = $a.Id - $this.Version = $a.Version - $this.Available = $a.Available - $this.Source = $a.Source + $this.Name = $a.Name | Assert-WhiteSpaceIsNull + $this.Id = $a.Id | Assert-WhiteSpaceIsNull + $this.Version = $a.Version | Assert-WhiteSpaceIsNull + $this.Available = $a.Available | Assert-WhiteSpaceIsNull + $this.Source = $a.Source | Assert-WhiteSpaceIsNull } WinGetPackage ([psobject] $a) { - $this.Name = $a.Name - $this.Id = $a.Id - $this.Version = $a.Version - $this.Available = $a.Available - $this.Source = $a.Source + $this.Name = $a.Name | Assert-WhiteSpaceIsNull + $this.Id = $a.Id | Assert-WhiteSpaceIsNull + $this.Version = $a.Version | Assert-WhiteSpaceIsNull + $this.Available = $a.Available | Assert-WhiteSpaceIsNull + $this.Source = $a.Source | Assert-WhiteSpaceIsNull } WinGetSource ([string[]]$a) { - $this.name = $a[0].TrimEnd() - $this.Id = $a[1].TrimEnd() - $this.Version = $a[2].TrimEnd() - $this.Available = $a[3].TrimEnd() - $this.Source = $a[4].TrimEnd() + $this.name = $a[0].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Id = $a[1].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Version = $a[2].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Available = $a[3].TrimEnd() | Assert-WhiteSpaceIsNull + $this.Source = $a[4].TrimEnd() | Assert-WhiteSpaceIsNull } From baf0302e505bf78e43be2b13b5257f3279e55333 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 13:23:17 -0800 Subject: [PATCH 11/17] Update WindowsPackageManager.psd1 --- .../crescendo/WindowsPackageManager.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 index a134f9dfef..84e7579317 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 @@ -27,7 +27,7 @@ Author = 'denelon' CompanyName = 'Unknown' # Copyright statement for this module -Copyright = '(c) denelon. All rights reserved.' +Copyright = 'Copyright Microsoft Corporation. All rights reserved.' # Description of the functionality provided by this module # Description = '' From d0806f7275e29abc91660b9c06b34064e558cd54 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 13:24:04 -0800 Subject: [PATCH 12/17] Update tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 --- .../crescendo/WindowsPackageManager.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 index 84e7579317..50926a8796 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/crescendo/WindowsPackageManager.psd1 @@ -24,7 +24,7 @@ GUID = '79355747-76a0-4d6d-b182-4a8715b8fc59' Author = 'denelon' # Company or vendor of this module -CompanyName = 'Unknown' +CompanyName = 'Microsoft Corporation' # Copyright statement for this module Copyright = 'Copyright Microsoft Corporation. All rights reserved.' From 0da93731ab091b9795d2293a7ccf71a7890575b6 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 15:20:56 -0800 Subject: [PATCH 13/17] implemented uninstall adjusted example text --- .../src/Library/Install-WinGetPackage.ps1 | 5 +- .../src/Library/Uninstall-WinGetPackage.ps1 | 99 +++++++++++++++---- 2 files changed, 83 insertions(+), 21 deletions(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 index 5bc80ba78d..85dbe9bef7 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Install-WinGetPackage.ps1 @@ -53,9 +53,6 @@ Function Install-WinGetPackage .PARAMETER Version Used to specify the Version of the package - .PARAMETER Channel - Used to specify the Channel for the package. Note the Windows Package Manager as of version 1.1.0 does not support channels. - .PARAMETER VerboseLog Used to provide verbose logging for the Windows Package Manager. @@ -81,7 +78,7 @@ Function Install-WinGetPackage .EXAMPLE Install-WinGetPackage -Name "Package" - This example expects the source named "Private" contains a package with "Package" as a valid name. + This example expects a configured source contains a package with "Package" as a valid name. #> PARAM( diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 index 96c9537f8f..be8e8ce49e 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 @@ -25,20 +25,14 @@ Function Uninstall-WinGetPackage{ .PARAMETER Exact Used to specify an exact match for any parameters provided. Many of the other parameters may be used for case insensitive substring matches if Exact is not specified. - .PARAMETER Channel - Used to specify the Channel for the package. Note the Windows Package Manager as of version 1.1.0 does not support channels. - .PARAMETER Source Name of the Windows Package Manager private source. Can be identified by running: "Get-WinGetSource" and using the source Name - .PARAMETER Manifest - Used to specify the Manifest of the package - .PARAMETER Interactive - Used to specify the installer should be run in interactive mode. + Used to specify the uninstaller should be run in interactive mode. .PARAMETER Silent - Used to specify the installer should be run in silent mode with no user input. + Used to specify the uninstaller should be run in silent mode with no user input. .PARAMETER Log Used to specify the location for the log location if it is supported by the package uninstaller. @@ -49,42 +43,113 @@ Function Uninstall-WinGetPackage{ .PARAMETER Header Used to specify the value to pass as the "Windows-Package-Manager" HTTP header for a REST source. - .PARAMETER AcceptSourceAgreement Used to explicitly accept any agreement required by the source. + .PARAMETER Local + Used to uninstall from a local manifest + .EXAMPLE - Get-WinGetManifest -id "Publisher.Package" + Uninstall-WinGetPackage -id "Publisher.Package" This example expects only a single configured REST source with a package containing "Publisher.Package" as a valid identifier. .EXAMPLE - Get-WinGetManifest -id "Publisher.Package" -source "Private" + Uninstall-WinGetPackage -id "Publisher.Package" -source "Private" This example expects the REST source named "Private" with a package containing "Publisher.Package" as a valid identifier. .EXAMPLE - Get-WinGetManifest -Name "Package" + Uninstall-WinGetPackage -Name "Package" - This example expects the REST source named "Private" with a package containing "Package" as a valid name. + This example expects a configured source contains a package with "Package" as a valid name. #> PARAM( - + [Parameter(Position=0)] $Filter, + [Parameter()] $Name, + [Parameter()] $Id, + [Parameter()] $Moniker, + [Parameter()] $Source, + [Parameter()] [switch] $Interactive, + [Parameter()] [switch] $Silent, + [Parameter()] [string] $Version, + [Parameter()] [switch] $Exact, + [Parameter()] [switch] $Override, + [Parameter()] [System.IO.FileInfo] $Location, + [Parameter()] [switch] $Force, + [Parameter()] [System.IO.FileInfo] $Log, ## This is a path of where to create a log. + [Parameter()] [switch] $AcceptSourceAgreements, + [Parameter()] [switch] $Local # This is for installing local manifests ) BEGIN { - + [string[]] $WinGetArgs = "Uninstall" + IF($PSBoundParameters.ContainsKey('Filter')){ + IF($Local) { + $WinGetArgs += "--Manifest" + } + $WinGetArgs += $Filter + } + IF($PSBoundParameters.ContainsKey('Name')){ + $WinGetArgs += "--Name", $Name + } + IF($PSBoundParameters.ContainsKey('Id')){ + $WinGetArgs += "--Id", $Id + } + IF($PSBoundParameters.ContainsKey('Moniker')){ + $WinGetArgs += "--Moniker", $Moniker + } + IF($PSBoundParameters.ContainsKey('Source')){ + $WinGetArgs += "--Source", $Source + } + IF($Interactive){ + $WinGetArgs += "--Interactive" + } + IF($Silent){ + $WinGetArgs += "--Silent" + } + if($PSBoundParameters.ContainsKey('Version')){ + $WinGetArgs += "--Version", $Version + } + if($Exact){ + $WinGetArgs += "--Exact" + } + if($PSBoundParameters.ContainsKey('Log')){ + $WinGetArgs += "--Log", $Log + } + if($PSBoundParameters.ContainsKey('Location')){ + $WinGetArgs += "--Location", $Location + } + if($Force){ + $WinGetArgs += "--Force" + } } PROCESS { - + ## Exact, ID and Source - Talk with tomorrow to better understand this. + IF(!$Local) { + $Result = Find-WinGetPackage -Filter $Filter -Name $Name -Id $Id -Moniker $Moniker -Tag $Tag -Command $Command -Source $Source + } + + if($Result.count -eq 1 -or $Local) { + & "WinGet" $WingetArgs + $Result = "" + } + elseif($Result.count -lt 1){ + Write-Host "Unable to locate package for installation" + $Result = "" + } + else { + Write-Host "Multiple packages found matching input criteria. Please refine the input." + } } END { - + return $Result } } +} New-Alias -Name Remove-WinGetPackage -Value Uninstall-WinGetPackage From e3a96c1708320aed9bdd265e1c262212de311f06 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 15:21:51 -0800 Subject: [PATCH 14/17] Update Uninstall-WinGetPackage.ps1 --- .../src/Library/Uninstall-WinGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 index be8e8ce49e..8e4f6b3266 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 @@ -137,7 +137,7 @@ Function Uninstall-WinGetPackage{ $Result = "" } elseif($Result.count -lt 1){ - Write-Host "Unable to locate package for installation" + Write-Host "Unable to locate package for uninstallation" $Result = "" } else { From 1cf5cf02d8b5643d0bca14a96579bd9c12b7606c Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 15:29:10 -0800 Subject: [PATCH 15/17] tabs vs. spaces --- .../Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 index 6ca83875f3..1006824caa 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Microsoft.WinGet.Client.psm1 @@ -4,9 +4,9 @@ $RequiredVersion = "1.1.12653" $version = Get-WinGetVersion if ($version -lt $RequiredVersion) { - # Need to do localization + # Need to do localization Write-Host "Windows Package Manager is missing. For more information on installing the Windows Package Manager. `n Visit: https://github.com/microsoft/winget-cli#installing-the-client" - throw [WinGetVersionMismatch]::new("Requires Windows Package Manager $RequiredVersion or later to be installed.") + throw [WinGetVersionMismatch]::new("Requires Windows Package Manager $RequiredVersion or later to be installed.") } Get-ChildItem -Path $PSScriptRoot\Library -Filter *.ps1 | foreach-object { . $_.FullName } From a060d7491b1c0ad6ad258f5133758e8bf1259f52 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 15:30:05 -0800 Subject: [PATCH 16/17] removing commented line --- .../Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 index b4b484d94f..186c8b2f7d 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Add-WinGetSource.ps1 @@ -53,7 +53,6 @@ Function Add-WinGetSource } PROCESS { - #[string[]]$WinGetSourceListRaw = & "WinGet" $WingetArgs | out-string -stream | foreach-object{$_ -replace ("$([char]915)$([char]199)$([char]170)", "$([char]199)")} & "WinGet" $WingetArgs } END From adff0a9b75579bed1a9ca5bd6a77e35b14995045 Mon Sep 17 00:00:00 2001 From: denelon Date: Fri, 10 Dec 2021 15:40:28 -0800 Subject: [PATCH 17/17] removed extra brace --- .../src/Library/Uninstall-WinGetPackage.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 index 8e4f6b3266..0e1dcac608 100644 --- a/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 +++ b/tools/PowerShell/Microsoft.WinGet.Client/src/Library/Uninstall-WinGetPackage.ps1 @@ -149,7 +149,6 @@ Function Uninstall-WinGetPackage{ return $Result } } -} New-Alias -Name Remove-WinGetPackage -Value Uninstall-WinGetPackage