我有一个从服务器日志中检索到的 Active Directory (AD) 用户名列表,代表正在使用不应该使用的软件的同事。
我需要从广告中查找他们的电子邮件地址或全名(如果电子邮件地址不可能/可靠),以联系这些用户。
我有一个从服务器日志中收集用户名列表的工具,它是用 Excel 编写的,因此是用 VBA 编写的。理想情况下,我需要一个可以通过 VBA 运行的解决方案。
有没有办法传递任意 AD 用户名(而不是当前用户),并从 AD 返回全名或电子邮件地址?
这应该原则上是可能的,因为使用 win32net.NetUserGetInfo 在 Python 中执行此操作很简单 - 因此底层 API 必须存在。
我也可以在 CMD 中实现我所需要的,使用以下行:
net user %userid% /DOMAIN | find /I "Full name"
是否可以从 VBA 内部调用上述行(没有企业防病毒软件阻止它的高风险,因为以前从 VBA 生成隐藏的 CMD shell 时曾发生过这种情况)?
我已经以一种相当不优雅的方式解决了这个问题,所以我愿意接受更好的答案,但我是通过直接使用CMD.exe(使用Shell从VBA)调用“net user”和另一个用于解析的SO答案相结合来完成的STDOUT 中该 Shell 命令的输出(从 VBA 中的 shell 命令捕获输出值?)。
我的代码的重要部分是在我的主 VBA 表中(为您提供“我”的上下文)代码:
' Note d_offenders is a dictionary of AD usernames (the value stored is a list of software they have open, so not relevant to this solution)
Dim key As Variant
For Each key In d_offenders.Keys
Me.Cells(start_row + i, output_col).Value2 = key
Me.Cells(start_row + i, output_col + 1).Value2 = get_name(CStr(key))
Me.Cells(start_row + i, output_col + 2).Value2 = d_offenders(key)
i = i + 1
Next key
然后我使用以下两个函数来定义如何检索全名:
Private Function get_name(uname As String) As String
Dim res As String
res = ShellRun("cmd.exe /C net user " & uname & " /DOMAIN | find /I ""Full name""")
If res > vbNullString Then get_name = Right(res, Len(res) - 29) Else get_name = "Not found."
End Function
Public Function ShellRun(sCmd As String) As String
'Run a shell command, returning the output as a string
Dim oShell As Object
On Error GoTo errHandler
Set oShell = CreateObject("WScript.Shell")
'run command
Dim oExec As Object
Dim oOutput As Object
Set oExec = oShell.Exec(sCmd)
Set oOutput = oExec.StdOut
'handle the results as they are written to and read from the StdOut object
Dim s As String
Dim sLine As String
While Not oOutput.AtEndOfStream
sLine = oOutput.ReadLine
If sLine <> vbNullString Then s = s & sLine & vbCrLf
Wend
ShellRun = s
Exit Function
errHandler:
ShellRun = vbNullString
End Function
正如我所说,弹出(临时)CMD 窗口有点笨拙,但它有效,我最终得到了一个列表: