diff --git a/src/PSGet.Format.ps1xml b/src/PSGet.Format.ps1xml index 8d2ee44e6..6ebfff609 100644 --- a/src/PSGet.Format.ps1xml +++ b/src/PSGet.Format.ps1xml @@ -27,6 +27,28 @@ + + PSCommandResourceInfo + + Microsoft.PowerShell.PowerShellGet.UtilClasses.PSCommandResourceInfo + + + + + + + + + + + Names + $_.ParentResource.Name + $_.ParentResource.Version + + + + + PSIncludedResourceInfoTable diff --git a/src/code/FindHelper.cs b/src/code/FindHelper.cs index 5ef2995fe..966429525 100644 --- a/src/code/FindHelper.cs +++ b/src/code/FindHelper.cs @@ -90,12 +90,12 @@ public List FindByResourceName( return foundPackages; } - _pkgsLeftToFind = name.ToList(); + _pkgsLeftToFind = new List(name); // Error out if repository array of names to be searched contains wildcards. if (repository != null) { - repository = Utils.ProcessNameWildcards(repository, out string[] errorMsgs, out _repositoryNameContainsWildcard); + repository = Utils.ProcessNameWildcards(repository, removeWildcardEntries:false, out string[] errorMsgs, out _repositoryNameContainsWildcard); foreach (string error in errorMsgs) { _cmdletPassedIn.WriteError(new ErrorRecord( @@ -154,6 +154,161 @@ public List FindByResourceName( return foundPackages; } + public List FindCommandOrDscResource( + ResourceType type, + SwitchParameter prerelease, + string[] tag, + string[] repository, + PSCredential credential) + { + _type = type; + _prerelease = prerelease; + _tag = tag; + _credential = credential; + + List foundPackages = new List(); + List cmdsLeftToFind = new List(tag); + + if (tag.Length == 0) + { + return foundPackages; + } + + // Error out if repository array of names to be searched contains wildcards. + if (repository != null) + { + repository = Utils.ProcessNameWildcards(repository, removeWildcardEntries:false, out string[] errorMsgs, out _repositoryNameContainsWildcard); + foreach (string error in errorMsgs) + { + _cmdletPassedIn.WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); + } + } + + // Get repositories to search. + List repositoriesToSearch; + try + { + repositoriesToSearch = RepositorySettings.Read(repository, out string[] errorList); + foreach (string error in errorList) + { + _cmdletPassedIn.WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorGettingSpecifiedRepo", + ErrorCategory.InvalidOperation, + this)); + } + } + catch (Exception e) + { + _cmdletPassedIn.ThrowTerminatingError(new ErrorRecord( + new PSInvalidOperationException(e.Message), + "ErrorLoadingRepositoryStoreFile", + ErrorCategory.InvalidArgument, + this)); + + return foundPackages; + } + + for (int i = 0; i < repositoriesToSearch.Count && cmdsLeftToFind.Any(); i++) + { + _cmdletPassedIn.WriteVerbose(string.Format("Searching in repository {0}", repositoriesToSearch[i].Name)); + if (repositoriesToSearch[i].ApiVersion == PSRepositoryInfo.APIVersion.v2) + { + foreach (PSCommandResourceInfo cmdInfo in HttpFindCmdOrDsc(repositoriesToSearch[i], _type)) + { + foundPackages.Add(cmdInfo); + + foreach (string cmd in cmdInfo.Names) + { + cmdsLeftToFind.Remove(cmd); + } + } + } + } + + return foundPackages; + } + + public List FindTag( + ResourceType type, + SwitchParameter prerelease, + string[] tag, + string[] repository, + PSCredential credential) + { + _type = type; + _prerelease = prerelease; + _tag = tag; + _credential = credential; + + List foundPackages = new List(); + List tagsLeftToFind = new List(tag); + + if (tag.Length == 0) + { + return foundPackages; + } + + // Error out if repository array of names to be searched contains wildcards. + if (repository != null) + { + repository = Utils.ProcessNameWildcards(repository, removeWildcardEntries:false, out string[] errorMsgs, out _repositoryNameContainsWildcard); + foreach (string error in errorMsgs) + { + _cmdletPassedIn.WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorFilteringNamesForUnsupportedWildcards", + ErrorCategory.InvalidArgument, + this)); + } + } + + // Get repositories to search. + List repositoriesToSearch; + try + { + repositoriesToSearch = RepositorySettings.Read(repository, out string[] errorList); + foreach (string error in errorList) + { + _cmdletPassedIn.WriteError(new ErrorRecord( + new PSInvalidOperationException(error), + "ErrorGettingSpecifiedRepo", + ErrorCategory.InvalidOperation, + this)); + } + } + catch (Exception e) + { + _cmdletPassedIn.ThrowTerminatingError(new ErrorRecord( + new PSInvalidOperationException(e.Message), + "ErrorLoadingRepositoryStoreFile", + ErrorCategory.InvalidArgument, + this)); + + return foundPackages; + } + + for (int i = 0; i < repositoriesToSearch.Count && tagsLeftToFind.Any(); i++) + { + _cmdletPassedIn.WriteVerbose(string.Format("Searching in repository {0}", repositoriesToSearch[i].Name)); + if (repositoriesToSearch[i].ApiVersion == PSRepositoryInfo.APIVersion.v2) + { + // tag1, tag2, tag3 + + // TODO: didn't really finsh come back here + foreach (PSResourceInfo cmdInfo in HttpSearchFromRepository(repositoriesToSearch[i])) + { + foundPackages.Add(cmdInfo); + } + } + } + + return foundPackages; + } #endregion #region Private methods @@ -701,6 +856,12 @@ private PSResourceInfo[] HttpFindTags(PSRepositoryInfo repository, ResourceType // TODO: write out error } + private PSCommandResourceInfo[] HttpFindCmdOrDsc(PSRepositoryInfo repository, ResourceType type) + { + return _httpFindPSResource.FindCommandOrDscResource(_tag, repository, _prerelease, type, out string errRecord); + // TODO: write out error + } + private List FindDependencyPackages( PSResourceInfo currentPkg, PackageMetadataResource packageMetadataResource, diff --git a/src/code/FindPSResource.cs b/src/code/FindPSResource.cs index 41644153a..1bf918563 100644 --- a/src/code/FindPSResource.cs +++ b/src/code/FindPSResource.cs @@ -20,15 +20,16 @@ namespace Microsoft.PowerShell.PowerShellGet.Cmdlets /// [Cmdlet(VerbsCommon.Find, "PSResource", - DefaultParameterSetName = ResourceNameParameterSet)] + DefaultParameterSetName = NameParameterSet)] [OutputType(typeof(PSResourceInfo), typeof(PSCommandResourceInfo))] public sealed class FindPSResource : PSCmdlet { #region Members - private const string ResourceNameParameterSet = "ResourceNameParameterSet"; + private const string NameParameterSet = "NameParameterSet"; private const string CommandNameParameterSet = "CommandNameParameterSet"; private const string DscResourceNameParameterSet = "DscResourceNameParameterSet"; + private const string TagParameterSet = "TagParameterSet"; private CancellationTokenSource _cancellationTokenSource; private FindHelper _findHelper; @@ -42,7 +43,7 @@ public sealed class FindPSResource : PSCmdlet [SupportsWildcards] [Parameter(Position = 0, ValueFromPipeline = true, - ParameterSetName = ResourceNameParameterSet)] + ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } @@ -50,34 +51,23 @@ public sealed class FindPSResource : PSCmdlet /// Specifies one or more resource types to find. /// Resource types supported are: Module, Script, Command, DscResource /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = TagParameterSet)] public ResourceType Type { get; set; } /// /// Specifies the version of the resource to be found and returned. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string Version { get; set; } /// /// When specified, includes prerelease versions in search. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter()] public SwitchParameter Prerelease { get; set; } - /// - /// Specifies a module resource package name type to search for. Wildcards are supported. - /// - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] - [ValidateNotNullOrEmpty] - public string[] ModuleName { get; set; } - /// /// Specifies a list of command names that searched module packages will provide. Wildcards are supported. /// @@ -95,18 +85,14 @@ public sealed class FindPSResource : PSCmdlet /// /// Filters search results for resources that include one or more of the specified tags. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter(ParameterSetName = TagParameterSet)] [ValidateNotNull] public string[] Tag { get; set; } /// /// Specifies one or more repository names to search. If not specified, search will include all currently registered repositories. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter()] [ArgumentCompleter(typeof(RepositoryNameCompleter))] [ValidateNotNullOrEmpty] public string[] Repository { get; set; } @@ -114,17 +100,13 @@ public sealed class FindPSResource : PSCmdlet /// /// Specifies optional credentials to be used when accessing a repository. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter()] public PSCredential Credential { get; set; } /// /// When specified, search will return all matched resources along with any resources the matched resources depends on. /// - [Parameter(ParameterSetName = ResourceNameParameterSet)] - [Parameter(ParameterSetName = CommandNameParameterSet)] - [Parameter(ParameterSetName = DscResourceNameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] public SwitchParameter IncludeDependencies { get; set; } #endregion @@ -158,7 +140,7 @@ protected override void ProcessRecord() { switch (ParameterSetName) { - case ResourceNameParameterSet: + case NameParameterSet: ProcessResourceNameParameterSet(); break; @@ -170,6 +152,10 @@ protected override void ProcessRecord() ProcessCommandOrDscParameterSet(isSearchingForCommands: false); break; + case TagParameterSet: + ProcessTagParameterSet(); + break; + default: Dbg.Assert(false, "Invalid parameter set"); break; @@ -198,7 +184,7 @@ private void ProcessResourceNameParameterSet() Name = new string[] {"*"}; } - Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); + Name = Utils.ProcessNameWildcards(Name, removeWildcardEntries:false, out string[] errorMsgs, out bool nameContainsWildcard); foreach (string error in errorMsgs) { @@ -238,24 +224,16 @@ private void ProcessCommandOrDscParameterSet(bool isSearchingForCommands) { var commandOrDSCNamesToSearch = Utils.ProcessNameWildcards( pkgNames: isSearchingForCommands ? CommandName : DscResourceName, + removeWildcardEntries: true, errorMsgs: out string[] errorMsgs, - isContainWildcard: out bool nameContainsWildcard); - - if (nameContainsWildcard) - { - WriteError(new ErrorRecord( - new PSInvalidOperationException("Wilcards are not supported for -CommandName or -DSCResourceName for Find-PSResource. So all CommandName or DSCResourceName entries will be discarded."), - "CommandDSCResourceNameWithWildcardsNotSupported", - ErrorCategory.InvalidArgument, - this)); - return; - } + isContainWildcard: out bool _); + var paramName = isSearchingForCommands ? "CommandName" : "DscResourceName"; foreach (string error in errorMsgs) { WriteError(new ErrorRecord( - new PSInvalidOperationException(error), - "ErrorFilteringCommandDscResourceNamesForUnsupportedWildcards", + new PSInvalidOperationException($"Wildcards are not supported for -{paramName}: {error}"), + "WildcardsUnsupportedForCommandNameorDSCResourceName", ErrorCategory.InvalidArgument, this)); } @@ -267,50 +245,59 @@ private void ProcessCommandOrDscParameterSet(bool isSearchingForCommands) return; } - var moduleNamesToSearch = Utils.ProcessNameWildcards( - pkgNames: ModuleName, - errorMsgs: out string[] moduleErrorMsgs, + List foundPackages = _findHelper.FindCommandOrDscResource( + type: isSearchingForCommands? ResourceType.Command : ResourceType.DscResource, + prerelease: Prerelease, + tag: commandOrDSCNamesToSearch, + repository: Repository, + credential: Credential); + + // if a single package contains multiple commands we are interested in, return a unique entry for each: + // Command1 , PackageA + // Command2 , PackageA + foreach (var package in foundPackages) + { + WriteObject(package); + } + } + + private void ProcessTagParameterSet() + { + var tagsToSearch = Utils.ProcessNameWildcards( + pkgNames: Tag, + removeWildcardEntries: true, + errorMsgs: out string[] errorMsgs, isContainWildcard: out bool _); - foreach (string error in moduleErrorMsgs) + foreach (string error in errorMsgs) { WriteError(new ErrorRecord( - new PSInvalidOperationException(error), - "ErrorFilteringModuleNamesForUnsupportedWildcards", + new PSInvalidOperationException($"Wildcards are not supported for -Tag: {error}"), + "WildcardsUnsupportedForTag", ErrorCategory.InvalidArgument, this)); } - if (moduleNamesToSearch.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 tagsToSearch + if (tagsToSearch.Length == 0) { - moduleNamesToSearch = new string[] {"*"}; + return; } - + List foundPackages = _findHelper.FindByResourceName( - name: moduleNamesToSearch, - type: isSearchingForCommands? ResourceType.Command : ResourceType.DscResource, + name: Utils.EmptyStrArray, + type: Type, version: Version, prerelease: Prerelease, - tag: Tag, + tag: tagsToSearch, repository: Repository, credential: Credential, includeDependencies: IncludeDependencies); - - // if a single package contains multiple commands we are interested in, return a unique entry for each: - // Command1 , PackageA - // Command2 , PackageA - foreach (string nameToSearch in commandOrDSCNamesToSearch) + + foreach (var package in foundPackages) { - foreach (var package in foundPackages) - { - // this check ensures DSC names provided as a Command name won't get returned mistakenly - // -CommandName "command1", "dsc1" <- (will not return or add DSC name) - if ((isSearchingForCommands && package.Includes.Command.Contains(nameToSearch)) || - (!isSearchingForCommands && package.Includes.DscResource.Contains(nameToSearch))) - { - WriteObject(new PSCommandResourceInfo(nameToSearch, package)); - } - } + WriteObject(package); } } diff --git a/src/code/GetPSResource.cs b/src/code/GetPSResource.cs index 6a167eca1..ad7334a14 100644 --- a/src/code/GetPSResource.cs +++ b/src/code/GetPSResource.cs @@ -118,7 +118,7 @@ protected override void ProcessRecord() { WriteVerbose("Entering GetPSResource"); - var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); + var namesToSearch = Utils.ProcessNameWildcards(Name, removeWildcardEntries:false, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) { WriteError(new ErrorRecord( diff --git a/src/code/HttpFindPSResource.cs b/src/code/HttpFindPSResource.cs index 4e6a66e55..b0bfb1698 100644 --- a/src/code/HttpFindPSResource.cs +++ b/src/code/HttpFindPSResource.cs @@ -62,12 +62,20 @@ public PSResourceInfo[] FindTags(string[] tags, PSRepositoryInfo repository, boo { errRecord = String.Empty; List pkgsFound = new List(); - HashSet tagPkgs = new HashSet(); + HashSet tagPkgs = new HashSet(); + // TAG example: + // chocolatey, crescendo + // > chocolatey === ModuleA + // > crescendo === ModuleA + // ---> for tags get rid of duplicate modules + foreach (string tag in tags) { string[] responses = v2ServerAPICall.FindTag(tag, repository, includePrerelease, type, out errRecord); + // TODO: map the tag with the package which the tag came from + foreach (string response in responses) { var elemList = ConvertResponseToXML(response); @@ -100,6 +108,80 @@ public PSResourceInfo[] FindTags(string[] tags, PSRepositoryInfo repository, boo return pkgsFound.ToArray(); } + /// + /// Find method which allows for searching for packages with tag(s) from a repository and returns latest version for each. + /// Examples: Search -Tag "JSON" -Repository PSGallery + /// API call: + /// - No prerelease: http://www.powershellgallery.com/api/v2/Search()?$filter=IsLatestVersion&searchTerm='tag:JSON' + /// - Include prerelease: http://www.powershellgallery.com/api/v2/Search()?$filter=IsAbsoluteLatestVersion&searchTerm='tag:JSON'&includePrerelease=true + /// + public PSCommandResourceInfo[] FindCommandOrDscResource(string[] tags, PSRepositoryInfo repository, bool includePrerelease, ResourceType type, out string errRecord) + { + errRecord = String.Empty; + Hashtable pkgHash = new Hashtable(); + List cmdInfoObjs = new List(); + + // COMMAND example: + // command1, command2 + // > command1 === ModuleA + // > command2 === ModuleA + // + // > command1, command2 === ModuleA + + foreach (string tag in tags) + { + string[] responses = v2ServerAPICall.FindTag(tag, repository, includePrerelease, type, out errRecord); + + + foreach (string response in responses) + { + var elemList = ConvertResponseToXML(response); + + foreach (var element in elemList) + { + PSResourceInfo.TryConvertFromXml( + element, + includePrerelease, + out PSResourceInfo psGetInfo, + repository.Name, + out string errorMsg); + + if (psGetInfo != null ) + { + // Map the tag with the package which the tag came from + if (!pkgHash.Contains(psGetInfo.Name)) + { + pkgHash.Add(psGetInfo.Name, Tuple.Create, PSResourceInfo>(new List { tag }, psGetInfo)); + } + else { + // if the package is already in the hashtable, add this tag to the list of tags associated with that package + Tuple, PSResourceInfo> hashValue = (Tuple, PSResourceInfo>)pkgHash[psGetInfo.Name]; + hashValue.Item1.Add(tag); + } + } + else + { + // TODO: Write error for corresponding null scenario + // TODO: array out of bounds exception when name does not exist + // http://www.powershellgallery.com/api/v2/Search()?$filter=IsLatestVersion&searchTerm='tag:PSCommand_Get-TargetResource' + errRecord = errorMsg; + } + } + } + } + + // convert hashtable to PSCommandInfo + foreach(DictionaryEntry pkg in pkgHash) + { + Tuple, PSResourceInfo> hashValue = (Tuple, PSResourceInfo>) pkg.Value; + + cmdInfoObjs.Add(new PSCommandResourceInfo(hashValue.Item1.ToArray(), hashValue.Item2)); + } + + return cmdInfoObjs.ToArray(); + } + + /// /// Find method which allows for searching for packages with resource type specified from a repository and returns latest version for each. /// Name: supports wildcards diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 84e563235..2b9eba28e 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -501,7 +501,7 @@ private void RequiredResourceHelper(Hashtable reqResourceHash) private void ProcessInstallHelper(string[] pkgNames, VersionRange pkgVersion, bool pkgPrerelease, string[] pkgRepository, PSCredential pkgCredential, InstallPkgParams reqResourceParams) { - var inputNameToInstall = Utils.ProcessNameWildcards(pkgNames, out string[] errorMsgs, out bool nameContainsWildcard); + var inputNameToInstall = Utils.ProcessNameWildcards(pkgNames, removeWildcardEntries:false, out string[] errorMsgs, out bool nameContainsWildcard); if (nameContainsWildcard) { WriteError(new ErrorRecord( diff --git a/src/code/PSResourceInfo.cs b/src/code/PSResourceInfo.cs index 55a9fbebb..75e911cfb 100644 --- a/src/code/PSResourceInfo.cs +++ b/src/code/PSResourceInfo.cs @@ -202,7 +202,7 @@ public sealed class PSCommandResourceInfo // included by the PSResourceInfo property #region Properties - public string Name { get; } + public string[] Names { get; } public PSResourceInfo ParentResource { get; } @@ -213,11 +213,11 @@ public sealed class PSCommandResourceInfo /// /// Constructor /// - /// Name of the command or DSC resource + /// Name of the command or DSC resource /// the parent module resource the command or dsc resource belongs to - public PSCommandResourceInfo(string name, PSResourceInfo parentResource) + public PSCommandResourceInfo(string[] names, PSResourceInfo parentResource) { - Name = name; + Names = names; ParentResource = parentResource; } diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index 15922899a..36868eff3 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -232,7 +232,7 @@ protected override void ProcessRecord() private void ProcessSaveHelper(string[] pkgNames, bool pkgPrerelease, string[] pkgRepository) { - var namesToSave = Utils.ProcessNameWildcards(pkgNames, out string[] errorMsgs, out bool nameContainsWildcard); + var namesToSave = Utils.ProcessNameWildcards(pkgNames, removeWildcardEntries:false, out string[] errorMsgs, out bool nameContainsWildcard); if (nameContainsWildcard) { WriteError(new ErrorRecord( diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 96a15d362..2714e2ff0 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -101,7 +101,7 @@ protected override void ProcessRecord() ThrowTerminatingError(IncorrectVersionFormat); } - Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); + Name = Utils.ProcessNameWildcards(Name, removeWildcardEntries:false, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) { diff --git a/src/code/UnregisterPSResourceRepository.cs b/src/code/UnregisterPSResourceRepository.cs index c18257007..058393c1d 100644 --- a/src/code/UnregisterPSResourceRepository.cs +++ b/src/code/UnregisterPSResourceRepository.cs @@ -45,7 +45,7 @@ protected override void BeginProcessing() } protected override void ProcessRecord() { - Name = Utils.ProcessNameWildcards(Name, out string[] _, out bool nameContainsWildcard); + Name = Utils.ProcessNameWildcards(Name, removeWildcardEntries:false, out string[] _, out bool nameContainsWildcard); if (nameContainsWildcard) { var message = String.Format("Name: '{0}, cannot contain wildcards", String.Join(", ", Name)); diff --git a/src/code/UpdatePSResource.cs b/src/code/UpdatePSResource.cs index fcb0dfe3e..3f4a62657 100644 --- a/src/code/UpdatePSResource.cs +++ b/src/code/UpdatePSResource.cs @@ -255,6 +255,7 @@ private string[] ProcessPackageNames( { namesToProcess = Utils.ProcessNameWildcards( pkgNames: namesToProcess, + removeWildcardEntries:false, errorMsgs: out string[] errorMsgs, isContainWildcard: out bool _); diff --git a/src/code/Utils.cs b/src/code/Utils.cs index 5c8b214b7..77309af8a 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -128,6 +128,7 @@ public static string[] GetStringArray(ArrayList list) public static string[] ProcessNameWildcards( string[] pkgNames, + bool removeWildcardEntries, out string[] errorMsgs, out bool isContainWildcard) { @@ -146,6 +147,13 @@ public static string[] ProcessNameWildcards( { if (WildcardPattern.ContainsWildcardCharacters(name)) { + if (removeWildcardEntries) + { + // Tag // CommandName // DSCResourceName + errorMsgsList.Add($"{name} will be discarded from the provided entries."); + continue; + } + if (String.Equals(name, "*", StringComparison.InvariantCultureIgnoreCase)) { isContainWildcard = true;