Question Comment puis-je envoyer à distance une commande CLI à des milliers d'ordinateurs de domaine Windows à la fois?


J'ai besoin d'émettre une commande CLI (cmd.exe ou PowerShell) à tous les milliers d'ordinateurs de mon domaine. Pour des raisons évidentes, cela ne va pas impliquer de faire la tâche manuellement ou de visiter physiquement chaque machine.

Comment cela devrait-il être fait?


7
2017-09-05 20:20


origine




Réponses:


Le cas général:

Comment puis-je envoyer à distance une commande CLI à des milliers d'ordinateurs de domaine Windows à la fois?

Comme pour la plupart des activités de notre profession, votre approche la plus simple consiste généralement à diviser le travail en tâches simples et discrètes, puis à exécuter ces tâches dans l'ordre, ou à les relier (par exemple en les plaçant dans un seul script). .

En cela, vous avez 3 tâches distinctes que je peux établir.

  1. Recueillir une liste de clients sur lesquels la commande doit être exécutée.

  2. Connectez-vous à tous les clients.

  3. Émettez la commande à tous les clients.

Après cela, vous voudrez probablement vérifier les résultats, tout comme avant, vous voudrez tester votre processus, mais ignorons cela pour les besoins de cette question. N'ignorez pas les tests de pré-implémentation et de post-implémentation dans le monde réel, sinon vous serez désolé.

Vous devez également prendre une décision "architecturale" (si vous souhaitez exécuter les étapes 2 et 3 en parallèle ou en série), mais ignorons-le également. Je vais les faire en série, parce que c'est plus facile et que je suis paresseux.

Notez, à ce jour, je n’ai jamais fait mention d’outils spécifiques, d’implémentations ou d’exemples donnés. C'est délibéré. Jusqu'à présent, tout ce qui précède était un travail de conception et / ou d'architecture. Oui, si vous voulez "faire les choses correctement", vous concevez et planifiez avant vous mettez en œuvre. (Passez du général au spécifique.)

Pour rendre cela pratique, voici un spécifique problème que j'ai résolu en émettant simultanément une commande à des milliers d'ordinateurs du domaine Windows.


Le cas spécifique:

Comment corriger l'heure sur tous mes ordinateurs de domaine Windows en même temps?

Pour des raisons inutiles, j’ai récemment rencontré une situation dans laquelle la meilleure solution consistait à émettre une seule commande à chaque  unique ordinateur appartenant à mon employeur, afin de corriger un décalage temporel dans l’ensemble du domaine. (J'étais également très limité par le temps - il me restait moins de 2 heures pour que tous les ordinateurs du domaine soient synchronisés avec l'heure "vraie".)

  1. Recueillir une liste de clients sur lesquels la commande doit être exécutée.

    • En raison des spécificités de mon environnement, associées à mes outils et compétences spécifiques, j'ai utilisé PowerShell à cette fin.
    • Parce que je veux tous les ordinateurs, et à cause de ce que je vais faire ensuite, je veux simplement stocker cette liste dans une variable. La commande spécifique que j'utiliserai est la suivante:
    • $boxlist = Get-ADComputer -filter *(Stocke une liste de tous les objets ordinateur trouvés dans Active Directory dans la variable nommée liste de boîtes)

  2. Connectez-vous à tous les clients.

    • Depuis que je suis pressé, je vais rester avec ce que je sais. J'utilise régulièrement PowerShell Remoting pour des ordinateurs isolés ou de petits groupes d'ordinateurs et je suis très à l'aise avec cela. Je ne l'ai pas utilisé pour un groupe de cette taille, mais rien n'empêche que cela ne fonctionne pas, et je n'ai pas le temps d'apprendre de nouvelles choses ou d'installer de nouveaux outils pour le moment, il faudra donc le faire.
    • À ce stade, je me rends compte que je devrai fournir des informations d’identité pour compléter la demande, a choisi le Get-Credential applet de commande pour faire cela, et se retrouver avec les deux commandes ci-dessous à la suite.
    • $creds = Get-Credential domain\user (Crée une invite dans laquelle je saisis mes informations d'identification et stocke un jeton d'authentification dans la variable nommée Cred)
    • $session = New-PSSession -ComputerName $boxlist.name -Credential $creds (Crée de nouvelles sessions PowerShell pour chaque ordinateur de la liste de boîtes variable, à l'aide des informations d'identification que je viens de fournir, et stocke ces sessions PowerShell dans la variable nommée sessions)

  3. Émettez la commande à tous les clients.

    • En raison de la façon dont l'heure est configurée sur notre domaine et de la cause fondamentale de l'inclinaison de l'heure, je sais déjà quelle commande je souhaite émettre. Nous avons un objet de stratégie de groupe qui définit tous les paramètres du service de temps Windows comme nous le souhaitons, notre source de temps faisant autorité est synchronisée jusqu'à l'heure vraie, nos sources de temps subordonnées sont synchronisées avec la source de temps faisant autorité du domaine, et ce que je dois faire, c'est simplement forcer les clients à immédiatement resynchroniser avec leur source de temps locale. -Cela appelle à w32tm /resync /nowait /rediscoveret utilisant Powershell, serait invoqué avec le Invoke-Command cmdlet.
    • Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover} (Invoque la commande transmise au commutateur Scriptblock au commutateur Session, qui contient la variable nommée sessions qui contient une liste de tous les ordinateurs de mon domaine)

Le script ou tous ses composants ont été écrits et peuvent soit être exécutés ligne par ligne dans un shell PowerShell, soit enregistrés en tant que fichier de script PowerShell et exécutés. Je suis pressé, et c'est un script assez court que je ne pense pas devoir utiliser à nouveau (ou avoir du mal à recréer, donc je le trouve, ligne par ligne dans la fenêtre shell) Faire.

$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}

10
2017-09-05 20:20