文章目录
- 介绍
- 远程处理:一对一及一对多
-
- PowerShell远程处理的原理
- WinRM概述
- 一对一场景的Enter-PSSession和Exit-PSSession
- 一对多场景的Invoke-Command
- 远程命令和本地命令直接的差异
-
- Invoke-Command和-ComputerName对比
- 本地处理和远程处理对比
- 反序列化对象
- 轻松实现远程控制
-
- 介绍
- 利用Enter-PSSession命令使用会话
- 利用Invoke-Command命令使用会话
- 隐式远程控制:导入一个会话
- 使用断开会话
- 高级远程控制配置
-
- 使用其他端点
- 创建自定义端点
- 深入远程控制身份验证
- 总结
介绍
远程处理:一对一及一对多
PowerShell远程处理的原理
在一定程度上,
WinRM概述
在使用远程处理之前,我们必须配置该
Enable-PSRemoting命令只有在网络状态为“工作网络”或“家庭网络”时才可以,否则会报错
winRM Set WinRM/Config/Listener?Address=*+Transport=HTTP @{PORT="1234"}
一对一场景的Enter-PSSession和Exit-PSSession
当使用一对一远程处理时,实际上是在单台远程计算机上调用了一个
Enter-PSSession -ComputerName Server-R2
你需要使用正确的计算机名称来替代
Server-R2
如果执行成功,则显示如下。
[Server-R2] PS C:>
退出一对一的远程需要使用
一对多场景的Invoke-Command
下面讲的是
Invoke-Command -ComputerName S12,S13,S14 -Command { Get-EventLog Security -Newest 200 | Where { $_.EventID -eq 1212 }}
简单说明如下。
- S12,S13,S14需要使用真正的计算机名称。如果网络良好,计算机足够强劲,也可使用
-ThrottleLimit 参数来指定更多数量的计算机 - -Command在帮助中是找不到的,实际上它是
-ScriptBlock 参数的别名或者昵称
针对多个计算机每次执行远程命令都需要写一遍,我们可以将其放入要给文本文件中,并通过下面的命令进行调用。
Invoke-Command -Command {dir} -ComputerName (Get-Content ct.txt)
而如果需要将本地的变量传递到远程使用,可以考虑使用ArgumentList参数或者$using语句进行传递,直接赋值是无法传递到远程的。
$serverFilePath = 'C:File.txt' # 此命令无法传递本地变量 Invoke-Command -ComputerName (Get-Content ct.txt) -Command { Write-Host "The value of foo is $serverFilePath"} # 使用ArgumentList参数 Invoke-Command -ComputerName (Get-Content ct.txt) -Command { Write-Host "The value of foo is $($args[0])} -ArgumentList $serverFilePath" # 使用using语句 Invoke-Command -ComputerName (Get-Content ct.txt) -Command { Write-Host "The value of foo is $using:serverFilePath"}
远程命令和本地命令直接的差异
使用以下命令来进行说明。
Invoke-Command -ComputerName S12,S13,S14 -Command { Get-EventLog Security -Newest 200 | Where { $_.EventID -eq 1212 }}
Invoke-Command和-ComputerName对比
下面是实现相同目的的另一种写法。
Get-EventLog Security -Newest 200 -ComputerName S12,S13,S14 | Where { $_.EventID -eq 1212 }
该命令的运行方式上存在很大的不同。
- 提及的计算机会按顺序被串行访问,而不会采用并行方式,也就意味着命令执行时间更长
- 该命令输出的结果中不会包含
PSComputerName 属性,也就意味着我们很难判别某个结果是从哪台计算机得来的 - 该连接并不会使用
WinRM 实现,而使用.Net Framework 决定的底层协议 - 我们会从
3 台计算机上返回200 条记录,然后在根据EventID 过滤。这意味着返回很多我们不需要的结果 - 我们得到的是功能全面的事件对象
如果我们使用之前的
- 计算机会被并行访问,即效率更高
- 命令的结果包含
PSComputerName 属性,即我们知道哪个结果来自哪台计算机 - 通过
WinRM 来创建连接,会使用一个预定义的端口,使得命令更轻易地穿过任何防火墙 - 每天计算机都会查
200 条记录并本地筛选,传回的结果都是我们想要的 - 传递结果前,每天计算机都会将输出结果序列化为
XML 。本地收到XML 后在反序列化为一些类似的对象结果。
本地处理和远程处理对比
再次引用之前的例子。
Invoke-Command -ComputerName S12,S13,S14 -Command { Get-EventLog Security -Newest 200 | Where { $_.EventID -eq 1212 }}
然后和下面的例子对比一下,唯一的不同是移动了最后的大括号位置。
Invoke-Command -ComputerName S12,S13,S14 -Command { Get-EventLog Security -Newest 200 } | Where { $_.EventID -eq 1212 }
在第二个命令中,只有
反序列化对象
远程处理的另一个需要注意的的事项是返回来本地计算机的对象可能缺失部分功能。可以通过下面的命令进行对比。
Get-Service | Get-Member Invoke-Command -ScriptBlock { Get-Service } -ComputerName S1 | Get-Member
从上面命令结果中可以看到,除了每个对象都拥有的普通
轻松实现远程控制
介绍
会话是一个在你的
你可以通过
New-PSSession -ComputerName Serverr2,server17,dc5 Get-PSSession # 获取会话
我们更倾向于把会话放到一个变量中。
$sessions = New-PSSession -ComputerName Server-R2,server17,dc5 -Credential WebAdmin
请永远不要忘记这些会话会消耗资源。建议不用的时候手动关闭,可以使用
$sessions | Remove-PSSession Get-PSSession | Remove-PSSession #关闭所有处于开启状态的会话
请记住,我们已经在这些计算机上启用了远程控制,并且这些计算机处于同一个域
利用Enter-PSSession命令使用会话
Enter-PSSession -Session $sessions[0]
执行上面的命令,可以看到命令提示符已经改变,表示我们已经在控制远程计算机,
或许你很难通过索引号记起是哪个计算机,这种情况可以考虑使用属性来进行区分。例如,将
具体可以参考下面的示例来查看怎么使用。
Enter-PSSession -Session ($sessions | Where-Object { $_.ComputerName -EQ 'Server-R2' }) Enter-PSSession -Session (Get-PSSession -ComputerName Server-R2) Get-PSSession -ComputerName Server-R2 | Enter-PSSession
通过
利用Invoke-Command命令使用会话
Invoke-Command -Command { Get-WmiObject -Class Win32_Process } -Session $sessions
注意,我们将一个
- 远程控制通过一个预定义的端口进行传输,
WMI 却不是。远程控制因此针对在防火墙后的计算机更加容易使用,这是由于更容易开启必要的防火墙例外 - 将所有的进程传输到本地费时费力。使用
Invoke-Command 命令,可以让每台计算机完成各自的工作,并返回结果 - 远程控制并行执行,默认可以连接最多
32 台计算机。WMI 顺序执行,一次只能一台计算机执行 - 我们无法通过
Get-WmiObject 使用我们预定义的会话对象,但可以通过Invoke-Command 使用
Invoke-Command -Command { Get-WmiObject -Class Win32_Process } -Session (Get-PSSession -ComputerName Ioc*)
隐式远程控制:导入一个会话
隐式远程控制是对我们来说最酷、最有用的功能之一——可能是在任何操作系统的命令行界面中迄今为止最酷、最有用的功能。但是不幸的是,该功能并未记入
比如,有些功能只在某些系统上安装了,由于各种各样的原因,你无法将这些模块安装到本地计算机上。这时候如果想使用,就可以使用隐式远程控制。
让我们通过一个例子来说明。
# 建立连接 $session = New-PSSession -ComputerName Server-r2 # 载入远程控制模块 Invoke-Command -Command { Import-Module ActiveDirectory } -Session $session # 导入远程控制命令 Import-PSSession -Session $session -Module ActiveDirectory -Prefix rem # 查看临时本地模块 ModuleType Name ExportedCommands ---------- ---- ---------------- Script tmp_2b92353dc-23523-34s42... {Set-ADOrganizationalUnit,Get-ADD...
下面是本例的解释。
- 首先,通过与一台装有活动目录模块的远程计算机建立一个会话。我们需要该计算机上装有
PowerShell V2 或更新的版本,同时启用了远程控制 - 我们告诉远程计算机导入其本地的活动目录模块。由于会话处于打开状态,该模块将一直在远程计算机上处于被载入状态
- 我们接下来告诉我们的计算机从远程会话中导入命令。我们只需要活动目录模块中的命令,并在每个命令的名词部分加入“
rem ”前缀。这样更容易区分远程命令,也防止与本地命令发生冲突 PowerShell 在本地计算机创建一个临时模块,用于代表远程命令。这些命令并不是被复制过来;Powershell 为其创建了指向远程计算机的快捷方式
当我们运行这些命令时,它们并不是在我们本地的计算机上执行,而是隐式的在远程计算机上执行,之后将结果发送给本地计算机。所以这个结果不会包含对象的方法。
使用断开会话
首先,会话不在脆弱,意思是网络闪断或其他传输中断的情况下,会话不会断开。即使没有显示使用会话对象时,你也可以用到这项提升。因此,你获得了更稳定的的连接。
在第
但最酷的地方在于,我们可以登录另一台计算机,也就是
在
在
- -IdleTimeout指定当远程
Shell 中没有用户活动时,远程Shell 将保持打开状态的最长时间。在指定时间过后,远程Shell 将被自动删除。默认值是2000 小时,或84 天 - -MaxConcurrentUsers指定可以在同一计算机上通过远程
Shell 同时执行远程操作的最大用户数 - -MaxShellRunTime指定会话可以打开的最初时间。默认值无限。请记住,
IdleTimeout 参数可以覆盖此参数 - -MaxShellsPerUser指定任何用户可以在同一系统上远程打开的并发
Shell 的最大数目。该值与MaxConcurrentUsers 相乘,可以得到计算机上所有用户做大会话数据量的值
在
- -MaxConnections设置连接到整个远程控制架构下的连接数上限。即使你设置了每个用户可以运行的
Shell 数量或上限值的用户,该参数也会限制传入连接
高级远程控制配置
使用其他端点
在
你可能注意到,我们的
Enter-PSSession -ComputerName Server-R2 -ConfigurationName 'microsoft.powershell32'
创建自定义端点
创建自定义端点可用分为以下两步。
1、通过
2、通过
我们可以创建一个只有域中
New-PSSessionConfigurationFile -Path C:HelpDeskEndpoint.pssc -ModulesToImport NetAdapter -SessionType RestrictedRemoteServer -CompanyName "Our Company" -Author "Don Jones" -Description "Net adapter commands for use by help desk" -PowerShellVersion '5.1'
参数的简单说明。
- -Path参数是必须的,并且你提供的文件名称必须以
.PSSC 结尾 - -ModulesToImoport列出组件(
NetAdapter ),我们只希望对本端点只有该组件可用 - -SessionType RestrictedRemoteServer除了一些必要的命令,移除所有
PowerShell 核心命令。该列表会很小,仅包含Select-Object 、Measure-Object 、Get-Command 、Get-Help 、Exit-PSSession 等 - -PowerShellVersion默认是
5.1
创建完会话配置文件之后,可用同过下述命令使配置文件生效。
Register-PSSessionConfiguration -Path .HelpDeskEndpoint.pssc -RunAsCredential COMPANYHelpDeskProxyAdmin -ShowSecurityDescriptorUI -Name HelpDesk
这就创建好了一个
Enter-PSSession -ComputerName SS1 -ConfiguraionName HelpDesk
深入远程控制身份验证
微软期望更多是在域环境下使用
- 名称可以被解析为
IP 地址 - 名称必须与活动目录中的计算机名称匹配
如果不满足这些条件,则无法实现双向身份验证,也就无法远程。这样你只能选择:
要想通过
在任意
- 展开计算机配置
- 展开管理模块
- 展开
Windows 组 - 展开
Windows 远程控制管理 - 展开
WinRM 客户端 - 双击受信任的主机
- 启用策略并添加信任的主机列表,多个可通过逗号分隔,如“
*.company.com ,*.sales.company.com. ”
总结
以上是对