C# 中的 PC 审计应用程序






4.29/5 (12投票s)
2007年2月27日
3分钟阅读

160352

6935
一个用 C# 开发的基础 PC 审计程序。
引言
在日常工作中,我遇到的一个挑战是如何准确审计我网络上的计算机。我考虑购买几个不同的软件包,最后一个要花 4,500 美元来监控 250 个系统,但我始终不想花这笔钱。后来,我开始考虑自己编写一个审计程序是多么容易,这样就可以解决问题,而无需花钱。
使用代码
我开始研究,发现了几种方法可以使用 System.Environment
类、WMI 数据和 Windows 注册表来检索我需要的系统信息。我能够通过 System.Environment
类获取基本信息,例如计算机名称、当前用户和操作系统版本。我注意到一个问题是,我只能返回当前登录的用户。因此,上次登录到计算机的用户将显示为该系统的用户。相反,我决定跟踪用户登录计算机的次数。这样,我可以将用户字段填充为登录该计算机次数最多的人。
computerName = Environment.MachineName;
userName = Environment.UserName;
osVersion = Environment.OSVersion.ToString();
这很好,但我也想提取有关已安装软件、内存、本地磁盘信息和其他硬件详细信息的信息。WMI 提供了提取所有硬件信息的方法。我下载了一个 WMI 浏览器,并迅速找到了我需要的所有信息。 WMI 是通过使用 ManagementObjectSearcher
和 ManagementObjectCollection
对象来搜索的。
//Computer model and memory information
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
ManagementObjectCollection queryCollection1 = query1.Get();
foreach (ManagementObject mo in queryCollection1)
{
model = mo["model"].ToString();
memory = Convert.ToInt32(mo["totalphysicalmemory"]);
}
//Processor type and speed
query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
queryCollection1 = query1.Get();
foreach (ManagementObject mo in queryCollection1)
{
processor = mo["Name"].ToString();
}
//disk drives, total capacity and free space
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk");
ManagementObjectCollection queryCollection1 = query1.Get();
foreach (ManagementObject mo in queryCollection1)
{
sSql = "INSERT INTO diskDrives (deviceID, description, "
+ "freeSpace, size, computerId) values ('"
+ mo["DeviceID"] + "', '"
+ mo["Description"] + "', '"
+ mo["Freespace"] + "', '"
+ mo["Size"] + "', "
+ computerID + ")";
oComm = new SqlCommand(sSql, oConn);
oComm.ExecuteNonQuery();
}
我还发现,在 WMI 中,我能够获得有关已安装内存的更多详细信息,例如已安装的内存芯片数量和这些芯片的大小。
ManagementObjectSearcher query1 =
new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMemory");
ManagementObjectCollection queryCollection1 = query1.Get();
foreach (ManagementObject mo in queryCollection1)
{
sSql = "INSERT INTO memory (capacity, location, computerId) values ("
+ mo["Capacity"] + ", '"
+ mo["DeviceLocator"] + "', "
+ computerID + ")";
oComm = new SqlCommand(sSql, oConn);
oComm.ExecuteNonQuery();
}
我想要找到的最后一部分是当前已安装的应用程序。由于注册的 Windows 应用程序需要在卸载注册表项中放置一个条目,因此这是获取所需信息的最干净的方法。 Windows 还会为它安装的大多数补丁保留一个条目,这不是我感兴趣的事情,因为我有一个单独的补丁管理服务器来处理这个问题。因此,我决定过滤掉任何以 KB 开头的条目(Microsoft 补丁的常用名称)。
RegistryKey regKey, regSubKey;
regKey = Registry.LocalMachine;
regKey = regKey.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").
OpenSubKey("Windows").OpenSubKey("CurrentVersion").
OpenSubKey("Uninstall");
string[] foo = regKey.GetSubKeyNames();
for (int i = 0; i < foo.Length; i++)
{
string bar = foo[i].ToString();
if (String.Compare(bar, 0, "KB", 0, 2) != 0)
{
regSubKey = regKey.OpenSubKey(foo[i]);
if (regSubKey.GetValue("DisplayName") != null)
{
string software = regSubKey.GetValue("DisplayName").ToString();
software = software.Replace("'", "''");
sSql = "INSERT INTO software (computerId, " +
"softwareName) values (" + id + ", '" + software + "')";
oComm = new SqlCommand(sSql, oConn);
oComm.ExecuteNonQuery();
}
}
}
这解决了所有的代码工作,唯一剩下的部分是将其分发给大众。由于 .NET 安全功能,该应用程序需要在本地驱动器上运行。因此,登录脚本中的一个简单的 bat 文件会挂载一个网络共享,在该网络共享中可以找到可执行文件,将其复制到本地临时目录,执行审计,然后删除自身和文件共享。
audit.bat
net use z: \\networkShare
z:
cd audit
copy audit.exe %temp%
c:
net use z: /delete
cd %temp%
audit.exe
del audit.exe
我需要的最后一部分是一种报告收集的数据的方式。一个带有 GridView
的简单 Web 应用程序显示了数据。
关注点
在深入研究之前,我不熟悉 WMI 的功能,我非常惊讶地发现其中存储了关于系统的如此多的细节。通过使用一个简单的 WMI 浏览器,我能够快速找到我正在寻找的所有东西,以及一些非常有用的东西。
历史
- 2/27/07 - 上传代码到 Web 界面。