{"id":11110,"date":"2016-02-10T06:00:04","date_gmt":"2016-02-10T14:00:04","guid":{"rendered":"https:\/\/www.sapien.com\/blog\/?p=11110"},"modified":"2016-02-06T15:57:55","modified_gmt":"2016-02-06T23:57:55","slug":"use-group-object-to-detect-command-name-conflicts","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2016\/02\/10\/use-group-object-to-detect-command-name-conflicts\/","title":{"rendered":"Using Group-Object to Detect Command Name Conflicts"},"content":{"rendered":"<p>The <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113338\" target=\"_blank\">Group-Object<\/a> cmdlet, one of the original <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113250\" target=\"_blank\">provider cmdlets<\/a>,\u00a0is as old as Windows PowerShell. It was introduced in version 1.0 and hasn&#8217;t changed at all since then. But, it is one of my favorites. (You can tell\u00a0when I love a cmdlet by the number of examples. Group-Object has 9!) In fact, when you use it frequently, you begin to see groups as\u00a0a\u00a0path to many solutions.<\/p>\n<p><strong>Group-Object<\/strong> groups objects by the values of a property that you choose. So, it&#8217;s a quick way to find the property values that appear in a data set. Which domain controllers are used by users in this department? What command types are exported by this module? It&#8217;s also a great way to detect duplicate and unique values. (Really, try a few of the 9 examples.)<\/p>\n<p>In this post, I&#8217;ll be using an old cmdlet to help with a new problem &#8212; detecting multiple commands with the same name on the same machine.\u00a0 Because\u00a0providers and\u00a0repositories\u00a0offer more\u00a0modules, we can install module versions side-by-side on 5.0,\u00a0and we can install them in a blink without much consideration, name collisions are more likely than ever.<\/p>\n<hr \/>\n<h1>Detect commands with the same name<\/h1>\n<p>To detect commands with the same names in your installed modules, use the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113309\">Get-Command <\/a>cmdlet to get all commands in all installed modules. Then, use the <strong>Group-Object<\/strong> cmdlet to group commands by the value of their <strong>Name<\/strong> property. The result is a collection of groups where each group contains\u00a0commands with the same name.<\/p>\n<p>Some groups have just one member. But, each group that <strong>Group-Object<\/strong>\u00a0returns has a <strong>Count<\/strong> property that indicates the number of\u00a0objects in the group. That makes it easy to use the <strong>Where-Object<\/strong> cmdlet to find groups that have more than one member.<\/p>\n<pre lang=\"PowerShell\">$groups = Get-Command | Group-Object -Property Name | Where Count -gt 1<\/pre>\n<p>Let&#8217;s look at one of the multi-member groups. This is one for the Describe command in the Pester module. I use and study Pester pretty obsessively, so I have multiple versions of the Pester module on my test machine.<\/p>\n<pre class=\"output\">PS C:\\&gt; $groups | where Name -eq 'Describe'\r\n\r\nCount Name                      Group\r\n----- ----                      -----\r\n    6 Describe                  {Describe, Describe, Describe, Describe...}<\/pre>\n<p>This group has\u00a06 members, that is,\u00a06 Describe commands.<\/p>\n<p>Each group that <strong>Group-Object<\/strong> returns also has a <strong>Group<\/strong> property that contains the members of the group. In this case, the <strong>Group<\/strong> property of the Describe group contains\u00a0the Describe\u00a0commands.<\/p>\n<pre class=\"output\">PS C:\\&gt; ($groups | where Name -eq 'Describe').Group\r\n\r\nCommandType     Name             Version    Source\r\n-----------     ----             -------    ------\r\nFunction        Describe         3.3.13     Pester\r\nFunction        Describe         3.3.11     Pester\r\nFunction        Describe         3.3.9      Pester\r\nFunction        Describe         3.3.10     Pester\r\nFunction        Describe         3.3.8      Pester\r\nFunction        Describe         3.3.5      Pester\r\n<\/pre>\n<p>The Describe\u00a0duplicates\u00a0represent the same command in different versions of the same module. But, we also find commands with the same name in different modules, such as this <strong>Set-Clipboard<\/strong> command.<\/p>\n<pre class=\"output\">PS C:\\&gt; ($groups | where Name -eq 'Set-Clipboard').Group\r\n\r\nCommandType     Name                 Version    Source\r\n-----------     ----                 -------    ------\r\nCmdlet          Set-Clipboard        3.1.0.0    Microsoft.PowerShell.Management\r\nCmdlet          Set-Clipboard        3.2.1.0    Pscx<\/pre>\n<h1>Detect commands with same name in different modules<\/h1>\n<p>To get commands with the same names in modules with different names, use Group-Object to create groups based on\u00a0the <strong>Source<\/strong> (module name) property value of each command and look for groups with more than one unique <strong>Source<\/strong> value.<\/p>\n<p>To count the number of sources\u00a0that the second <strong>Group-Object<\/strong> command returns, I use the <strong>Length<\/strong> property that PowerShell adds to all objects, because the\u00a0<strong>Count<\/strong> property is the number of objects in the group.<\/p>\n<pre lang=\"PowerShell\">Get-Command | Group-Object -Property Name | where { $_.Count -GT 1 -and ($_.Group | Group-Object -Property Source).Length -gt 1 }<\/pre>\n<p>To display the groups, I use the <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=293962\" target=\"_blank\">Format-Table<\/a> cmdlet with a calculated property for the <strong>Source <\/strong>value.<\/p>\n<pre lang=\"PowerShell\">$diftModules = Get-Command | Group-Object -Property Name | where { $_.Count -GT 1 -and ($_.Group | Group-Object -Property Source).Length -gt 1 }\r\n\r\n$diftModules | Format-Table -Property Name, @{Label = 'Module'; Expression = { $_.Group.Source } }<\/pre>\n<p>&nbsp;<\/p>\n<h1>Which command runs?<\/h1>\n<p>Now, that we can find commands with the same name, I&#8217;d like to know which command runs by default when I invoke that command without a\u00a0qualifying\u00a0module or version. The answer is not some new-fangled cmdlet. It&#8217;s good old <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=289583\" target=\"_blank\">Get-Command<\/a>.<\/p>\n<p>When the value of the <strong>Name<\/strong> parameter includes wildcard characters (*), <strong>Get-Command<\/strong> gets all commands with the specified name. But, when the value of the <strong>Name<\/strong> parameter has no wildcards, <strong>Get-Command<\/strong> gets the command that runs by default; the one that takes precedence.<\/p>\n<p>For example, using a wildcard character (*) in Name, you can see\u00a0the two\u00a0<strong>Set-Clipboard<\/strong> commands that Group-Object detected.<\/p>\n<pre class=\"output\">PS C:\\&gt; Get-Command Set-Clipboard*\r\n\r\nCommandType\u00a0\u00a0\u00a0\u00a0 Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Version\u00a0\u00a0\u00a0 Source\r\n-----------\u00a0\u00a0\u00a0\u00a0 ----\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-------\u00a0\u00a0\u00a0 ------\r\nCmdlet\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Set-Clipboard\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a03.1.0.0\u00a0\u00a0\u00a0 Microsoft.PowerShell.Management\r\nCmdlet\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Set-Clipboard\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a03.2.1.0\u00a0\u00a0\u00a0 Pscx<\/pre>\n<p>To find the one that runs by default,\u00a0run <strong>Get-Command<\/strong> with no wildcard characters. It&#8217;s the newest version in the user-specific module directory.<\/p>\n<pre class=\"output\">PS C:\\&gt; Get-Command Set-Clipboard\r\n\r\nCommandType\u00a0\u00a0\u00a0\u00a0 Name\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Version\u00a0\u00a0\u00a0 Source\r\n-----------\u00a0\u00a0\u00a0\u00a0 ----\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0-------\u00a0\u00a0\u00a0 ------\r\nCmdlet\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Set-Clipboard\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a03.1.0.0\u00a0\u00a0\u00a0 Microsoft.PowerShell.Management<\/pre>\n<p>This is very helpful. But, what do you do to make sure that you&#8217;re running the command that you want to run? Stay tuned for a series of posts on different strategies to avoid mistakes.<\/p>\n<p>&nbsp;<\/p>\n<p><em>June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at <\/em><a href=\"mailto:juneb@sapien.com\"><em>juneb@sapien.com<\/em><\/a><em>\u00a0and follow her on Twitter at <\/em><a href=\"https:\/\/twitter.com\/juneb_get_help\"><em>@juneb_get_help<\/em><\/a><em>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Group-Object cmdlet, one of the original provider cmdlets,\u00a0is as old as Windows PowerShell. It was introduced in version 1.0 and hasn&#8217;t changed at all since then. But, it is one of my favorites. (You can tell\u00a0when I love a cmdlet by the number of examples. Group-Object has 9!) In fact, when you use it [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[932,1034,2,283,941,703,25],"tags":[934,28,961,1016],"class_list":["post-11110","post","type-post","status-publish","format-standard","hentry","category-beginners","category-best-practices","category-general","category-howto","category-powershell-5-0","category-powershell-studio","category-windows-powershell","tag-juneb","tag-powershell","tag-powershell-5-0","tag-powershell-studio"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=11110"}],"version-history":[{"count":15,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11110\/revisions"}],"predecessor-version":[{"id":11129,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11110\/revisions\/11129"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=11110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=11110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=11110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}