Eu tenho alguns scripts do Powershell para configurar aplicativos web do IIS, filas de mensagens, etc.
Eles usam um conjunto de bibliotecas de funções compartilhadas que criamos - então cada script começa com a linha
. .\common.ps1
para referenciar a biblioteca compartilhada. A biblioteca compartilhada contém um conjunto de funções como Create-IisApplicationPool
, Create-MessageQueue
e similares, que são então chamadas a partir do script real. O problema com esses scripts é que você precisa fazer logon via Remote Desktop e executá-los localmente, portanto, estou escrevendo alguns novos scripts para implantar código em uma instância do Amazon EC2 e usando a comunicação remota do Powershell para invocá-los localmente.
O que não consigo descobrir é como disponibilizar essa biblioteca compartilhada em uma sessão remota do Powershell.
Aqui está um exemplo simples:
functions.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)"
}
example.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")
Rodando localmente, isso funciona muito bem - e diz "Olá, Sr. Spolsky (DYLAN_PC)" como esperado.
Agora, se eu substituir a chamada Say-HelloWorld
por essa chamada de script remoto:
Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock {
Say-HelloWorld("Spolsky")
}
Eu recebo o erro do 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
Claramente, a sessão remota não pode ver as funções que foram importadas localmente.
Para funções simples, esta sintaxe funciona:
Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock ${function:Add-Title } -argumentlist "Spolsky"
mas isto falha para qualquer função que dependa de outras funções.
Eu tentei várias coisas usando PS-ExportSession e tentando passar um argumento -Session
para Invoke-Command, mas não consigo encontrar nenhuma maneira de capturar funções locais e suas dependências em um módulo que pode ser importado para um sessão remota. Qualquer ajuda recebida com gratidão!