PowerShell远程处理的原理(了解WinRM)

WinRM的主要特性

与Telnet和Shell(SSH)不一样的是,PowerShell采用一种新的通信协议,我们称之为针对管理的Web服务(Web Services for Management,WS-MAN)。
WS-MAN完全基于HTTP或者HTTPS进行工作,这样保证在需要的情况下,能轻易透过防火墙进行作业(因为每种协议都使用唯一的端口进行通信)。微软对WS-MAN的实现主要基于一个后台服务:Windows远程管理组件(WinRM)。
微软宣布远程处理技术除了WS-MAN之外,还可以基于SSH协议。这对那些已经熟悉SSH而不熟悉WS-MAN与WinRM的公司来说是一个好消息。从用户角度讲,如何使用远程处理技术并无区别,底层协议的区别对你来说应该是透明的。
实际上,微软很多自己的DevOPS产品也使用了WinRM技术,例如:

Deploy to IIS using WinRM - Azure Pipelines | Microsoft Docs https://docs.microsoft.com/zh-cn/azure/devops/pipelines/apps/cd/deploy-webdeploy-iis-winrm?view=azure-devops

序列化与反序列化

当你运行一个远程命令时,它会将输出结果放入一个特定形式的包中,之后通过网络中的HTTP(或者HTTPS)协议传回本地计算机。XML已经被证明是针对该问题的优秀解决方案,所以PowerShell会将输出对象序列化到XML中。下一步,XML文件会通过网络进行传输。当到达本地计算机之后,该XML会反序列化为PowerShell可以处理的对象。序列化和反序列化仅仅是一种格式转换的形式:从对象转化为XML称为序列化,从XML转为对象则为反序列化。

WinRM是一个通用的服务

并非只有PowerShell能使用WinRM服务。实际上,微软在越来越多的管理程序中开始使用WinRM服务——甚至包含已经使用了其他协议的那些程序。基于这一思想,微软保证WinRM可以将流量导入至多种管理程序——不仅仅是PowerShell。WinRM类似一个调度器:当有新的流量进来后,WinRM会决定由哪种程序来处理这部分流量。所有WinRM流量都标记了接收应用程序的名称,同时这些应用程序都必须在WinRM中创建各自的端点,这样WinRM才能侦听这些主体的流量。这也就意味着,你们不只需要启用WinRM服务,也需要在WinRM中将PowerShell注册为一个端点。

一对一和一对多的远程处理

PowerShell可以通过两种方法实现远程处理,第一种称为一对一或者1:1远程处理(第二种称为一对多,或者1:n远程处理。当使用一对一远程处理时,实际上是在单台远程计算机上调用了一个Shell命令窗口。输入的任何命令都会直接在该计算机上运行,然后在远程处理窗口中返回输出结果。该机制非常类似于远程桌面连接(Remote Desktop Connection),只是Windows PowerShell采用的是命令行环境。相对于远程桌面连接,这种远程处理技术只需要使用很少的资源,所以对服务器来讲,开销会小很多。

如果需要针对一台远程计算机建立一对一的远程处理进程,请运行下面的命令。

Enter-PSSession -ComputerName Server-R2
默认情况下,PowerShell最多一次与32台远程计算机通信。如果超过32台,那么会将计算机信息存放到一个队列中。如果命令在一台远程计算机上运行完毕,队列中的下一台计算机会立即开始运行。当然,如果网络足够良好,并且计算机足够强劲,那么我们可以通过Invoke-Command的-ThrottleLimit参数来指定更多数量的计算机。

Invoke-Command | Microsoft Docs
https://docs.microsoft.com/en-us/previous-versions/dd347578(v=technet.10)?redirectedfrom=MSDN

并发执行

使用Invoke-Command命令比Cmdlet的-ComputerName参数更有效率,更有用。计算机会被并发地访问,也就意味着,命令运行更有效率。命令的输出结果中包含PSComputerName属性,也就使得我们能轻易看到哪个结果来自于哪台计算机。

备注:部分内容参考了《Windows PowerShell实战指南(第3版)》,经过作者二次整理和补充,更加方便大家理解。

主流编程语言及工具对WinRM的支持情况

GitHub - diyan/pywinrm: Python library for Windows Remote Management (WinRM) https://github.com/diyan/pywinrm
GitHub - WinRb/WinRM: Ruby library for Windows Remote Management https://github.com/WinRb/WinRM
GitHub - masterzen/winrm: Command-line tool and library for Windows remote command execution in Go https://github.com/masterzen/winrm
winrm – Run tasks over Microsoft’s WinRM — Ansible Documentation https://docs.ansible.com/ansible/devel/plugins/connection/winrm.html

更多内容,您也可以参考
PowerShell远程处理的原理(了解WinRM)

猜你喜欢

转载自blog.51cto.com/543925535/2438390