本文内容最后更新于 2020-06-11 14:35。本文仅为纪念之用,内容仅供参考,不保证其时效性和准确性。
在 Linux 系统中,SSH 是实现远程任务管理的强大工具,而在 Windows 系统中,PowerShell 则提供了类似的远程操作能力。本文将引导您了解如何利用 PowerShell 执行远程操作。
基本概念
微软制定了一项名为 WS-Management 的标准协议,旨在为计算设备间的远程管理数据交换提供一个开放的规范。对于 Windows 系统而言,微软通过 Windows 远程管理(Windows Remote Management,WinRM)服务实现了这一协议。这构成了利用 PowerShell 进行远程操作的技术基石,因为 PowerShell 正是借助 WinRM 服务来达成远程控制的目的。
查看 WinRM 服务状态
要检查 WinRM 服务是否正在运行,可以执行以下命令:
Get-Service WinRM
请注意,在 Windows 服务器版本中,WinRM 服务通常是默认启用的;然而,在常规的 Windows 版本中,这项服务可能需要手动开启。接下来的部分将指导您正确地启动 WinRM 服务。
配置系统以接收远程指令
与 SSH 的客户端/服务器模型相仿,只需在接收远程指令的目标机器上配置 WinRM 服务即可。实质上,就是要让 WinRM 服务监听特定的端口,其工作原理与 SSH 守护进程相似。
以管理员身份启动 PowerShell,并运行以下命令:
Enable-PSRemoting –Force
Enable-PSRemoting
命令的作用不仅仅是激活 WinRM 服务,它还会自动配置必要的防火墙规则。
如果您的计算机已加入域,上述配置步骤就足够了。但对于未加入域的计算机,则还需额外设置信任主机,并重新启动 WinRM 服务:
Set-Item wsman:\localhost\client\trustedhosts *
Restart-Service WinRM
测试远程连接
PowerShell 提供了一个专门的命令,用于检测目标主机是否已准备好接收远程操作:
Test-WsMan xxx.xxx.xxx.xxx
若此命令能顺利返回结果,表明远程主机上的服务已正确配置,支持远程访问。反之,如果收到错误信息,则意味着远程主机尚未启用远程访问功能。
建立远程会话
这一过程与 SSH 的工作模式颇为相似——通过 SSH 客户端创建一个至服务器的会话 (session),进而执行各类操作。这是 SSH 的基础应用之一,而 PowerShell 同样支持这种场景,允许用户以相同的方式操作远程主机。
Enter-PSSession -ComputerName lz-2019 -Credential passw0rd
在提示时输入密码,即可完成会话的建立。自此,您便可以在远程主机上执行所需的任务了!
远程执行单一命令
在与远程主机建立会话后,执行任务变得更为便捷。然而,很多时候我们的需求仅仅是执行一个单独的命令,甚至是在脚本中调用这样的命令。这时,可以使用 Invoke-Command
命令,结合 -ScriptBlock
参数来实现这一目标:
Invoke-Command -ComputerName lz-2019 -ScriptBlock { Get-Service WinRM } -Credential passw0rd
执行上述命令时,需要提供用户的密码。
尽管如此,这种方法存在明显的局限性:由于需要手动输入密码,因此难以将其集成到自动化脚本中。为解决这一问题,可以采用以下方式将密码嵌入命令中,以便于自动化执行:
$Username = 'xxxx'
$Password = 'yyyy'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Invoke-Command -ComputerName lz-2019 -ScriptBlock { Get-Service WinRM } -Credential $Cred
远程执行多条命令
当需要依次执行多个相关联的命令时,例如后续命令依赖于前序命令的结果,直接使用 Invoke-Command
可能无法满足需求。这时,应当通过创建一个会话来保持命令间的关系:
Invoke-Command -ComputerName lz-2019 -ScriptBlock {$p = Get-Process PowerShell}
Invoke-Command -ComputerName lz-2019 -ScriptBlock {$p.VirtualMemorySize}
$s = New-PSSession -ComputerName lz-2019
Invoke-Command -Session $s -ScriptBlock {$p = Get-Process PowerShell}
Invoke-Command -Session $s -ScriptBlock {$p.VirtualMemorySize}
上述示例中,直接执行的前两条命令由于缺少上下文,导致第二个命令中的 $p
为空,从而无法获取预期结果。而最后两行命令通过同一个会话执行,确保了变量 $p
在不同命令间得以共享,进而成功返回结果。
远程执行脚本文件
掌握了远程执行单个命令的技巧之后,远程执行脚本就显得更加直观了。实际上,这正是自动化流程的核心组成部分:
Invoke-Command -ComputerName cm-12r2 -FilePath .\task.ps1
远程文件传输
自 PowerShell 5.x 版本起,开始支持远程文件传输功能。下面是一个简单的示例,展示如何将本地文件复制到远程主机:
$mySession = New-PSSession -ComputerName xxxxxx
Copy-Item -Path .\task.ps1 -Destination C:\task.ps1 -ToSession $mySession
该命令将本地当前目录下的 task.ps1
文件复制到了远程主机 xxxxxx
的 C 盘根目录下。Copy-Item
命令通过 ToSession
参数指定了目标会话,表明了文件传输的方向是从本地到远程。
对于整个目录的复制,需要添加 Recurse
参数:
$mySession = New-PSSession -ComputerName xxxxxx
Copy-Item -Path .\PowerShell -Destination C:\PowerShell -ToSession $mySession -Recurse
当需要从远程主机向本地传输文件或文件夹时,可以使用 FromSession
参数:
$mySession = New-PSSession -ComputerName xxxxxx
Copy-Item -Path C:\task.ps1 -Destination F:\temp\task.ps1 -FromSession $mySession
Copy-Item -Path C:\PowerShell -Destination F:\temp -FromSession $mySession -Recurse
这里使用 FromSession
参数,因此 Destination
指定的是本地路径。执行这些命令后,文件或文件夹将被复制到本地的 F:\temp
目录下。
结论
本文简要介绍了使用 PowerShell 实施远程操作的基础知识及一些常见的应用场景。整体而言,这些操作与 SSH 类似,而远程文件传输功能则是 PowerShell 较新版本中引入的特性。在实际应用时,请确保环境中的 PowerShell 版本支持所需的功能。
以上便是本文的所有内容,希望能够帮助到您的学习,同时也欢迎您给予更多关注和支持。
本文参考:PowerShell 远程执行任务