web-dev-qa-db-ja.com

ソフトウェアセンターにリストされているSystemCenter Configuration Managerの更新プログラムのインストールをスクリプト化する方法はありますか?

非常にタイトな停止ウィンドウがあり、多くのシステムでは、サーバーを正しい順序で再起動する必要があります。このため、更新のスクリプトを作成したいと思います。

私はこれを使おうとしました MicrosoftスクリプトリポジトリにあるPowershellスクリプト しかし、私にとってはリモートでは機能せず、Invoke-Commandを使用して常に機能するとは限らず、インストールを開始してから待機せずに戻りますインストールを完了します。インストールの完了後に各システムを再起動したいのですが、インストールのブロックまたはブロックするステータス情報がないとスクリプトを作成するのは困難です。あまりにも多くの時間を費やして、CCM_SoftwareUpdateクラスとCCM_SoftwareUpdatesManager WMIクラスに必要な処理を実行させようとした後、他のユーザーが同様の状況をどのように処理しているかを尋ねるときが来たと思いました。

私の友人は、彼の会社が Shavlik を使用してこの問題を解決したと言っていますが、残念ながら、それはここではオプションではありません。

SCCM 2012を使用しており、2003、2008、および2012サーバーが混在しています。

5
Nathan Hartley

はい。これは、投稿したスクリプトが実行しようとしているのと同様のPowerShellを使用して実行できます。しばらく前にそのスクリプトに出くわしました。それが機能したかどうかは思い出せませんが、何かが機能するようになりました。彼が機能しない理由はわかりません。同じ方法を使用しますが、C#を使用して.NETとWMIでこれを実行できたので、PowerShellで実行できることはわかっています。

private void InstallUpdates()
    {
        ManagementScope sc = new ManagementScope(@"\\.\root\ccm\clientsdk");
        ManagementClass c = new ManagementClass(@"CCM_SoftwareUpdatesManager");
        ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM CCM_SOFTWAREUPDATE WHERE COMPLIANCESTATE=0 AND EVALUATIONSTATE < 2");
        c.Scope = s.Scope = sc;

        ManagementObjectCollection col = s.Get();
        List<ManagementObject> lUpdates = new List<ManagementObject>();

        //Install each update individually and display progress
        int index = 1;

        //double progress = 5/10;

        //progressBar1.Value = progress;
        //this.Enabled = false;

        foreach (ManagementObject o in col)
        {

            System.Management.ManagementBaseObject[] args = { o };

            object[] methodArgs = { args };

            c.InvokeMethod("InstallUpdates", methodArgs);

            lblCurrentUpdate.Text = "Now Installing Update " + index + " of " + col.Count;

            UInt32 evalState = 0;
            progressBar1.Value = (int)(((index) / (double)col.Count)*100.0);

            //isCompleted = false;
            //backgroundWorker1.RunWorkerAsync(o);

            while (evalState < 7)
            {

                try
                {
                    o.Get();
                    evalState = (UInt32)o.Properties["EvaluationState"].Value;
                }

                catch (Exception ex)
                {
                    break;
                }

            }

            ++index;

        }

        //this.Enabled = true;

        //Restart Workstation
        System.Diagnostics.Process.Start("shutdown.exe", "-r -t 0 -f");

        Application.Exit();

    }

一言で言えば、私はWMIクエリを使用しました"SELECT * FROM CCM_SOFTWAREUPDATE WHERE COMPLIANCESTATE=0 AND EVALUATIONSTATE < 2"そして、Microsoftと同じように進行状況を表示したかったので、各更新を1つずつInstallUpdatesメソッドに渡しました。単一の更新オブジェクトのみを渡す場合でも、InstallUpdatesメソッドに配列を渡す必要があります。必要に応じて、返された配列全体を渡すことができます。これにより、通常どおりにキューに入れられ、1つずつインストールされます。

また、このコレクションのメンテナンスウィンドウを構成し、メンテナンスウィンドウの外に更新プログラムをインストールしないようにsccmに指示するのはどうですか? 1つの更新が終了すると、それがメンテナンスウィンドウを過ぎた場合、アップデートのインストールが停止します(理論的には、メンテナンスウィンドウに贅沢をしたことはありません)。

あなたがgimmiedehcodezのような人なら、そのコードは.NET4.0でコンパイルする必要があります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Management;
using System.Windows.Forms;

CCMClientSDKの詳細 ここ

2
MDMoore313

これが私がさまざまなウェブページからまとめたものです。 Powershellの使用。 Invoke-Commandの代わりにInvoke-WmiMethodコマンドレットを使用できるWinRM(リモートサーバーでwinrm quickconfigを使用してWinRMを有効にする)を使用すると、より成功することに注意してください。ただし、この方法はServer2008以降で機能します。 。 Server 2003の場合、Updates展開評価スキャンは機能しますが、Powershellは何かについて文句を言います。これを回避するには、コマンドをローカルで実行します。

#Start the System Center Configuration Manager Software Updates Deployment Evaluation Scan
$trigger = '{00000000-0000-0000-0000-000000000108}'
$scan = Invoke-WmiMethod -ComputerName $server -Namespace root\ccm -Class sms_client -Name TriggerSchedule $trigger

[System.Management.ManagementObject[]] $CMMissingUpdates = @(GWMI -ComputerName $server -query "SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState = '0'" -namespace "ROOT\ccm\ClientSDK") #End Get update count.
(GWMI -ComputerName $server -Namespace "root\ccm\clientsdk" -Class "CCM_SoftwareUpdatesManager" -List).InstallUpdates($CMMissingUpdates)
1
maxflipz