有没有办法编写脚本来安装软件中心列出的系统中心配置管理器更新?

有没有办法编写脚本来安装软件中心列出的系统中心配置管理器更新?

我们的停机时间非常紧张,对于我们的许多系统来说,服务器必须按照正确的顺序重新启动。因此,我想编写更新脚本。

我曾尝试使用这个在 Microsoft 脚本存储库中找到的 Powershell 脚本但是,对我来说,它无法远程工作,使用 Invoke-Command 时也并不总是有效,并且它会启动安装然后返回而不等待安装完成。我希望每个系统在安装完成后都重新启动,如果没有安装阻止或状态信息来阻止,这很难编写脚本。在花费了太多时间尝试让 CCM_SoftwareUpdate 和 CCM_SoftwareUpdatesManager WMI 类满足我的需要后,我想是时候问问其他人如何处理类似的情况了。

我的一个朋友说,他的公司通过使用沙夫利克但不幸的是,这里没有这个选项。

我们正在使用 SCCM 2012,并且混合使用 2003、2008 和 2012 服务器。

答案1

是的。您可以使用 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"并将每个更新逐一传递给 InstallUpdates 方法,因为我想以类似于 Microsoft 的方式显示进度。您必须将一个数组传递给 InstallUpdates 方法,即使您只传递一个更新对象。如果您愿意,您可以传递整个返回的数组,它会像往常一样将它们排队,逐一安装它们。

另外,如何为该集合配置维护窗口,并告诉 sccm 不要在维护窗口之外安装更新?当一个更新完成时,如果超过了维护窗口,它将停止安装更新(对我来说理论上是这样,我从来没有享受过维护窗口的奢侈)。

如果你是吉米德代码这类人,该代码应该用.NET 4.0编译,并且

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

有关 CCMClientSDK 的更多信息这里

答案2

以下是我从各种网页上收集的信息。使用 Powershell。请注意,使用 WinRM(在远程服务器上使用 winrm quickconfig 来启用 WinRM)会更成功,它可以使用 cmdletInvoke-Command而不是,Invoke-WmiMethod但这种方法对我在 Server 2008 及更新版本上有效。对于 Server 2003,更新部署评估扫描有效,但 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)

相关内容