From 421e63b4276b7d11b81c4081596a58e0ed2497db Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 13:58:42 -0400 Subject: [PATCH 01/10] remove older wildcard filtering method --- src/code/FindPSResource.cs | 19 ++++++++++++++++-- src/code/Utils.cs | 36 ----------------------------------- test/FindPSResource.Tests.ps1 | 6 ++++++ 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/code/FindPSResource.cs b/src/code/FindPSResource.cs index 12b3f4cb7..ba3016de3 100644 --- a/src/code/FindPSResource.cs +++ b/src/code/FindPSResource.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; using Dbg = System.Diagnostics.Debug; using System.Linq; @@ -198,7 +199,8 @@ private void ProcessResourceNameParameterSet() this)); } - Name = Utils.FilterOutWildcardNames(Name, out string[] errorMsgs); + var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + foreach (string error in errorMsgs) { WriteError(new ErrorRecord( @@ -208,8 +210,21 @@ private void ProcessResourceNameParameterSet() this)); } - if (Name.Length == 0) + // this catches the case where Name wasn't passed in as null or empty, + // but after filtering out unsupported wildcard names there are no elements left in namesToSearch + if (namesToSearch.Length == 0) + { + return; + } + + if (String.Equals(namesToSearch[0], "*", StringComparison.InvariantCultureIgnoreCase)) { + // WriteVerbose("Package names were detected to be (or contain an element equal to): '*', so all packages will be updated"); + WriteError(new ErrorRecord( + new PSInvalidOperationException("-Name '*' is not supported for Find-PSResource so all Name entries will be discarded."), + "NameEqualsWildcardIsNotSupported", + ErrorCategory.InvalidArgument, + this)); return; } diff --git a/src/code/Utils.cs b/src/code/Utils.cs index c5155ffc0..8b2fa3a29 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -111,42 +111,6 @@ public static string[] ProcessNameWildcards( errorMsgs = errorMsgsList.ToArray(); return namesWithSupportedWildcards.ToArray(); } - - public static string[] FilterOutWildcardNames( - string[] pkgNames, - out string[] errorMsgs) - { - List errorFreeNames = new List(); - List errorMsgList = new List(); - - foreach (string n in pkgNames) - { - bool isNameErrorProne = false; - if (WildcardPattern.ContainsWildcardCharacters(n)) - { - if (String.Equals(n, "*", StringComparison.InvariantCultureIgnoreCase)) - { - errorMsgList = new List(); // clear prior error messages - errorMsgList.Add("-Name '*' is not supported for Find-PSResource so all Name entries will be discarded."); - errorFreeNames = new List(); - break; - } - else if (n.Contains("?") || n.Contains("[")) - { - errorMsgList.Add(String.Format("-Name with wildcards '?' and '[' are not supported for Find-PSResource so Name entry: {0} will be discarded.", n)); - isNameErrorProne = true; - } - } - - if (!isNameErrorProne) - { - errorFreeNames.Add(n); - } - } - - errorMsgs = errorMsgList.ToArray(); - return errorFreeNames.ToArray(); - } #endregion diff --git a/test/FindPSResource.Tests.ps1 b/test/FindPSResource.Tests.ps1 index fd24878e3..d1e1666be 100644 --- a/test/FindPSResource.Tests.ps1 +++ b/test/FindPSResource.Tests.ps1 @@ -42,6 +42,12 @@ Describe 'Test Find-PSResource for Module' { $foundScript | Should -BeTrue } + It "should not find resources given Name that equals wildcard, '*'" { + Find-PSResource -Name "*" -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "NameEqualsWildcardIsNotSupported,Microsoft.PowerShell.PowerShellGet.Cmdlets.FindPSResource" + } + It "find resource given Name from V3 endpoint repository (NuGetGallery)" { $res = Find-PSResource -Name "Serilog" -Repository $NuGetGalleryName $res.Count | Should -Be 1 From dd5dd12735be33a3fbf0325ec42a0e77567f28ad Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 14:17:24 -0400 Subject: [PATCH 02/10] add errorhandling for unsupported wildcards to GetInstalledPSREsource --- src/code/GetInstalledPSResource.cs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/code/GetInstalledPSResource.cs b/src/code/GetInstalledPSResource.cs index db1974781..040b2bd69 100644 --- a/src/code/GetInstalledPSResource.cs +++ b/src/code/GetInstalledPSResource.cs @@ -107,23 +107,21 @@ protected override void BeginProcessing() _pathsToSearch = Utils.GetAllResourcePaths(this); } - if (Name == null) + Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); + foreach (string error in errorMsgs) { - Name = new string[] { "*" }; + WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); } - // if '*' is passed in as an argument for -Name with other -Name arguments, - // ignore all arguments except for '*' since it is the most inclusive - // eg: -Name ["TestModule, Test*, *"] will become -Name ["*"] - if (Name != null && Name.Length > 1) + + // this catches the case where Name wasn't passed in as null or empty, + // but after filtering out unsupported wildcard names there are no elements left in namesToSearch + if (Name.Length == 0) { - foreach (var pkgName in Name) - { - if (pkgName.Trim().Equals("*")) - { - Name = new string[] { "*" }; - break; - } - } + return; } } From cb7de8567993f795608cd63eede45a8ff5a2dc16 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 15:46:50 -0400 Subject: [PATCH 03/10] add error handling for wildcards (not supported) to InstallPSResource --- src/code/GetInstalledPSResource.cs | 12 ++++++------ src/code/InstallPSResource.cs | 27 +++++++++++++++++++++++++++ test/InstallPSResource.Tests.ps1 | 12 +++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/code/GetInstalledPSResource.cs b/src/code/GetInstalledPSResource.cs index 040b2bd69..293a62124 100644 --- a/src/code/GetInstalledPSResource.cs +++ b/src/code/GetInstalledPSResource.cs @@ -106,6 +106,11 @@ protected override void BeginProcessing() // retrieve all possible paths _pathsToSearch = Utils.GetAllResourcePaths(this); } + } + + protected override void ProcessRecord() + { + WriteDebug("Entering GetInstalledPSResource"); Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) @@ -118,16 +123,11 @@ protected override void BeginProcessing() } // this catches the case where Name wasn't passed in as null or empty, - // but after filtering out unsupported wildcard names there are no elements left in namesToSearch + // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in Name if (Name.Length == 0) { return; } - } - - protected override void ProcessRecord() - { - WriteDebug("Entering GetInstalledPSResource"); GetHelper getHelper = new GetHelper(this); foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(Name, _versionRange, _pathsToSearch)) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index dee8e3e4e..34b58052c 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -136,6 +136,33 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: + Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + if (nameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + foreach (string error in errorMsgs) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); + } + + // this catches the case where Name wasn't passed in as null or empty, + // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in namesToSearch + if (Name.Length == 0) + { + return; + } + installHelper.InstallPackages( names: Name, versionRange: _versionRange, diff --git a/test/InstallPSResource.Tests.ps1 b/test/InstallPSResource.Tests.ps1 index 503f17bb6..8c3c5275d 100644 --- a/test/InstallPSResource.Tests.ps1 +++ b/test/InstallPSResource.Tests.ps1 @@ -22,6 +22,17 @@ Describe 'Test Install-PSResource for Module' { Get-RevertPSResourceRepositoryFile } + $testCases = @{Name="*"; ErrorId="NameContainsWildcard"} + @{Name=$null; ErrorId="NameContainsWildcard"}, + @{Name="TestModule*"; ErrorId="NameContainsWildcard"}, + @{Name="Test?Module", "Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + + It "Should not install resource with wildcard in name" -TestCases $testCases { + Install-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" + } + It "Install specific module resource by name" { Install-PSResource -Name "TestModule" -Repository $TestGalleryName $pkg = Get-Module "TestModule" -ListAvailable @@ -43,7 +54,6 @@ Describe 'Test Install-PSResource for Module' { $pkg.Name | Should -Be $pkgNames } - It "Should not install resource given nonexistant name" { Install-PSResource -Name NonExistantModule -Repository $TestGalleryName $pkg = Get-Module "NonExistantModule" -ListAvailable From 1f46f73ea4ec1d9c5d8d1df7d26d246d9c8679b2 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 16:20:11 -0400 Subject: [PATCH 04/10] fix bug in test --- test/InstallPSResource.Tests.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/InstallPSResource.Tests.ps1 b/test/InstallPSResource.Tests.ps1 index 8c3c5275d..6d86d349a 100644 --- a/test/InstallPSResource.Tests.ps1 +++ b/test/InstallPSResource.Tests.ps1 @@ -22,8 +22,7 @@ Describe 'Test Install-PSResource for Module' { Get-RevertPSResourceRepositoryFile } - $testCases = @{Name="*"; ErrorId="NameContainsWildcard"} - @{Name=$null; ErrorId="NameContainsWildcard"}, + $testCases = @{Name="*"; ErrorId="NameContainsWildcard"}, @{Name="TestModule*"; ErrorId="NameContainsWildcard"}, @{Name="Test?Module", "Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} From 732d3fcd9f95eff2912f06774d2c839a188a6dfb Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 17:20:10 -0400 Subject: [PATCH 05/10] use local variable in Install --- src/code/InstallPSResource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 34b58052c..20cca0519 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -136,7 +136,7 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: - Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + var namesToInstall = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); if (nameContainsWildcard) { WriteError(new ErrorRecord( @@ -158,13 +158,13 @@ protected override void ProcessRecord() // this catches the case where Name wasn't passed in as null or empty, // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in namesToSearch - if (Name.Length == 0) + if (namesToInstall.Length == 0) { return; } installHelper.InstallPackages( - names: Name, + names: namesToInstall, versionRange: _versionRange, prerelease: Prerelease, repository: Repository, From 80292357bdc8633d23ffbac1911f0f821e1e1d2b Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 17:24:38 -0400 Subject: [PATCH 06/10] use local variable instead of Name property for assignments --- src/code/GetInstalledPSResource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/code/GetInstalledPSResource.cs b/src/code/GetInstalledPSResource.cs index 293a62124..7928c6e4c 100644 --- a/src/code/GetInstalledPSResource.cs +++ b/src/code/GetInstalledPSResource.cs @@ -112,7 +112,7 @@ protected override void ProcessRecord() { WriteDebug("Entering GetInstalledPSResource"); - Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); + var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) { WriteError(new ErrorRecord( @@ -124,13 +124,13 @@ protected override void ProcessRecord() // this catches the case where Name wasn't passed in as null or empty, // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in Name - if (Name.Length == 0) + if (namesToSearch.Length == 0) { return; } GetHelper getHelper = new GetHelper(this); - foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(Name, _versionRange, _pathsToSearch)) + foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(namesToSearch, _versionRange, _pathsToSearch)) { WriteObject(pkg); } From d78deef4cdf582f73c9c89c453e9e67481954f3f Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 17:43:30 -0400 Subject: [PATCH 07/10] made Install test compatible with Pester 4 --- test/InstallPSResource.Tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/InstallPSResource.Tests.ps1 b/test/InstallPSResource.Tests.ps1 index 6d86d349a..ef206fece 100644 --- a/test/InstallPSResource.Tests.ps1 +++ b/test/InstallPSResource.Tests.ps1 @@ -24,9 +24,10 @@ Describe 'Test Install-PSResource for Module' { $testCases = @{Name="*"; ErrorId="NameContainsWildcard"}, @{Name="TestModule*"; ErrorId="NameContainsWildcard"}, - @{Name="Test?Module", "Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + @{Name="Test?Module","Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} It "Should not install resource with wildcard in name" -TestCases $testCases { + param($Name, $ErrorId) Install-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue $err.Count | Should -Not -Be 0 $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.InstallPSResource" From 04d78d05e52af595e903c19eaa616f47e62c02e5 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 18:02:24 -0400 Subject: [PATCH 08/10] add tests for Save --- src/code/InstallPSResource.cs | 2 +- src/code/SavePSResource.cs | 29 ++++++++++++++++++++++++++++- test/SavePSResource.Tests.ps1 | 6 ++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 20cca0519..d546e6b4a 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -157,7 +157,7 @@ protected override void ProcessRecord() } // this catches the case where Name wasn't passed in as null or empty, - // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in namesToSearch + // but after filtering out unsupported wildcard names there are no elements left in namesToInstall if (namesToInstall.Length == 0) { return; diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index a68496dd6..ff4832ce0 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -151,8 +151,35 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: + var namesToSave = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + if (nameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + foreach (string error in errorMsgs) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); + } + + // this catches the case where Name wasn't passed in as null or empty, + // but after filtering out unsupported wildcard names there are no elements left in namesToSave + if (namesToSave.Length == 0) + { + return; + } + installHelper.InstallPackages( - names: Name, + names: namesToSave, versionRange: _versionRange, prerelease: Prerelease, repository: Repository, diff --git a/test/SavePSResource.Tests.ps1 b/test/SavePSResource.Tests.ps1 index 6a20641e3..7f107b21f 100644 --- a/test/SavePSResource.Tests.ps1 +++ b/test/SavePSResource.Tests.ps1 @@ -54,6 +54,12 @@ Describe 'Test Save-PSResource for PSResources' { $pkgDir.Name | Should -BeNullOrEmpty } + It "Not Save module with Name containing wildcard" { + Save-PSResource -Name "TestModule*" -Repository $TestGalleryName -Path $SaveDir -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "NameContainsWildcard,Microsoft.PowerShell.PowerShellGet.Cmdlets.SavePSResource" + } + # Do some version testing, but Find-PSResource should be doing thorough testing It "Should save resource given name and exact version" { Save-PSResource -Name "TestModule" -Version "1.2.0" -Repository $TestGalleryName -Path $SaveDir From b881dc896d0fa1a5fd794e76beb27d419f5485e7 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 18:23:44 -0400 Subject: [PATCH 09/10] add error handling/support for wildcards for Uninstall-PSResource --- src/code/UninstallPSResource.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 0a69e4617..03656830d 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -1,3 +1,4 @@ +using System.Text; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -16,7 +17,7 @@ namespace Microsoft.PowerShell.PowerShellGet.Cmdlets /// /// Uninstall-PSResource uninstalls a package found in a module or script installation path. /// - [Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true, HelpUri = "")] + [Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)] public sealed class UninstallPSResource : PSCmdlet { #region Parameters @@ -83,6 +84,31 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: + Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + if (nameContainsWildcard) + { + if (!ShouldProcess(string.Format("Uninstall resource with wildcard, so all of the following will be uninstalled from machine: '{0}'.", String.Join(",", Name)))) + { + return; + } + } + + foreach (string error in errorMsgs) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); + } + + // this catches the case where Name wasn't passed in as null or empty, + // but after filtering out unsupported wildcard names there are no elements left in Name + if (Name.Length == 0) + { + return; + } + if (!UninstallPkgHelper()) { // any errors should be caught lower in the stack, this debug statement will let us know if there was an unusual failure From 03dfbeab30f22e323b8ab0e4312546094c276cfa Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 2 Aug 2021 19:44:38 -0400 Subject: [PATCH 10/10] remove confirm high impact from Uninstall for now --- src/code/UninstallPSResource.cs | 11 ++--------- test/UninstallPSResource.Tests.ps1 | 10 ++++++++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 03656830d..5081d039b 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -17,7 +17,7 @@ namespace Microsoft.PowerShell.PowerShellGet.Cmdlets /// /// Uninstall-PSResource uninstalls a package found in a module or script installation path. /// - [Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)] + [Cmdlet(VerbsLifecycle.Uninstall, "PSResource", DefaultParameterSetName = NameParameterSet, SupportsShouldProcess = true)] public sealed class UninstallPSResource : PSCmdlet { #region Parameters @@ -84,14 +84,7 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: - Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); - if (nameContainsWildcard) - { - if (!ShouldProcess(string.Format("Uninstall resource with wildcard, so all of the following will be uninstalled from machine: '{0}'.", String.Join(",", Name)))) - { - return; - } - } + Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) { diff --git a/test/UninstallPSResource.Tests.ps1 b/test/UninstallPSResource.Tests.ps1 index 511f43016..f20e967ae 100644 --- a/test/UninstallPSResource.Tests.ps1 +++ b/test/UninstallPSResource.Tests.ps1 @@ -23,6 +23,16 @@ Describe 'Test Uninstall-PSResource for Modules' { Get-Module ContosoServer -ListAvailable | Should -Be $null } + $testCases = @{Name="Test?Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"}, + @{Name="Test[Module"; ErrorId="ErrorFilteringNamesForUnsupportedWildcards"} + + It "not uninstall module given Name with invalid wildcard characters" -TestCases $testCases { + param($Name, $ErrorId) + Uninstall-PSResource -Name $Name -ErrorVariable err -ErrorAction SilentlyContinue + $err.Count | Should -Not -Be 0 + $err[0].FullyQualifiedErrorId | Should -BeExactly "$ErrorId,Microsoft.PowerShell.PowerShellGet.Cmdlets.UninstallPSResource" + } + It "Uninstall a list of modules by name" { $null = Install-PSResource BaseTestPackage -Repository $TestGalleryName -TrustRepository -WarningAction SilentlyContinue