簡體   English   中英

在C#Runspace中的遠程服務器上導入Powershell模塊

[英]Import a Powershell Module on a Remote Server in a C# Runspace

我需要能夠通過C#運行空間導入駐留在遠程計算機上的模塊。

要清楚我的意思是:我正在創建的服務駐留在服務器A上。它使用下面的方法為服務器B創建一個遠程運行空間。 通過運行空間,我試圖在服務器B上導入一個模塊。

這是我用來進行遠程調用的方法:

internal Collection<PSObject> RunRemoteScript(string remoteScript, string remoteServer, string scriptName, out bool scriptSuccessful)
    {
        bool isLocal = (remoteServer == "localhost" || remoteServer == "127.0.0.1" || remoteServer == Environment.MachineName);

        WSManConnectionInfo connectionInfo = null;

        if (!isLocal)
        {
            connectionInfo = new WSManConnectionInfo(new Uri("http://" + remoteServer + ":5985"));
        }

        PsHostImplementation myHost = new PsHostImplementation(scriptName);

        using (Runspace remoteRunspace = (isLocal ? RunspaceFactory.CreateRunspace(myHost) : RunspaceFactory.CreateRunspace(myHost, connectionInfo)))
        {
            remoteRunspace.Open();
            using (PowerShell powershell = PowerShell.Create())
            {
                powershell.Runspace = remoteRunspace;

                Pipeline pipeline = remoteRunspace.CreatePipeline();

                pipeline.Commands.AddScript(remoteScript);

                Collection<PSObject> results = pipeline.Invoke();

                remoteRunspace.Close();

                scriptSuccessful = myHost.ScriptSuccessful;
                return results;
            }
        }
    }

“remoteScript”設置為我想要運行的Powershell腳本。 例如:

"Import-Module Modulename;CustomCommand-FromModule -parameter(s) -ErrorAction stop"

該模塊沒有打包在一起它是一個psd1,psm1,以及一堆腳本文件,它們位於遠程服務器(服務器B)上的C:\\\\ Powershell \\ ModuleName中,我已經測試並確保它正在調用ModuleName。 ps:1文件位於C:\\\\ Powershell \\ ModuleName目錄中。

在ModuleName.psd1文件中是行:

ModuleToProcess = 'ModuleName.psm1'

但是,如果我嘗試通過c#runspace運行它,我會收到一個非常奇怪的錯誤。

如果我將以下內容作為參數發送到“remoteScript”:

"Import-Module Modulename"

我收到以下錯誤:

System.Management.Automation.RemoteException:未處理模塊清單'C:\\ Powershell \\ ModuleName \\ ModuleName.psd1'的字段'ModuleToProcess'中列出的處理'ModuleName.psm1'的模塊,因為沒有找到任何有效模塊模塊目錄。

該模塊確實存在於“$ env:PSModulePath位置之一中,如果運行則會顯示:

get-module -listAvailable

我還嘗試在psd1文件中輸入ModuleName.psm1文件的完全限定路徑。 當我這樣做(或下面的x0n建議)我得到幾乎完全相同的錯誤:

未處理模塊清單'C:\\ Powershell \\ ModuleName \\ ModuleName.psd1'字段'ModuleToProcess'中列出的'C:\\ Powershell \\ ModuleName \\ ModuleName.psm1'模塊,因為在任何模塊中都找不到有效模塊目錄。

在這一點上,我真的不確定去哪里,即使這實際上是可能的。 我到處搜索,發現了一些似乎相關的東西,但是從來沒有完全相同,往往是我已經克服過的問題,或者根本沒有(據我所知)尚未遇到的問題。 任何幫助,將不勝感激! 謝謝!

我懷疑你需要做兩件事:

  1. 使用.psd1文件的絕對路徑:否則只會考慮在$env:PSModulePath找到的模塊(重要的不在於加載腳本運行的位置)。

  2. 確保您可以加載遠程腳本。 除非簽名,否則默認或RemoteSigned執行策略將阻止遠程腳本。

我發現,如果你的模塊是在一個較新的.net運行時(比如.net 4.0)上構建的,並且你試圖在powershell 2.0(基於.net 3.5)中加載它,這可能是一個問題..解決這個問題,你需要確保在.net 4.0 clr中加載PowerShell或調用進程。

您可以通過在* .exe.config中添加對支持的運行時的enty(如果不存在,則創建powershell.exe.config)來執行此操作。

我測試過它對上述問題很有用。

自從我解決了這個問題以來,我已經有一點點了,所以我為延遲道歉。 事實證明這個解決方案相當簡單,雖然有點奇怪。

為了解決這個問題,在ModuleName.psd1中我注釋掉了:

ModuleToProcess = 'ModuleName.psm1'

我將其添加到NestedModules中:

NestedModules = Join-Path $psscriptroot 'ModuleName.psm1'

坦率地說,我不確定為什么這會讓模塊成功加載,但它對我有用。

我解決了這個問題已經有一段時間了,所以我可能會錯過這里的一小步。 如果這對您不起作用,請告訴我您遇到的問題,然后我可以告訴您這是否是我必須做的其他事情。 我相當肯定這就是全部。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM