Der allgemeine Fall:
Wie kann ich einen CLI-Befehl remote an Tausende von Windows-Domänencomputern gleichzeitig ausgeben?
Wie bei den meisten Dingen in unserem Beruf besteht Ihr einfachster Ansatz im Allgemeinen darin, den Job in einfache, diskrete Aufgaben zu unterteilen und diese Aufgaben dann entweder nacheinander auszuführen oder wieder aneinander zu reihen (z. B. indem Sie sie alle in einem einzigen Skript zusammenfassen). .
Hier haben Sie 3 diskrete Aufgaben, die ich festlegen kann.
Sammeln Sie eine Liste der Clients, für die der Befehl ausgegeben werden soll.
Stellen Sie eine Verbindung zu allen Clients her.
Geben Sie den Befehl an alle Clients aus.
Danach möchten Sie wahrscheinlich die Ergebnisse überprüfen, genau wie zuvor möchten Sie Ihren Prozess testen, aber lassen Sie uns dies für die Zwecke dieser Frage ignorieren. Ignorieren Sie die Tests vor und nach der Implementierung in der realen Welt nicht, sonst wird es Ihnen leid tun.
Sie müssen auch eine "architektonische" Entscheidung treffen (ob Sie die Schritte 2 und 3 parallel oder seriell ausführen möchten), aber lassen Sie uns dies ebenfalls ignorieren. Ich werde sie in Serie machen, weil es einfacher ist und ich faul bin.
Beachten Sie, dass ich bisher zu keinem Zeitpunkt bestimmte Tools, Implementierungen oder Beispiele erwähnt habe. Das ist absichtlich. Bis zu diesem Punkt waren alle oben genannten Design- und / oder Architekturarbeiten. Ja, wenn Sie wollen „es richtig machen“ Sie entwerfen und zu planen , bevor Sie implementieren. (Gehen Sie von allgemein zu spezifisch.)
Im Folgenden finden Sie ein spezielles Problem, das ich gelöst habe, indem ich gleichzeitig einen Befehl an Tausende von Windows-Domänencomputern ausgegeben habe.
Der spezielle Fall:
Wie korrigiere ich die Uhrzeit auf allen meinen Windows-Domänencomputern gleichzeitig?
Aus Gründen, auf die nicht eingegangen werden muss, bin ich kürzlich auf eine Situation gestoßen, in der die beste Lösung darin bestand, jedem einzelnen Computer meines Arbeitgebers einen einzigen Befehl zu erteilen , um einen domänenweiten Zeitversatz zu beheben. (Ich war auch sehr zeitlich begrenzt - hatte weniger als 2 Stunden Zeit, um alle Computer in der Domäne wieder mit der "wahren" Zeit zu synchronisieren.)
- Sammeln Sie eine Liste der Clients, für die der Befehl ausgegeben werden soll.
- Aufgrund der Besonderheiten meiner Umgebung und meiner spezifischen Tools und Fähigkeiten habe ich dazu PowerShell verwendet.
- Da ich alle Computer haben möchte und aufgrund dessen, was ich als Nächstes tun werde, möchte ich diese Liste einfach in einer Variablen speichern. Der spezifische Befehl, den ich verwenden werde, lautet also:
$boxlist = Get-ADComputer -filter *
(Speichert eine Liste aller in Active Directory gefundenen Computerobjekte in der Variablen boxlist. )
- Stellen Sie eine Verbindung zu allen Clients her.
- Da ich es eilig habe, bleibe ich bei dem, was ich weiß. Ich verwende PowerShell Remoting routinemäßig für einzelne Computer oder kleine Gruppen von Computern und bin damit sehr vertraut. Ich habe es nicht für eine so große Gruppe verwendet, aber es gibt keinen Grund, warum es nicht funktionieren sollte, und ich habe momentan keine Zeit, neue Dinge zu lernen oder neue Tools zu installieren, also muss es funktionieren.
- An diesem Punkt wird mir klar, dass ich Anmeldeinformationen
Get-Credential
angeben muss, um die Anforderung tatsächlich abzuschließen, das Cmdlet dafür auswählen und als Ergebnis die folgenden zwei Befehle erhalten muss.
$creds = Get-Credential domain\user
(Erstellt eine Eingabeaufforderung, in die ich meine Anmeldeinformationen eingebe und ein Authentifizierungstoken in der Variablen creds speichere. )
$session = New-PSSession -ComputerName $boxlist.name -Credential $creds
(Erstellt neue PowerShell-Sitzungen für jeden Computer in der Boxlist- Variablen unter Verwendung der soeben angegebenen Anmeldeinformationen und speichert diese PowerShell-Sitzungen in der Variablen " Sessions". )
- Geben Sie den Befehl an alle Clients aus.
- Aufgrund der Art und Weise, wie die Zeit in unserer Domäne konfiguriert ist, und der Hauptursache für den Zeitversatz weiß ich bereits, welchen Befehl ich ausgeben möchte. Wir haben ein Gruppenrichtlinienobjekt, das alle Windows-Zeitdiensteinstellungen nach unseren Wünschen festlegt, unsere autorisierende Zeitquelle wird mit der tatsächlichen Zeit synchronisiert, unsere untergeordneten Zeitquellen werden mit der autorisierenden Zeitquelle der Domäne synchronisiert, und ich muss nur tun Erzwingen Sie , dass die Clients sofort eine erneute Synchronisierung mit ihrer lokalen Zeitquelle durchführen. -Diese Aufrufe
w32tm /resync /nowait /rediscover
und die Verwendung von Powershell werden mit dem Cmdlet Invoke-Command aufgerufen.
Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}
(Ruft den Befehl auf, der dem Scriptblock-Switch an den Session-Switch übergeben wird, der die Variable " Sessions" enthält , in der eine Liste aller Computer in meiner Domäne enthalten ist.)
Das Skript oder alle seine Komponenten wurden geschrieben und können entweder zeilenweise in einer PowerShell-Shell ausgeführt oder als PowerShell-Skriptdatei gespeichert und ausgeführt werden. Ich habe es eilig, und dies ist ein ziemlich kurzes Skript, von dem ich mir nicht vorstellen kann, dass ich es erneut verwenden muss (oder Probleme beim Neuerstellen habe. Daher lande ich es Zeile für Zeile im Shell-Fenster tun.
$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}