CEOQAWindows 2003Visual Studio 2005Windows 2000架构师Windows XP.NET 2.0C# 2.0中级开发Visual StudioWindows.NETC#
2007 年夏令时:更新 Windows 服务器和工作站
在您的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.reg和DSTInfo.vbs)直接来自微软网站。
结论
看起来很多公司都在为夏令时问题做准备。这可能不会造成太大的问题,但最好做好准备。我以为已经有人发布了类似的东西,但什么也没找到……所以我把它公开发布。如果有人找到将PsExec输出管道传输到文件的方法,我真的很想知道。谢谢。