How do I check if a PowerShell module is installed?

To check if a module exists I have tried the following:

try {
    Import-Module SomeModule
    Write-Host "Module exists"
} 
catch {
    Write-Host "Module does not exist"
}

The output is:

Import-Module : The specified module 'SomeModule' was not loaded because no valid module file was found in any module directory.
At D:\keytalk\Software\Client\TestProjects\Export\test.ps1:2 char:5
+     Import-Module SomeModule
+     ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (SomeModule:String) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

Module exists

I do get an error, but no exception is thrown, so we see Module exists in the end, although SomeModule does not exist.

Is there a good way (preferably without generating an error) to detect if a PowerShell module is installed on the system?


Solution 1:

You can use the ListAvailable option of Get-Module:

if (Get-Module -ListAvailable -Name SomeModule) {
    Write-Host "Module exists"
} 
else {
    Write-Host "Module does not exist"
}

Solution 2:

A module could be in the following states:

  • imported
  • available on disk (or local network)
  • available in an online gallery

If you just want to have the darn thing available in a PowerShell session for use, here is a function that will do that or exit out if it cannot get it done:

function Load-Module ($m) {

    # If module is imported say that and do nothing
    if (Get-Module | Where-Object {$_.Name -eq $m}) {
        write-host "Module $m is already imported."
    }
    else {

        # If module is not imported, but available on disk then import
        if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) {
            Import-Module $m -Verbose
        }
        else {

            # If module is not imported, not available on disk, but is in online gallery then install and import
            if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) {
                Install-Module -Name $m -Force -Verbose -Scope CurrentUser
                Import-Module $m -Verbose
            }
            else {

                # If the module is not imported, not available and not in the online gallery then abort
                write-host "Module $m not imported, not available and not in an online gallery, exiting."
                EXIT 1
            }
        }
    }
}

Load-Module "ModuleName" # Use "PoshRSJob" to test it out

Solution 3:

The ListAvailable option doesn't work for me. Instead this does:

if (-not (Get-Module -Name "<moduleNameHere>")) {
    # module is not loaded
}

Or, to be more succinct:

if (!(Get-Module "<moduleNameHere>")) {
    # module is not loaded
}