65.9K
CodeProject 正在变化。 阅读更多。
Home

2007 年夏令时:更新 Windows 服务器和工作站

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (1投票)

2007年2月15日

CPOL

1分钟阅读

viewsIcon

48874

downloadIcon

183

在您的Active Directory结构中搜索Windows操作系统,然后应用新的夏令时规则,而无需支付热修复更新费用,也不需要由于组策略而重启。

引言

新的夏令时规则将于2007年3月11日凌晨2点生效。微软提供了一些更新系统的示例说明,但存在一些严重的缺点

  • 不支持Windows 2000服务器或工作站。实际上是支持的,但您需要支付“扩展支持”费用才能获得它。
  • Windows Server 2003的补丁是“可选的”,因此您必须选择自定义Windows更新 - 而不是默认的“关键更新”。这已经不再是这种情况了;微软最近将该补丁更改为“关键更新”。
  • 微软提出的更新多台计算机的解决方案涉及计算机节点组策略对象,这很好,但它确实需要重启。

这里是微软关于此主题的知识库文章。

解决方案

我做的是编写一个控制台应用程序,通过操作系统查询AD结构,然后使用SysInternals的PsExec工具在多台远程机器上执行注册表更新。

环境:Visual Studio 2005,.NET 2.0,C#(您需要添加System.DirectoryServices的引用)

这是代码

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.DirectoryServices;
using System.Diagnostics;

namespace MyNamespace
{
  class Program
  {
  static void Main(string[] args)
  {
    SearchResultCollection results = null;

    StreamWriter sw = new StreamWriter("\\\\sharename\\DST$\\results.log", true);
    StreamWriter swerr = new StreamWriter("\\\\sharename\\DST$\\errors.log", true);

    try
    {
    // Bind to a container.
    string path = "ldap://DC=ABC,DC=DEF,DC=org/">ldap://DC=ABC,DC=DEF,DC=org/";

    DirectoryEntry entry = new DirectoryEntry(path);

    // Create a DirectorySearcher object.
    DirectorySearcher mySearcher = new DirectorySearcher(entry);
    mySearcher.PropertiesToLoad.Add("name");
    mySearcher.PropertiesToLoad.Add("operatingsystem");
    // Set a filter for W2K servers. Can also be used for 2003
    // mySearcher.Filter = 
    // "(&(objectCategory=computer)(operatingSystem=Windows Server 2003))";
    // Testing a single machine would look like this
    // mySearcher.Filter = "(&(objectCategory=computer)
    // (operatingSystem=Windows 2000 Server)(name=SERVERNAME))";

    mySearcher.Filter = "(&(objectCategory=computer)
                    (operatingSystem=Windows 2000 Server))";

    results = mySearcher.FindAll();

    foreach (SearchResult searchResult in results)
      {
        ResultPropertyValueCollection valcol = searchResult.Properties["name"];
        {
        // Write the value contained in index position 0 in the name attribute.

        string pc = valcol[0].ToString();

        // User needs to be a Domain Admin or a local admin on the remote computer
        string psargs = "\\\\" + pc + " -u DOMAIN\\username -p password 
                    \\\\sharename\\DST$\\DSTUpdate.bat";

        Process proc = new Process();
        proc.StartInfo.FileName = "C:\\sharename\\DST\\psexec.exe";
        proc.StartInfo.Arguments = psargs;
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.Start();
        proc.WaitForExit();

        string output = proc.StandardOutput.ReadToEnd();

        // This is done this way because SysInternal's PsExec 
        // does not handle StandardOutput and StandardError
        // when running on a remote machine 
        sw.WriteLine("Computer: " + pc + 
                 " Result(blank = no update): " + output + "\r\n");
        sw.Flush();

        proc.Close();

        }
      }
    }

    catch (Exception ex)
    {
      swerr.WriteLine("Error: " + ex.Message);
    }

    finally
    {
      // To prevent memory leaks, always call 
      // SearchResultCollection.Dispose() manually.
      if (null != results)
      {
      results.Dispose();
      results = null;
      }

    sw.Close();
    swerr.Close();
    }

  }//end main
  }//end class
}// end namespace

文件DTSUpdate.bat只有三行

@echo off
regedit /s \\sharename\DST$\DSTRegistry.reg
cscript \\sharename\DST$\DSTInfo.vbs

这两个文件(DSTRegistry.regDSTInfo.vbs)直接来自微软网站

结论

看起来很多公司都在为夏令时问题做准备。这可能不会造成太大的问题,但最好做好准备。我以为已经有人发布了类似的东西,但什么也没找到……所以我把它公开发布。如果有人找到将PsExec输出管道传输到文件的方法,我真的很想知道。谢谢。

© . All rights reserved.