使用VBScript运行OSPP.vbs获取Office密钥的报错排查
解决VBScript调用ospp.vbs提取Office密钥的问题
嘿,看你在做公司主机信息盘点的脚本,已经搞定了BIOS、网络配置这些数据,就卡在Office密钥提取这儿对吧?我帮你梳理下怎么把这个问题解决掉,顺便把你现有的脚本优化一下。
首先先复盘你踩过的坑:
- 一开始直接调用ospp.vbs报错,因为微软的这个脚本必须用cscript引擎运行,不能用wscript
- 后来加了强制转cscript的子过程还是报错,最后发现是Office路径指向错了(你用了Office16的路径,但公司装的是2010,对应Office14目录),修正后终于能启动cscript窗口,但还没把密钥提取出来
接下来直接上修正后的完整脚本,我帮你调整了路径、修复了命令引号的问题,还加了提取密钥最后5位的逻辑:
RunMeAsCScript Dim wshShell, oExec, output, keyLine, lastFiveKey Set wshShell = WScript.CreateObject("WScript.Shell") ' 注意:Office 2010对应Office14目录,2016是Office16,根据实际版本调整 Dim osppPath osppPath = "C:\Program Files (x86)\Microsoft Office\Office14\ospp.vbs" ' 正确构建执行命令:用双引号包裹带空格的路径,避免命令解析错误 Dim execCommand execCommand = "c:\Windows\System32\cscript.exe """ & osppPath & """ /dstatus" ' 执行命令并等待运行完成 Set oExec = wshShell.Exec(execCommand) Do While oExec.Status = 0 WScript.Sleep 500 ' 缩短等待间隔,不用等5秒这么久 Loop ' 读取ospp.vbs的全部输出内容 output = oExec.StdOut.ReadAll() ' 从输出中匹配密钥最后5位的行(ospp.vbs只会显示最后5位,这是微软的安全限制) keyLine = Split(output, vbCrLf) For Each line In keyLine If InStr(LCase(line), "last 5 characters of installed product key") > 0 Then lastFiveKey = Trim(Right(line, 5)) Exit For End If Next ' 这里可以把结果集成到你的XML输出逻辑里 If lastFiveKey <> "" Then WScript.Echo "Office 2010密钥最后5位: " & lastFiveKey ' 示例:把lastFiveKey写入你现有的XML文件节点 ' 比如调用你已有的XML生成函数,添加<OfficeKeyLast5>节点 Else WScript.Echo "未找到Office密钥信息" End If ' 强制用CScript运行的子过程(修复了原脚本的循环索引越界问题) Sub RunMeAsCScript() Dim strArgs, strCmd, strEngine, i, wshShell Set wshShell = CreateObject("WScript.Shell") strEngine = UCase(Right(WScript.FullName, 12)) If strEngine <> "\CSCRIPT.EXE" Then ' 重构命令行参数,避免索引越界 strArgs = "" If WScript.Arguments.Count > 0 Then For i = 0 To WScript.Arguments.Count - 1 strArgs = strArgs & " " & QuoteIt(WScript.Arguments(i)) Next End If ' 构建重新运行的命令 strCmd = "CSCRIPT.EXE //NoLogo """ & WScript.ScriptFullName & """" & strArgs ' 执行并等待新进程结束 Dim objDebug Set objDebug = wshShell.Exec(strCmd) Do While objDebug.Status = 0 WScript.Sleep 100 Loop WScript.Quit objDebug.ExitCode End If End Sub ' 处理带空格的参数引号包裹函数 Function QuoteIt(strTemp) If InStr(strTemp, " ") > 0 Then strTemp = """" & Replace(strTemp, """", """""") & """" End If QuoteIt = strTemp End Function
几个关键的优化点说明:
- 路径修正:Office版本对应的目录要搞对:2010是Office14,2013是Office15,2016/2019/365是Office16
- 命令拼接:原脚本里的ProgramPath写了多余的引号(四个引号),现在改成用
""" & osppPath & """来正确包裹带空格的路径 - 输出捕获:用
oExec.StdOut.ReadAll()直接获取所有输出,再通过字符串匹配找到密钥行 - 循环修复:原RunMeAsCScript里的循环边界写错了,会导致索引越界,现在改成
WScript.Arguments.Count - 1
另外要注意:ospp.vbs本身只会显示密钥的最后5位,这是微软的安全限制,没办法直接获取完整密钥(除非用第三方工具,但合规性要注意),所以用最后5位做盘点标识是合理的。
你可以把提取到的lastFiveKey变量直接集成到你现有的XML生成逻辑里,比如添加一个对应的节点就行啦。
内容的提问来源于stack exchange,提问作者Fotkurz
相关产品推荐
相关产品推荐

