HopelessN00b Asked: 2014-09-06 12:20:50 +0800 CST2014-09-06 12:20:50 +0800 CST 2014-09-06 12:20:50 +0800 CST 如何一次远程向数千台 Windows 域计算机发出 CLI 命令? 772 我需要向我域中的所有数千台计算机发出 CLI 命令(cmd.exe 或 PowerShell)。出于显而易见的原因,这不会涉及手动执行任务或物理访问每台机器。 这应该怎么做? windows 1 个回答 Voted Best Answer HopelessN00b 2014-09-06T12:20:50+08:002014-09-06T12:20:50+08:00 一般情况: 如何一次远程向数千台 Windows 域计算机发出 CLI 命令? 与我们专业中的大多数事情一样,您最简单的方法通常是将工作分解为简单、离散的任务,然后按顺序执行这些任务,或者将它们重新组合在一起(例如将它们全部放在一个脚本中) . 在此,您有 3 个我可以建立的离散任务。 收集要发出命令的客户端列表。 连接到所有客户端。 向所有客户端发出命令。 在此之后,您可能想要验证结果,就像在此之前一样,您想要测试您的过程,但为了这个问题的目的,让我们忽略它。只是不要忽略现实世界中的实施前和实施后测试,否则你会后悔的。 您还需要做出“架构”决定(是并行还是串行执行步骤 2 和 3),但我们也忽略它。我将连续进行,因为它更容易,而且我很懒。 请注意,到目前为止,我从未提及任何特定的工具、实现或给出的示例。这是故意的。到目前为止,以上都是设计和/或建筑工作。是的,如果您想“正确地做”,您可以在实施之前进行设计和计划。(从一般到具体。) 为了实现这一点,下面是我通过同时向数千台 Windows 域计算机发出命令来解决的一个特定问题。 具体案例: 如何一次更正所有 Windows 域计算机上的时间? 由于不需要深入探讨的原因,我最近遇到了一种情况,最好的解决方案是向我雇主拥有的每台计算机发出 一个命令,以修复域范围的时间偏差。(我的时间也很受限制——用不到 2 小时的时间让域中的所有计算机与“真实”时间同步。) 收集要发出命令的客户端列表。 由于我的环境的特殊性,再加上我的特定工具和技能,我使用 PowerShell 来执行此操作。 我已将 PowerShell 部署到环境中的每个客户端,每个客户端都已加入域,我部署了一个 GPO 来启用 WinRM,一年多前为了在我的所有客户端上进行 PowerShell 远程处理,我喜欢 PowerShell 并且使用它很舒服. 此处使用的 cmdlet 是Get-ADComputer,用于从 Active Directory 中检索计算机对象。这是要走的路,因为所有计算机都已加入域,因此在 AD 中列出。 因为我想要所有的计算机,并且因为我接下来要做的事情,我想简单地将这个列表存储在一个变量中,所以我将使用的具体命令是: $boxlist = Get-ADComputer -filter *(将在 Active Directory 中找到的所有计算机对象的列表存储到名为boxlist的变量中) 连接到所有客户端。 因为我很着急,所以我会坚持我所知道的。我经常将 PowerShell Remoting 用于单台计算机或一小组计算机,并且对它非常满意。我没有将它用于这么大的团队,但它没有理由不工作,而且我现在没有时间学习新事物或安装新工具,所以它必须这样做。 New-PSSession是我的首选 cmdlet。 此时,我意识到我需要提供凭据才能实际完成请求,选择Get-Credentialcmdlet 来执行此操作,并最终得到以下两个命令。 $creds = Get-Credential domain\user(创建一个提示,我在其中输入我的凭据并将身份验证令牌存储在名为creds的变量中) $session = New-PSSession -ComputerName $boxlist.name -Credential $creds(使用我刚刚提供的凭据为boxlist变量中的每台计算机创建新的 PowerShell 会话,并将这些 PowerShell 会话存储在名为sessions的变量中) 向所有客户端发出命令。 由于在我们的域上配置时间的方式,以及时间偏差的根本原因,我已经知道我要发出什么命令。我们有一个 GPO,可以按照我们喜欢的方式设置所有 Windows 时间服务设置,我们的权威时间源同步到真实时间,我们的从属时间源与域的权威时间源同步,我需要做的只是强制客户端立即与其本地时间源重新同步。- 这将使用Invoke-Command cmdletw32tm /resync /nowait /rediscover调用和使用 Powershell 。 Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}(将提供给 Scriptblock 开关的命令调用到 Session 开关,其中包含名为sessions的变量,其中包含我域中所有计算机的列表) 该脚本或其所有组件都已编写完毕,可以在 PowerShell shell 中一次一行地执行,也可以保存为 PowerShell 脚本文件并运行。我很着急,这是一个非常短的脚本,我不认为我需要再次使用(或者无法重新创建,所以在 shell 窗口中逐行打孔就是我最终的结果正在做。 $boxlist = Get-ADComputer -filter * $creds = Get-Credential domain\user $session = New-PSSession -ComputerName $boxlist.name -Credential $creds Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}
一般情况:
如何一次远程向数千台 Windows 域计算机发出 CLI 命令?
与我们专业中的大多数事情一样,您最简单的方法通常是将工作分解为简单、离散的任务,然后按顺序执行这些任务,或者将它们重新组合在一起(例如将它们全部放在一个脚本中) .
在此,您有 3 个我可以建立的离散任务。
收集要发出命令的客户端列表。
连接到所有客户端。
向所有客户端发出命令。
在此之后,您可能想要验证结果,就像在此之前一样,您想要测试您的过程,但为了这个问题的目的,让我们忽略它。只是不要忽略现实世界中的实施前和实施后测试,否则你会后悔的。
您还需要做出“架构”决定(是并行还是串行执行步骤 2 和 3),但我们也忽略它。我将连续进行,因为它更容易,而且我很懒。
请注意,到目前为止,我从未提及任何特定的工具、实现或给出的示例。这是故意的。到目前为止,以上都是设计和/或建筑工作。是的,如果您想“正确地做”,您可以在实施之前进行设计和计划。(从一般到具体。)
为了实现这一点,下面是我通过同时向数千台 Windows 域计算机发出命令来解决的一个特定问题。
具体案例:
如何一次更正所有 Windows 域计算机上的时间?
由于不需要深入探讨的原因,我最近遇到了一种情况,最好的解决方案是向我雇主拥有的每台计算机发出 一个命令,以修复域范围的时间偏差。(我的时间也很受限制——用不到 2 小时的时间让域中的所有计算机与“真实”时间同步。)
Get-ADComputer
,用于从 Active Directory 中检索计算机对象。这是要走的路,因为所有计算机都已加入域,因此在 AD 中列出。$boxlist = Get-ADComputer -filter *
(将在 Active Directory 中找到的所有计算机对象的列表存储到名为boxlist的变量中)New-PSSession
是我的首选 cmdlet。Get-Credential
cmdlet 来执行此操作,并最终得到以下两个命令。$creds = Get-Credential domain\user
(创建一个提示,我在其中输入我的凭据并将身份验证令牌存储在名为creds的变量中)$session = New-PSSession -ComputerName $boxlist.name -Credential $creds
(使用我刚刚提供的凭据为boxlist变量中的每台计算机创建新的 PowerShell 会话,并将这些 PowerShell 会话存储在名为sessions的变量中)w32tm /resync /nowait /rediscover
调用和使用 Powershell 。Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}
(将提供给 Scriptblock 开关的命令调用到 Session 开关,其中包含名为sessions的变量,其中包含我域中所有计算机的列表)该脚本或其所有组件都已编写完毕,可以在 PowerShell shell 中一次一行地执行,也可以保存为 PowerShell 脚本文件并运行。我很着急,这是一个非常短的脚本,我不认为我需要再次使用(或者无法重新创建,所以在 shell 窗口中逐行打孔就是我最终的结果正在做。