使用Golang在远程Windows服务器上执行WMI查询的实现方法

使用Golang在远程Windows服务器上执行WMI查询的实现方法 大家好,

我有一个用例,需要通过Go语言建立到远程Windows服务器的WMI连接。基本上,我需要传递主机名和用户凭据。一旦与远程主机建立WMI连接,就需要在远程服务器上运行WMI查询以获取服务器详细信息。在Go语言中如何实现这一点?我在Python中搜索时,发现Python已经有相应的实现。我需要这方面的帮助,请求指导如何解决我的用例。

我看到一些Go库可以为本地系统执行WMI枚举。

谢谢。

2 回复

你好。如果你的Windows机器上安装了SSH和WMI命令行工具,或许你可以使用Golang的SSH会话来在远程终端上运行命令?

更多关于使用Golang在远程Windows服务器上执行WMI查询的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中实现远程Windows服务器的WMI查询,可以使用go-oleoleutil库。以下是一个完整的示例:

package main

import (
    "fmt"
    "log"
    "github.com/go-ole/go-ole"
    "github.com/go-ole/go-ole/oleutil"
)

func main() {
    // 初始化COM库
    ole.CoInitialize(0)
    defer ole.CoUninitialize()

    // 创建WMI服务对象
    unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
    if err != nil {
        log.Fatal(err)
    }
    defer unknown.Release()

    wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
    if err != nil {
        log.Fatal(err)
    }
    defer wmi.Release()

    // 远程服务器连接参数
    server := "远程服务器IP或主机名"
    namespace := "root\\cimv2"
    user := "用户名"
    password := "密码"

    // 连接到远程WMI服务
    serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", server, namespace, user, password)
    if err != nil {
        log.Fatal("连接失败:", err)
    }
    service := serviceRaw.ToIDispatch()
    defer service.Release()

    // 执行WMI查询 - 获取操作系统信息
    query := "SELECT * FROM Win32_OperatingSystem"
    resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
    if err != nil {
        log.Fatal("查询失败:", err)
    }
    result := resultRaw.ToIDispatch()
    defer result.Release()

    // 获取查询结果数量
    countRaw, err := oleutil.GetProperty(result, "Count")
    if err != nil {
        log.Fatal(err)
    }
    count := int(countRaw.Val)

    // 遍历结果集
    for i := 0; i < count; i++ {
        itemRaw, err := oleutil.CallMethod(result, "ItemIndex", i)
        if err != nil {
            log.Fatal(err)
        }
        item := itemRaw.ToIDispatch()
        
        // 获取具体属性值
        caption, _ := oleutil.GetProperty(item, "Caption")
        version, _ := oleutil.GetProperty(item, "Version")
        totalMemory, _ := oleutil.GetProperty(item, "TotalVisibleMemorySize")
        
        fmt.Printf("操作系统: %v\n", caption.Value())
        fmt.Printf("版本: %v\n", version.Value())
        fmt.Printf("总内存: %v KB\n", totalMemory.Value())
        
        item.Release()
    }
}

如果需要查询其他WMI类,这里是一个获取磁盘信息的示例:

func queryDiskInfo(service *ole.IDispatch) {
    query := "SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"
    resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
    if err != nil {
        log.Fatal(err)
    }
    result := resultRaw.ToIDispatch()
    defer result.Release()

    countRaw, _ := oleutil.GetProperty(result, "Count")
    count := int(countRaw.Val)

    for i := 0; i < count; i++ {
        itemRaw, _ := oleutil.CallMethod(result, "ItemIndex", i)
        item := itemRaw.ToIDispatch()
        
        deviceID, _ := oleutil.GetProperty(item, "DeviceID")
        size, _ := oleutil.GetProperty(item, "Size")
        freeSpace, _ := oleutil.GetProperty(item, "FreeSpace")
        
        fmt.Printf("磁盘: %v\n", deviceID.Value())
        fmt.Printf("总大小: %v 字节\n", size.Value())
        fmt.Printf("可用空间: %v 字节\n", freeSpace.Value())
        
        item.Release()
    }
}

安装依赖库:

go get github.com/go-ole/go-ole

这个实现通过COM接口连接到远程Windows服务器的WMI服务,可以执行标准的WQL查询。确保远程服务器的防火墙允许WMI连接(默认端口135),并且用户账户有足够的权限。

回到顶部