Summary: Microsoft Scripting Guy, Ed Wilson, talks about discovering cool information by playing around with Windows PowerShell modules.

Microsoft Scripting Guy, Ed Wilson, is here. It is the weekend here in Charlotte, North Carolina in the United States. I am sipping a cup of oolong green tea with a bit of jasmine and cinnamon stick, and eating some fresh strawberries that the Scripting Wife found. I am listening to Traffic on my laptop, I have my Windows PowerShell console open, and I am playing around with modules.

Modules that have nested modules

The first thing to do when playing with module information is to import all of the modules. The easy way to do this is to use Get-Module (gmo is an alias) to get the modules, and then pipe the module info to the Import-Module cmdlet (ipmo is an alias). This command is shown here.

gmo -ListAvailable | ipmo

After I have imported all of the modules, I can use the Get-Module cmdlet to find modules that have nested modules. To do this, I look for values in the NestedModules property. This command is shown here.

Get-Module | ? nestedmodules | select name, nestedmodules

The command and its associated output are shown here.

Image of command output

To find out how many modules have nested modules, I pipe the results to the Measure-Object cmdlet as shown here.

PS C:\> Get-Module | ? nestedmodules | select name, nestedmodules | measure

Count    : 55

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

To see how many modules I have loaded, I use the Get-Module cmdlet and pipe the results to the Measure-Object cmdlet. This is shown here.

PS C:\> Get-Module | measure

Count    : 81

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

Finding numbers of exported commands

To find the number of exported commands from a cmdlet, I need to count how many cmdlets exist in the ExportedCommands property. I can directly access the ExportedCommands property by grouping the results of the command. This is shown here.

PS C:\> (Get-Module bestpractices).exportedcommands

Key                                        Value

---                                        -----

Get-BpaModel                               Get-BpaModel

Get-BpaResult                              Get-BpaResult

Invoke-BpaModel                            Invoke-BpaModel

Set-BpaResult                              Set-BpaResult

With the BestPractices module, it is rather easy to see how many commands it exports. But with a module such as the ActiveDirectory module, it may not be quite so easy. I could pipe the results to the Measure-Object cmdlet—but because the ExportedCommands property contains a dictionary object, it means I have access to the Count property. Therefore, I can simply add Count to the end of the command and arrive at the number of commands that are exported by the module. This technique is shown here.

PS C:\> (Get-Module bestpractices).exportedcommands.count

4

OK, that is cool, but what I really need is the ability to obtain the module name and the number of commands it exports. To do this, I need to create a custom object. The easiest way to create a custom object is to use the Select-Object cmdlet and select the properties I need. While I am at it, I want to create a custom label. The following is the command that I arrive at.

PS C:\> Get-Module bestpractices | select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}}

Name                                                                     cmdletCount

----                                                                     -----------

BestPractices                                                                      4

Cool. I can now simply delete the BestPractices module name, and I will obtain a list of all modules and the number of commands they export. Here is the revised code:

Get-Module | select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}}

This works great. But one problem is that the output is not in order. To do this, I simply add Sort-Object at the end of the command. (One nice thing about creating a custom object as output is that I can use Windows PowerShell to further manipulate the output.) The following command is a single-line command that I have broken for readability on the blog.

Get-Module |

select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}} |

sort cmdletcount –Descending

The command and the output associated with the command are shown here.

Image of command output

I can even pipe the results to the Out-GridView cmdlet and have a graphical tool to filter my results. This is shown in the following code.

Get-Module |

select name, @{LABEL='cmdletCount';EXPRESSION={[int]$_.exportedcommands.count}} |

sort cmdletcount -Descending |

Out-GridView

The Out-GridView tool is shown here.

Image of menu

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy