如何托管 Powershell 脚本或应用程序以便可以通过 WSManConnectionInfo 访问它? (如 Office 365)
Posted
技术标签:
【中文标题】如何托管 Powershell 脚本或应用程序以便可以通过 WSManConnectionInfo 访问它? (如 Office 365)【英文标题】:How do I host a Powershell script or app so it's accessible via WSManConnectionInfo? (like Office 365) 【发布时间】:2012-04-11 00:24:47 【问题描述】:我知道连接到远程运行空间的唯一方法包括以下参数
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 公开它?
正确使用哪些参数以及如何设置它们?
【问题讨论】:
任何带有完整源代码的最终解决方案?? 请说明您要完成的工作 我想创建一个基于 C# 的命令行开关,并通过 HTTP 发布它。然后 Powershell 将使用 import 命令获取命令并远程执行代码,就像远程 shell 一样。 @JonTirjan PowerShell cmdlet 不通过 http 发布。您在上面引用的 url 只是架构定义,而不是代码本身。 @LamonteCristo,你有什么问题吗? 【参考方案1】:这有几个部分,所以我将分别解释它们,然后将它们放在一起。
隐式远程处理
Exchange 正在使用Implicit Remoting。
它的工作方式是您建立一个到远程机器的 PSSession,然后将远程实例中可用的一些命令导入到您自己的实例中。
这是使用Import-Module -Session $session
或Import-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 -ConfigurationName
或New-PSSession -ConnectionUri
。
定义会话配置
您可以在会话配置中指定很多的东西; 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
的引用,然后创建一个继承自 Cmdlet
或 PSCmdlet
的类。
建议定义模块清单,但在技术上是可选的,就像使用脚本模块一样。
但是,我还没有在程序集中包含会话配置信息(还没有?),也没有看到有关如何执行此操作的参考。
把它放在一起
步骤大致如下:
-
编译模块并使其在远程端可用,以便可以从该计算机上的本地会话将其导入到 powershell。
创建一个新的 PSSession 配置文件,并指定
-AssembliesToLoad
或 -ModulesToImport
(或两者如果需要),或 specify the configuration information in the assembly itself(这里可能首选)。
在机器上注册配置。
在客户端,您希望将其提供给 PowerShell,因此您只需创建会话,然后将其导入:
$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
但是您可能希望通过使用会话配置来获得额外的自定义和控制,这取决于您。这就是交换的方式,但对于您的目的而言,这可能是多余的。
【讨论】:
以上是关于如何托管 Powershell 脚本或应用程序以便可以通过 WSManConnectionInfo 访问它? (如 Office 365)的主要内容,如果未能解决你的问题,请参考以下文章
“创建管道时出错。”在 Azure 管道自托管代理中运行 powershell 脚本时
无法在 IIS 托管的 .net web api 项目中运行 powershell 脚本