Install-PSModules.ps1
<# .Synopsis Installs and imports PowerShell modules defined in psmodules.json. .Description Like `dotnet tool install` for PowerShell Modules. psmodules.json file defines the modules to be installed. Modules are installed to the user scope. psmodules.json schema is: { "modules": [ { "name": "Module Name", "version": "1.0.0" } ] } .Example Install-PSModules #> $manifestFileName = "psmodules.json" function ReadManifest() { $manifest = Get-ChildItem $manifestFileName $data = Get-Content $manifest | ConvertFrom-Json $data } function InstallModules($data) { if (!(Test-Path ".\$modulesFolder")) { New-Item -ItemType "directory" ".\$modulesFolder" | out-null } $data.modules | ` Where-Object { -Not (IsInstalled -packageName $_.name -version $_.version) } | ` ForEach-Object { InstallModule -packageName $_.name -version $_.version } } function IsInstalled($packageName, $version) { $availableModule = get-module -ListAvailable -FullyQualifiedName @{ ModuleName = $packageName; RequiredVersion = $version } $availableModule -and @($availableModule).Length -eq 1 } function InstallModule($packageName, $version) { Write-Host "Installing $packageName $version..." Install-Module $packageName -RequiredVersion $version -Scope CurrentUser } function ImportModules($data) { $data.modules | ForEach-Object { ImportModule -packageName $_.name -version $_.version } } function ImportModule($packageName, $version) { # to ensure there are not multiple versions of the same module loaded, # first remove the module (all versions), then import it. $m = get-module $packageName if ($m -and @($m).Length -eq 1) { remove-module $packageName } Import-Module -FullyQualifiedName @{ ModuleName = $packageName; RequiredVersion = $version } -Force } $data = ReadManifest InstallModules $data ImportModules $data |