@Viking Here is a variation of your one-liner to provide some additional context.
Get-Module -ListAvailable | Group-Object -Property Name | Sort-Object Name | ForEach-Object { if ($_.Count -eq 1) { "$($_.Name) - $($_.Group.Version)" } else { $_.Group | Sort-Object Version, Path -Descending | ForEach-Object { "$($_.Name) - $($_.Version) ($(Split-Path -Parent $_.Path | ForEach-Object { if([Version]::TryParse((Split-Path $_ -Leaf), [ref]$null)) { Split-Path -Parent $_} else {$_} } | Split-Path -Parent))" } } }
This will produce output lines matching one of two patterns:
Module-Name - Version
Module-Name - Version (Path)
When only a single version/instance of a module is present, the first output will be generated. If a module is installed in multiple locations or there are multiple versions of that module installed, the second output will be generated. In the event you only want the second pattern for all modules, you can use this instead:
Get-Module -ListAvailable | Group-Object -Property Name | Sort-Object Name | ForEach-Object { $_.Group | Sort-Object Version, Path -Descending | ForEach-Object { "$($_.Name) - $($_.Version) ($(Split-Path -Parent $_.Path | ForEach-Object { if([Version]::TryParse((Split-Path $_ -Leaf), [ref]$null)) { Split-Path -Parent $_} else {$_} } | Split-Path -Parent))" } }
Get-Module is a core PowerShell cmdlet that is fully cross-platform supported and uses the same internal code that performs the actual module loading for PowerShell to generate it’s output. This cmdlet will enumerate all the module paths that the current session knows about (via the environmental variable PSModulePath) regardless of architecture (32/64-bit) so running thru BigFix under the 32-bit context will produce valid results.
Get-InstalledModule on the other hand is a cmdlet out of the PowerShellGet module that will list only modules that have been installed via the PowerShellGet Install-Module cmdlets.
Hope this helps.