如何托管Powershell脚本或应用程序,以便可以通过WSManConnectionInfo访问它? (如Office 365)

时间:2012-03-27 13:03:43

标签: c# powershell powershell-remoting cmdlets runspace

我知道连接到远程运行空间的唯一方法包括以下参数

   WSManConnectionInfo connectionInfo = 
     new WSManConnectionInfo(false, "localhost", 80, "/Powershell", "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);

   WSManConnectionInfo connectionInfo = 
     new WSManConnectionInfo(false, "localhost", 5985, "/wsman", "http://schemas.microsoft.com/powershell/Microsoft.Powershell", credential);
  • 如何设置我自己的自定义Powershell对象,以便通过HTTP公开它?

  • 使用的正确参数是什么以及如何设置?

1 个答案:

答案 0 :(得分:20)

这有几个部分,所以我将分别解释它们然后将它们组合在一起。

隐式远程

Exchange正在使用Implicit Remoting

它的工作方式是你建立一个远程机器的PSSession,然后将远程实例提供的一些命令导入你自己的命令。

这是使用Import-Module -Session $sessionImport-PSSession完成的。

你可以在Powershell中为自己尝试一下。使用未安装Active Directory RSAT的工作站(没有ActiveDirectory powershell cmdlet),然后连接到执行的计算机(让我们称之为DC1):

$s = New-PSSession -ComputerName DC1
Invoke-Command -Session $s -ScriptBlock { Import-Module ActiveDirectory }
Import-PSSession -Session $s -Module ActiveDirectory

将对Import-PSSession的调用限制为仅一个模块,您只需导入这些cmdlet。此时,您可以执行Get-ADComputer,例如在本地可用,即使实际调用是在DC1上完成的。

会话配置

进行powershell远程连接时,您将连接到会话配置。如果您未指定一个,则连接到名为Microsoft.PowerShell的一个。要查看计算机上定义的所有配置,请致电Get-PSSessionConfiguration。您可能会看到其他一些内容,例如Microsoft.PowerShell32是一种连接到32位PowerShell会话的方法。

要连接到特定配置,请使用New-PSSession -ConfigurationNameNew-PSSession -ConnectionUri

定义会话配置

您可以在会话配置中指定 lot 的内容; powershell的版本,比特,预先导入的模块,您可以预先定义函数和代码,阻止语言功能等等。

This answer provides a good overview of how to create your own configuration

您还可以将配置信息放在程序集中,这对于您尝试执行的操作非常有用。

在模块中包装代码

正如您在Import-PSSession中看到的那样,如果模块中存在代码,则只需导入所需的代码即可。因此,您应确保通过模块公开cmdlet。

您在评论中说过要在C#中编写cmdlet。 这不是我所做的,但本文似乎提供了有关how to create a PowerShell Module in C#的详细说明。

这是我现在所做的事情(这篇文章很好)。在C#中编写cmdlet隐含地已经是一个模块。实际上,您可以使用Import-Module加载已编译的.NET程序集,无论它是否包含任何PowerShell cmdlet。

例如,如果您创建了一个公共类并将其编译为DLL,则可以执行Import-Module MyAssembly.dll,并且该类现在可以在PowerShell会话中使用。

在C#中定义cmdlet意味着包含对System.management.Automation的引用,然后创建一个继承自CmdletPSCmdlet的类。

建议定义模块清单,但在技术上是可选的,就像使用脚本模块一样。

我没有将会话配置信息包含在程序集中(但是?),也没有看到有关如何执行此操作的参考。

将它们聚集在一起

这些步骤应大致相同:

  1. 编译模块并使其在远程端可用,以便可以从该机器上的本地会话导入PowerShell。
  2. 创建一个新的PSSession配置文件,并指定-AssembliesToLoad-ModulesToImport(或两者都必要)或specify the configuration information in the assembly itself(此处可能更喜欢)。
  3. 在机器上注册配置。
  4. 在客户端,您希望将其提供给PowerShell,因此您只需创建会话,然后导入它:
  5.     $s = New-PSSession -ComputerName RemoteMachine -ConfigurationName MyConfig
        # The configuration was defined in such a way 
        # that your module will already be imported in the remote session.
        Import-PSSession -Module MyModule
    

    简化它?

    不必在远程端创建自定义配置。只要您的模块可用于远程计算机上的任何PowerShell会话,您就可以跳过会话配置步骤,然后您就可以执行以下操作:

    $s = New-PSSession -ComputerName RemoteMachine
    Invoke-Command -Session $s -ScriptBlock { Import-Module MyModule }
    Import-PSSession -Session $s -Module MyModule
    

    但是您可能希望使用会话配置进行额外的自定义和控制,这取决于您。这就是交换的方式,但对你的目的而言可能有些过分。