Modules are the main way to extend functionality in PowerShell. In v2, if you wanted to access the functionality of a module you had to explicitly load it, using the Import-Module functionality. Starting with v3, if PowerShell encounters a command it doesn’t recognize it will go through the list of valid modules looking for that command, and if found load it automatically. Let’s take a look at an example.
First, let’s see what modules are already loaded.
Get-Module # Show modules loaded
ModuleType Name ExportedCommands ---------- ---- ---------------- Manifest Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...} Manifest Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Next, let’s see what’s available.
Get-Module -ListAvailable # Show what's available to load
Directory: C:\Users\rcain\Documents\WindowsPowerShell\Modules ModuleType Name ExportedCommands ---------- ---- ---------------- Script adoLib {New-Connection, new-sqlcommand, i... Script Agent {Get-SqlConnection, Get-SqlServer,... Script ISECreamBasic {Add-IseMenu, Remove-IseMenu} Script mySQLLib {New-MySQLConnection, new-MySqlCom... Script OracleClient {new-oracle_connection, invoke-ora... Script OracleIse {Connect-Oracle, Disconnect-Oracle... Script PBM {Get-PolicyStore, Get-TargetServer... Script PerfCounters {Invoke-Sqlcmd2, Get-ProcessPerfco... Script Repl {Get-SqlConnection, Get-ReplServer... Script ShowMbrs {New-ShowMbrs, Set-ShowMbrs, Get-G... Script SQLIse {Test-SqlScript, Out-SqlScript, In... Script SQLMaint {Invoke-DBMaint, Get-SqlConnection... Binary SQLParser {Test-SqlScript, Out-SqlScript} Script SQLProfiler {Invoke-Sqlcmd2, Save-InfoToSQLTab... Script SQLPSX Script SQLServer {Get-SqlConnection, Get-SqlServer,... Script SSIS {New-ISApplication, Copy-ISItemSQL... Script WPK {Add-CodeGenerationRule, ConvertFr... Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules ModuleType Name ExportedCommands ---------- ---- ---------------- Manifest AppLocker {Set-AppLockerPolicy, Get-AppLocke... Manifest BitsTransfer {Add-BitsFile, Remove-BitsTransfer... Manifest CimCmdlets {Get-CimAssociatedInstance, Get-Ci... Manifest Microsoft.PowerShell.Diagnostics {Get-WinEvent, Get-Counter, Import... Manifest Microsoft.PowerShell.Host {Start-Transcript, Stop-Transcript} Manifest Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear... Manifest Microsoft.PowerShell.Security {Get-Acl, Set-Acl, Get-PfxCertific... Manifest Microsoft.PowerShell.Utility {Format-List, Format-Custom, Forma... Manifest Microsoft.WSMan.Management {Disable-WSManCredSSP, Enable-WSMa... Manifest PSDiagnostics {Disable-PSTrace, Disable-PSWSManC... Binary PSScheduledJob {New-JobTrigger, Add-JobTrigger, R... Manifest PSWorkflow New-PSWorkflowExecutionOption Manifest TroubleshootingPack {Get-TroubleshootingPack, Invoke-T...
The CIM cmdlets are a new set that ships with v3. Looking at the output above, you’ll note the CIM module (CimCmdlets, highlighted in second set of modules) is not loaded. Let’s run one of the cmdlets from the module.
# Note the CimCmdlets module isn't loaded. # Now run a command from that module Get-CimInstance win32_bios
SMBIOSBIOSVersion : 8DET50WW (1.20 ) Manufacturer : LENOVO Name : Default System BIOS SerialNumber : XXXXXXXX Version : LENOVO - 1200
Now let’s run Get-Module again, and you’ll see that the module has now been loaded. Pretty slick.
# Run again to show CimCmdlets is now loaded Get-Module
ModuleType Name ExportedCommands ---------- ---- ---------------- Binary CimCmdlets {Get-CimAssociatedInstance, Get-Ci... Manifest Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkp... Manifest Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Varia...
Of course this does have some drawbacks. First, it will take time for PowerShell to search through all the paths looking for the commands. Second, if the requested module isn’t in one of the predefined path, it will still fail. Finally, just for the sake of self-documentation it’s better to know what modules your script depends on. For that reason when writing scripts or modules of my own I will continue to explicitly use Import-Module, and suggest you do too.
However, when working in interactive mode, i.e. running a PowerShell console and entering commands, auto loading can be a huge timesaver. No longer do I have to take time to issue an Import-Module cmdlet before I can use the commands I need.
Warning: This post was written using PowerShell v3 BETA. Changes between now and the final release may affect the validity of this post.