web-dev-qa-db-ja.com

何千ものWindowsドメインコンピュータに一度にリモートでCLIコマンドを発行するにはどうすればよいですか?

ドメイン上の数千台のコンピューターすべてにCLIコマンド(cmd.exeまたはPowerShell)を発行する必要があります。明らかな理由から、これには手動でタスクを実行したり、各マシンに物理的にアクセスしたりする必要はありません。

これはどのように行う必要がありますか?

7
HopelessN00b

一般的なケース:

何千ものWindowsドメインコンピュータに一度にリモートでCLIコマンドを発行するにはどうすればよいですか?

私たちの職業のほとんどのものと同様に、最も簡単なアプローチは、通常、ジョブを単純な個別のタスクに分割し、それらのタスクを順番に実行するか、それらを(単一のスクリプトに入れるなどして)戻すことです。 。

これには、私が確立できる3つの個別のタスクがあります。

  1. コマンドを発行するクライアントのリストを収集します。

  2. すべてのクライアントに接続します。

  3. すべてのクライアントにコマンドを発行します。

この後、おそらくこれまでと同じように結果を検証したいと思うでしょうが、プロセスをテストしたいと思うでしょうが、この質問の目的のためにそれを無視しましょう。現実の世界での実装前と実装後のテストを無視しないでください。無視しないと、申し訳ありません。

また、「アーキテクチャ上の」決定を下す必要があります(ステップ2と3を並行して実行するか、順次実行するか)が、それも無視しましょう。それは簡単で、私は怠惰なので、私はそれらを逐次的に行います。

これまでのところ、特定のツール、実装、または特定の例について言及したことはありません。それは意図的です。これまでのところ、上記はすべて設計および/または建築作業でした。はい、「正しく実行」したい場合は、実装する前に(== --- ==)を設計および計画します。 (一般から特定へ。)

これを実用的にするために、以下はspecific問題を数千のWindowsドメインコンピューターに同時にコマンドを発行することによって解決しました。


特定のケース:

すべてのWindowsドメインコンピューターの時刻を一度に修正するにはどうすればよいですか?

入る必要がない理由で、私は最近、everysingleに単一のコマンドを発行することが最善の解決策であるという状況に遭遇しましたドメイン全体のタイムスキューを修正するために、私の雇用主が所有するコンピューター。 (私も非常に時間の制約がありました-ドメイン内のすべてのコンピューターを「真の」時間と同期させるのに2時間もかかりませんでした。)

  1. コマンドを発行するクライアントのリストを収集します。

    • 私の環境の詳細と特定のツールおよびスキルを組み合わせたため、PowerShellを使用してこれを行いました。
      • 環境内のすべてのクライアントにPowerShellを展開し、すべてのクライアントがドメインに参加しています PowerShell Remotingの目的でWinRMを有効にするためにGPO)を展開しました 私のクライアントは1年以上前、PowerShellが好きで使い慣れています。
      • ここで使用するコマンドレットは Get-ADComputer 、ActiveDirectoryからコンピュータオブジェクトを取得するために使用されます。これは、すべてのコンピューターがドメインに参加しているため、ADにリストされているためです。
    • すべてのコンピューターが必要であり、次に行うことのために、このリストを変数に単純に格納したいので、使用する特定のコマンドは次のとおりです。
    • $boxlist = Get-ADComputer -filter *(ActiveDirectoryで見つかったすべてのコンピューターオブジェクトのリストをboxlistという名前の変数に格納します)

  2. すべてのクライアントに接続します。

    • 私は急いでいるので、私が知っていることに固執します。単一のコンピューターまたはコンピューターの小さなグループにPowerShell Remotingを日常的に使用しており、非常に快適です。私はこれほど大きなグループでは使用していませんが、機能しない理由はありません。また、今すぐ新しいことを学んだり、新しいツールをインストールしたりする時間がないので、やらなければなりません。
      • New-PSSession は、このための私の頼りになるコマンドレットです。
    • この時点で、実際にリクエストを完了するには資格情報を提供する必要があることに気付き、 Get-Credential それを行うためのコマンドレット。結果として、以下の2つのコマンドで終了します。
    • $creds = Get-Credential domain\user(資格情報を入力するプロンプトを作成し、認証トークンをcredsという名前の変数に格納します)
    • $session = New-PSSession -ComputerName $boxlist.name -Credential $creds(先ほど提供した資格情報を使用して、boxlist変数内のすべてのコンピューターに対して新しいPowerShellセッションを作成し、それらのPowerShellセッションをsessionsという名前の変数に格納します)

  3. すべてのクライアントにコマンドを発行します。

    • ドメインでの時間の構成方法と時間のずれの根本的な原因により、どのコマンドを発行したいかは既にわかっています。 GPOは、すべてのWindowsタイムサービス設定を好きなように設定します。信頼できるタイムソースは実際の時間に同期され、従属するタイムソースはドメインの信頼できるタイムソースと同期されます。 、そして私がする必要があるのは、クライアントにローカルタイムソースとの即時再同期を強制することだけです。-これは w32tm /resync /nowait /rediscover 、およびPowershellを使用して、 Invoke-Command コマンドレットで呼び出されます。
    • Invoke-Command -Session $session -ScriptBlock {w32tm /resync /nowait /rediscover}(Scriptblockスイッチに渡されたコマンドをSessionスイッチに呼び出します。これには、ドメイン内のすべてのコンピューターのリストが含まれるsessionsという名前の変数が含まれます)

スクリプトまたはそのすべてのコンポーネントが記述されており、PowerShellシェルで一度に1行実行されるか、PowerShellスクリプトファイルとして保存されて実行されます。私は急いでいて、これは私が再び使用する必要があるとは思えないかなり短いスクリプトです(または再作成に問題があるため、シェルウィンドウで1行ずつパンチするのが最終的なものです)やっている。

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