一般情况:

一般情况:

我需要向我域中数千台计算机发出 CLI 命令(cmd.exe 或 PowerShell)。出于显而易见的原因,这不需要手动执行任务,也不需要亲自访问每台计算机。

应该如何做呢?

答案1

一般情况:

如何同时向数千台 Windows 域计算机远程发出 CLI 命令?

与我们职业中的大多数事情一样,最简单的方法通常是将工作分解为简单、离散的任务,然后按顺序执行这些任务,或将它们串在一起(例如将它们全部放入一个脚本中)。

在此,我可以为您设立 3 项离散任务。

  1. 收集要发出命令的客户端列表。

  2. 连接到所有客户端。

  3. 向所有客户端发出命令。

在此之后,您可能想要验证结果,就像在此之前一样,您可能想要测试您的流程,但为了回答这个问题,我们先忽略这一点。只是不要忽略现实世界中的实施前和实施后测试,否则您会后悔的。

您还需要做出“架构”决策(是并行执行步骤 2 和步骤 3 还是串行执行),但我们也忽略这一点。我将串行执行它们,因为这样更简单,而且我很懒。

请注意,到目前为止,我从未提及任何特定工具、实现或给出的示例。这是故意的。到目前为止,以上都是设计和/或架构工作。是的,如果你想“做对”,你就得设计和规划实施。(从一般到具体。)

为了使其切实可行,下面是具体的我通过同时向数千台 Windows 域计算机发出命令解决了这个问题。


具体案例:

如何一次性更正所有 Windows 域计算机上的时间?

出于一些不需要深入讨论的原因,我最近遇到了一种情况,最好的解决方案是发出一个命令来每一个 单身的我使用我雇主的计算机来修复域内的时间偏差。(我的时间也非常紧张——我只有不到 2 小时的时间让域内的所有计算机与“真实”时间同步。)

  1. 收集要发出命令的客户端列表。

    • 由于我的环境的特殊性,再加上我的特定工具和技能,我使用 PowerShell 来执行此操作。
      • 我已将 PowerShell 部署到环境中的每个客户端,每个客户端都已加入域,我部署了一个 GPO 来启用 WinRM,以便进行 PowerShell 远程处理一年多以前,我在所有客户上都使用过 PowerShell,我喜欢它并且很习惯使用它。
      • 此处要使用的 cmdlet 是Get-ADComputer,用于从 Active Directory 检索计算机对象。这是可行的方法,因为所有计算机都已加入域,因此在 AD 中列出。
    • 因为我想要所有的计算机,也因为我接下来要做的,所以我想简单地将此列表存储在一个变量中,所以我将使用的具体命令是:
    • $boxlist = Get-ADComputer -filter *(将 Active Directory 中找到的所有计算机对象的列表存储在名为箱单

  2. 连接到所有客户端。

    • 由于时间紧迫,我决定坚持我所了解的内容。我经常使用 PowerShell Remoting 来管理单台计算机或小型计算机组,并且非常熟悉它。我还没有将它用于这么大的组,但它没有理由不能工作,而且我现在没有时间学习新东西或安装新工具,所以只能这样了。
    • 此时,我意识到我需要提供凭证才能真正完成请求,因此选择了Get-Credentialcmdlet 来执行该操作,最终得到下面两个命令。
    • $creds = Get-Credential domain\user(创建一个提示,我在其中输入我的凭据,并将身份验证令牌存储在名为信用
    • $session = New-PSSession -ComputerName $boxlist.name -Credential $creds(为箱单变量,使用我刚刚提供的凭据,并将这些 PowerShell 会话存储在名为会议

  3. 向所有客户端发出命令。

    • 由于我们域上的时间配置方式以及时间偏差的根本原因,我已经知道要发出什么命令。我们有一个 GPO,可以按照我们喜欢的方式设置所有 Windows 时间服务设置,我们的权威时间源与真实时间同步,我们的下属时间源与域的权威时间源同步,我需要做的只是强制客户端立即地与本地时间源重新同步。-这要求w32tm /resync /nowait /rediscover并使用 Powershell,将使用以下命令调用调用命令执行以下命令:
    • Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}(将传递给 Scriptblock 开关的命令调用到 Session 开关,其中包含名为会议其中有我域中所有计算机的列表)

脚本或其所有组件都已编写完毕,可以在 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}

相关内容