Comment puis-je utiliser des fonctions partagées dans une session Powershell à distance?

J'ai des scripts Powershell pour configurer des applications Web IIS, des files d'attente de messages, etc.

Ils utilisent un set de bibliothèques de fonctions partagées que nous avons créées – donc chaque script commence par la ligne

. .\common.ps1

pour referencer la bibliothèque partagée. La bibliothèque partagée contient un set de fonctions telles que Create-IisApplicationPool , Create-MessageQueue et similaires, qui sont ensuite appelés à partir du script réel. Le problème avec ces scripts est que vous devez vous connecter via le Bureau à distance et les exécuter localement, alors j'écris de nouveaux scripts pour déployer un code dans une instance de l'Amazon EC2 et en utilisant le Powershell remoting pour les appeler localement.

Ce que je ne peux pas résoudre, c'est la façon de rendre cette bibliothèque partagée disponible dans une session Powershell à distance.

Voici un exemple simple:

functions.ps1

 function Add-Title([ssortingng] $name) { "Mr. $name" } function Say-HelloWorld([ssortingng] $name = "World") { $computerName = $env:COMPUTERNAME $greeting = Add-Title($name) Write-Host "Hello, $greeting ($computerName)" } 

exemple.ps1

 . ./functions.ps1 $remoteUsername = "username" $remotePassword = "password" $remoteHostname = "172.16.0.100" $securePassword = ConvertTo-SecureSsortingng -AsPlainText -Force $remotePassword $cred = New-Object System.Management.Automation.PSCredential $remoteUsername, $securePassword Say-HelloWorld("Spolsky") 

Exécuter localement, cela fonctionne très bien – et dit "Bonjour, M. Spolsky (DYLAN_PC)" comme prévu.

Maintenant, si je remplace l'appel Say-HelloWorld par cette invocation de script à distance:

 Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock { Say-HelloWorld("Spolsky") } 

Je reçois l'erreur 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:Ssortingng) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

De toute évidence, la session à distance ne peut pas voir les fonctions qui ont été imscopes localement.

Pour des fonctions simples, cette syntaxe fonctionne:

 Invoke-Command -computerName $remoteHostname -Credential $cred -ScriptBlock ${function:Add-Title } -argumentlist "Spolsky" 

mais cela échoue pour toute fonction qui dépend d'autres fonctions.

J'ai essayé diverses choses en utilisant PS-ExportSession et j'ai essayé de passer un argument -Session à Invoke-Command, mais je ne peux find aucun moyen de capturer les fonctions locales et leurs dependencies dans un module pouvant être importé dans une session distante. Toute aide reçue avec reconnaissance!

4 Solutions collect form web for “Comment puis-je utiliser des fonctions partagées dans une session Powershell à distance?”

C'est un peu un sujet ancien, mais toutes les réponses sont plus rondes que cela.

 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 } 

Vous dites que chaque script commence . .\common.ps1 . .\common.ps1 , mais je ne le vois pas dans votre script d'exemple. Quoi qu'il en soit, si vous devez utiliser les fonctions en commun.ps1, vous devez l'insert quelque part sur lequel la machine distante peut accéder.

Vous pouvez utiliser les lecteurs redirigés dans Powershell comme vous l'auriez dans une session RDP:

 New-PSSession SERVER1 -Cred $creds | Enter-PSSession . \\tsclient\c\common.ps1 

Ou vous pouvez mettre common.ps1 sur un partage réseau:

 . \\Server1\share\common.ps1 

Ou vous pouvez simplement coller le contenu sur common.ps1 dans chaque script.

Ou vous pouvez mettre common.ps1 sur le système de files local de la machine distante.

Lorsque l'parsingur Powershell sur l'ordinateur distant voit "… \ common.ps1", il tente de charger common.ps1 à partir du directory de travail actuel, qui est probablement le directory personnel de n'importe quel user ayant établi la session PS distante.

Je m'attendais à ce que vous ayez besoin de copyr les fonctions.ps1 avant de l'extraire. En fait, je copyrais probablement les deux scripts sur le même directory (par exemple, via le partage C $ admin dans \\server\C$\foo ), puis appeler à distance C:\foo\example.ps1 utilisant Invoke-Command .

J'ai eu exactement le même problème. Je suppose qu'il s'agit d'invocations à distance s'exécutant dans le context de l'appelant distant. J'ai réussi à contourner le problème en fournissant un path d'access local complet à la bibliothèque cible en tant que variable, puis en partageant la bibliothèque via la variable:

 function Get-ScriptDirectory { return Split-Path $script:MyInvocation.MyCommand.Path } function GetLocalFileName { param([ssortingng]$filename) return [system.io.path]::Combine((Get-ScriptDirectory),$filename) } # dot-source the library using full local name to get round problem with remote invocation $MYLIBRARY = GetLocalFileName "mylibrary.ps1" . $MYLIBRARY 
Les astuces du serveur de linux et windows, tels que ubuntu, centos, apache, nginx, debian et des sujets de réseau.