如何在远程 Powershell 会话中使用共享函数?

Dyl*_*tie 3 remote-access powershell remoting

我有一些用于设置 IIS Web 应用程序、消息队列等的 Powershell 脚本。

他们使用我们创建的一组共享函数库 - 所以每个脚本都以行开头

. .\common.ps1

引用共享库。共享库包含一组函数,例如Create-IisApplicationPoolCreate-MessageQueue等等,然后从实际脚本中调用这些函数。这些脚本的问题在于您需要通过远程桌面登录并在本地运行它们,因此我正在编写一些新脚本来将代码部署到 Amazon EC2 实例,并使用 Powershell 远程处理在本地调用它们。

我无法解决的是如何使这个共享库在远程 Powershell 会话中可用。

这是一个简单的例子:

函数.ps1

function Add-Title([string] $name) {
    "Mr. $name"
}

function Say-HelloWorld([string] $name = "World") {
    $computerName = $env:COMPUTERNAME
    $greeting = Add-Title($name)
    Write-Host "Hello, $greeting ($computerName)"
}
Run Code Online (Sandbox Code Playgroud)

例子.ps1

. ./functions.ps1


$remoteUsername = "username"
$remotePassword = "password"
$remoteHostname = "172.16.0.100"

$securePassword = ConvertTo-SecureString -AsPlainText -Force $remotePassword
$cred = New-Object System.Management.Automation.PSCredential $remoteUsername, $securePassword


Say-HelloWorld("Spolsky")
Run Code Online (Sandbox Code Playgroud)

在本地运行,这很好用 - 并按预期说“你好,斯波尔斯基先生(DYLAN_PC)”。

现在,如果我Say-HelloWorld用这个远程脚本调用替换调用:

Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock {
    Say-HelloWorld("Spolsky")
}
Run Code Online (Sandbox Code Playgroud)

我收到 Powershell 错误:

The term 'Say-HelloWorld' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is co
rrect and try again.
    + CategoryInfo          : ObjectNotFound: (Say-HelloWorld:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
Run Code Online (Sandbox Code Playgroud)

显然,远程会话无法看到本地导入的函数。

对于简单的函数,此语法有效:

Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock ${function:Add-Title } -argumentlist "Spolsky"
Run Code Online (Sandbox Code Playgroud)

但这对于依赖于其他功能的任何功能都失败了。

我使用 PS-ExportSession 尝试了各种方法,并尝试将-Session参数传递给 Invoke-Command,但找不到任何方法可以在可以导入远程会话的模块中捕获本地函数及其依赖项。任何帮助表示感谢!

Mat*_*ore 5

这是一个有点老的话题,但所有的答案都比这更绕。

Import-Module .\Common.ps1 -Force
# Now you can call common functions locally

$commonFunctions = (Get-Command .\Common.ps1).ScriptContents
Invoke-Command -Session $session -ArgumentList $commonFunctions -ScriptBlock {
    param($commonFunctions)
    Invoke-Expression $commonFunctions

    # Now you can call common functions on the remote computer
}
Run Code Online (Sandbox Code Playgroud)