ServerManagement.Powershell.psm1
<# .Synopsis Copies the specified module to the remote session .Description Copies the specified module and any dependencies to the remote session. This emulates the installation of a module but without requiring internet access for the remote machine. .Example Copy-PowerShellModuleRemote -Session $Session -ModuleName Compex.ServerManagement .Parameter Session Remote session to copy the module to .Parameter ModuleName Name of the module to copy .Parameter Force Does not prompt for input and auto copys all dependencies #> function Copy-PowerShellModuleRemote { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseUsingScopeModifierInNewRunspaces', '')] # $PSHome is a built in thing [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Session, [Parameter(Mandatory = $true)] [String]$ModuleName, [Parameter(Mandatory = $false)] [switch] $Force ) # Validate local module # Currently only checking installed modules, if needed we could expand to also check all module locations using Get-Module as a fallback if not found $localModule = Get-InstalledModule -Name $ModuleName if($null -eq $localModule){ Throw "The module $ModuleName was not found to be installed on your machine. Please install it first before you try and copy to a remote machine." }else { Write-Output "Found module $($localModule.Name) with version $($localModule.Version)." } # Check for Dependencies... Write-Verbose 'Checking for Dependencies' $dependencies = Get-PowershellModuleDependency -ModuleName $ModuleName foreach ($dependency in $dependencies) { if($Force -or (Read-Host "The module depends on another module called: $($dependency.Name) would you like to install (y/n)?").ToLower() -eq 'y'){ Copy-PowerShellModuleRemote -Session $Session -ModuleName $dependency.Name } } # Get Remote Path Write-Verbose 'Getting remote path for module installation' $remotePath = Invoke-Command -Session $Session -ScriptBlock {"$PSHOME\Modules\"} $leafPath = $localModule.InstalledLocation.Substring($localModule.InstalledLocation.LastIndexOf($ModuleName)) $path = Join-Path -Path $remotePath -ChildPath $leafPath # Create Remote Directory Write-Verbose 'Validating / Creating remote folder structure' if((Invoke-Command -Session $Session -ScriptBlock {Test-Path -Path $using:path}) -eq $false){ Write-Output "Creating remote folder: $path" Invoke-Command -Session $Session -ScriptBlock {New-Item -Path $using:path -ItemType Directory} # Copy to remote machine Write-Output "Copying $ModuleName to remote machine" Copy-Item "$($localModule.InstalledLocation)\*" -Destination $path -Recurse -ToSession $Session }else{ Write-Output "$ModuleName version $($localModule.Version) folder already found on remote machine, skipping copy.." } # Validate remote module Invoke-Command -Session $Session -ScriptBlock {Import-Module "$using:ModuleName"} $remoteModule = Invoke-Command -Session $Session -ScriptBlock {Get-Module "$using:ModuleName"} if($null -eq $remoteModule){ throw "$ModuleName not found after copying..." }else{ Write-Output "Confirmed $ModuleName Installation" } } <# .Synopsis Returns an array of the module dependencies .Description Returns an array of the module dependencies, includes name and version .Example Get-PowershellModuleDependency -ModuleName Compex.ServerManagement .Parameter ModuleName Name of the module to get dependencies for #> function Get-PowershellModuleDependency { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [String]$ModuleName ) # Get Module Write-Verbose "Checking if $ModuleName is installed" $localModule = Get-InstalledModule -Name $ModuleName if($null -eq $localModule){ Throw "The module $ModuleName was not found to be installed on your machine." } Write-Verbose 'Finding manifest file for module' $manifestFile = Get-ChildItem "$($localModule.InstalledLocation)\*.psd1" Write-Verbose 'Loading manifest file' $manifest = Import-PowerShellDataFile $manifestFile.FullName $dependencies = @() foreach ($module in $manifest.RequiredModules) { $dependencies += New-Object PSObject -Property @{ Name = $module['ModuleName'] Version = $module['ModuleVersion'] } } return $dependencies } |