从 PS 5.0 开始,我认为现在有另一种更清洁的方式:
利用 Copy-Item 的 ToSession 参数将本地模块复制到远程机器。
这不涉及以前解决方案的缺点:
- 无需事先将模块复制到远程机器
- 没有共享文件夹或动态重新创建模块:
示例用法:
$s = New-PSSession MyTargetMachine
Get-Module MyLocalModule | Import-LocalModuleToRemoteSession -Session $s -Force
# Show module is loaded
Invoke-Command $s -ScriptBlock { Get-Module }
Import-LocalModuleToRemoteSession 函数
请注意,它不会加载模块依赖项
<#
.SYNOPSIS
Imports a loaded local module into a remote session
.DESCRIPTION
This script copies a module's files loaded on the local machine to a remote session's temporary folder and imports it, before removing the temporary files.
It does not require any shared folders to be exposed as it uses the default Copy-To -ToSession paramter (added in PS 5.0).
#>
function Import-LocalModuleToRemoteSession
{
[CmdletBinding()]
param(
# Module to import
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName,Mandatory)]
[System.Management.Automation.PSModuleInfo]$ModuleInfo,
# PSSession to import module to
[Parameter(Mandatory)]
[System.Management.Automation.Runspaces.PSSession]
$Session,
# Override temporary folder location for module to be copied to on remote machine
[string]
$SessionModuleFolder=$null,
[switch]
$Force,
[switch]
$SkipDeleteModuleAfterImport
)
begin{
function New-TemporaryDirectory {
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
New-Item -ItemType Directory -Path (Join-Path $parent $name)
}
}
process{
if( [string]::IsNullOrWhiteSpace($SessionModuleFolder) ){
Write-Verbose "Creating temporary module folder"
$item = Invoke-Command -Session $Session -ScriptBlock ${function:New-TemporaryDirectory} -ErrorAction Stop
$SessionModuleFolder = $item.FullName
Write-Verbose "Created temporary folder $SessionModuleFolder"
}
$directory = (Join-Path -Path $SessionModuleFolder -ChildPath $ModuleInfo.Name)
Write-Verbose "Copying module $($ModuleInfo.Name) to remote folder: $directory"
Copy-Item `
-ToSession $Session `
-Recurse `
-Path $ModuleInfo.ModuleBase `
-Destination $directory
Write-Verbose "Importing module on remote session @ $directory "
try{
Invoke-Command -Session $Session -ErrorAction Stop -ScriptBlock `
{
Get-ChildItem (Join-Path -Path ${Using:directory} -ChildPath "*.psd1") `
| ForEach-Object{
Write-Debug "Importing module $_"
Import-Module -Name $_ #-Force:${Using:Force}
}
if( -not ${Using:SkipDeleteModuleAfterImport} ){
Write-Debug "Deleting temporary module files: $(${Using:directory})"
Remove-Item -Force -Recurse ${Using:directory}
}
}
}
catch
{
Write-Error "Failed to import module on $Session with error: $_"
}
}
}