/build/static/layout/Breadcrumb_cap_w.png

How TO: Track Windows and Office Product Keys

I’ve been getting a lot of request for this in my trainings, so here it is. 
At the end of this post, you will have all the tools you need to track your Windows product keys and Microsoft office product keys. 
They way this works is we find the keys using nirsoft's keyfinder program. 
Next a VBS writes the keys to the registry. 
Finally we tie it all together with custom inventory rules. 

Requirements:Product Finder (now form Nirsfot) 
Here is the link to the portable version
http://www.nirsoft.net/utils/produkey.zip 

First thing we need to do is copy this VBS code into notepad and save it as keys.vbs 

Option Explicit

Dim objFSO			
Dim objTextFile
Dim winKey 
Dim officeKey
Dim strFile
Dim arrKeys
Dim i

Const ForReading = 1
Const winCDLine = "Windows"
Const officeCDLine = "Microsoft Office"
Const noViso = "Visio"
Const officeKeyReg = "offKey"
Const winKeyReg = "winKey"


Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
    ("keys.csv", ForReading)

'Read the file into the array
strFile = objTextFile.ReadAll
arrKeys = Split(strFile, vbCrLf)

For i = LBound(arrKeys) To UBound(arrKeys)
	'try to find the windows product key
	If(instr(arrkeys(i),winCDLine))Then
		winKey = getKey(arrKeys(i))
		writeReg winKey,winKeyReg	
	End If
	'try to find the office product key
	If(InStr(arrKeys(i),noViso)) Then
	
	ElseIf(InStr(arrKeys(i),officeCDLine)) Then
		officeKey = getKey(arrKeys(i))
		writeReg officeKey,officeKeyReg
	End If
Next

Function getKey(strKeyLine)
Dim temper
Const KeyLoc = 2
Const ProdLoc = 0

temper = Split(strkeyLine,",")
getKey = temper(prodloc) & "_" & temper(KeyLoc)

End function


Sub writeReg(strValue,StrValueName)

Dim strComputer
Dim oReg
Dim wshShell

Const HKEY_LOCAL_MACHINE = &H80000002
Const strKeyPath = "SOFTWARE\TVG"
Const strKeyPath64 = "SOFTWARE\Wow6432Node\TVG"
Const is64Key = "SOFTWARE\Wow6432Node"

strComputer = "."

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
    strComputer & "\root\default:StdRegProv")
Set WshShell = WScript.CreateObject("WScript.Shell")

'check for 64 bit
If(OS64()) Then
	oReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath64
	oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath64,strValueName,strValue
Else
	oReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath
	oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
End If

End Sub

Function OS64()
Dim objOS
Dim colItems
Dim objItem
Dim strComputer

strComputer = "."
Set objOS = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objOS.ExecQuery("SELECT OSArchitecture FROM Win32_OperatingSystem")

'this should fail on 32 bit XP
On error resume next
For Each objItem In colItems
	If(IsNull(objItem.OSArchitecture)) Then 
		OS64 = False
	ElseIf(InStr(objItem.OSArchitecture,"64") > 0) Then
		OS64 = True
	Else 
		OS64 = False
	End If
Next
On Error Goto 0

If(Err <> 0) Then 
	OS64 = False
End if
End Function
 
Next thing we need to do is go to the scripting module and a new script. 
For script type select Online Shell Script. 
Choose a label, select windows as the operating system and set the script to run as local system. 
Next upload produkey.cfg, produkey.exe (both found in the nirsoft folder, make sure you unzip) and keys.vbs as dependencies. 
For the script text enter the following 2 lines. 
ProduKey.exe /windowskeys 1 /officekeys 1 /iekeys 0 /sqlkeys 0 /exchangekeys 0 /extractedition 1 /scomma keys.csv
cscript.exe keys.vbs


Last thing we need to do is change the script name from script.sh to script.bat (just below the script text). 

Now that we have the keys in the registry we can start creating the custom inventory rules. 
Go to the software module and add a new item. 
Call the first one “Windows Product Key” 
Select all your windows operating systems for supported OSs. 
Finally here is the syntax for the custom inventory rule: 
RegistryValueReturn(HKEY_LOCAL_MACHINE\SOFTWARE\TVG,winKey,TEXT)

Go ahead and save the software. 
Next add another item but this time call it "Microsoft Office Key" 
Highlight all the windows OSs again. 
Here is the syntax for the second piece of software. 
RegistryValueReturn(HKEY_LOCAL_MACHINE\SOFTWARE\TVG,offKey,TEXT)


At this point you could also create additional software records, for example one for each office key. 
That way depending on the key you would have a unique software title. This way you could use the KBOXs built in asset management module and do licence compliance. 

Below are two reports that you can use to see what machines have what keys installed. 
Office report: 
SELECT M.NAME,
       SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',1) AS OFFICE_VERSION,
       SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',-1) AS PRODUCT_KEY
FROM   SOFTWARE S,
       MACHINE_CUSTOM_INVENTORY MCI,
       MACHINE M
WHERE  MCI.SOFTWARE_ID = S.ID 
       AND M.ID = MCI.ID
       AND S.DISPLAY_NAME = 'Microsoft Office Key'
ORDER  BY OFFICE_VERSION,
          PRODUCT_KEY


Windows report: 
SELECT M.NAME,
       SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',1) AS WINDOWS_VERSION,
       SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',-1) AS PRODUCT_KEY
FROM   SOFTWARE S,
       MACHINE_CUSTOM_INVENTORY MCI,
       MACHINE M 
WHERE  MCI.SOFTWARE_ID = S.ID 
       AND M.ID = MCI.ID 
       AND S.DISPLAY_NAME = 'Windows Product Key'
ORDER  BY WINDOWS_VERSION,
          PRODUCT_KEY


I hope this is useful. 
Thanks to vacuna for helping me put this together. 

Comments

  • This is fantastic. We are actually diving into re-doing compliance agreements with Microsoft this year. It might help us pull some of our machines to see if there are any inconsistencies. Thanks! - Hammer1790 12 years ago
  • I can see this being very helpful to see if we have any keys out there being used that are not ours - shigbee 11 years ago
  • Just a few things i noticed.

    SELECT M.NAME,
    SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',1) AS OFFICE_VERSION,
    SUBSTRING_INDEX(MCI.STR_FIELD_VALUE,'_',-1) AS PRODUCT_KEY
    FROM SOFTWARE S,
    MACHINE_CUSTOM_INVENTORY MCI,
    MACHINE M
    WHERE MCI.SOFTWARE_ID = S.ID
    AND M.ID = MCI.ID
    AND S.DISPLAY_NAME = 'Microsoft Office Key'
    ORDER BY OFFICE_VERSION,
    PRODUCT_KEY

    This has a type, it needs to say 'Microsoft Product Key' or else it wont work.

    Visio does not work. It is detected by Nirsoft Produkey, its just the script does not create the Reg entry as expected.

    Any ideas? - talkwithphil 11 years ago
  • In my setup, to get Office Product Key report in KACE, the original formula worked.
    I didnt need to modify 'Microsoft Office Key' to 'Microsoft Product Key' - d-box 11 years ago
  • This worked perfectly! one question though. What needs to be changed to pull MS Visio or MS Project 2007 on the reports? - wchoi2104 10 years ago
  • Hey Just some more notes. I had an issue with our users because this method with the script embedded as an online script causes a popup to flash on the screen for the command prompt and users thought it was a virus and freaked out. I used a BAT to EXE converter and have the script run the .exe silently instead. takes care of the command popup and everyone is happy.

    LInk to the bat to exe is below.

    http://download.cnet.com/Bat-To-Exe-Converter/3000-2069_4-10555897.html

    I also reworked the VBS to differentiate between Microsoft Office, Project, Visio and Operating system and it reports on all 4 of them now which is perfect.

    VBS is below.

    Option Explicit

    Dim objFSO
    Dim objTextFile
    Dim winKey
    Dim officeKey
    Dim strFile
    Dim arrKeys
    Dim i

    Const ForReading = 1
    Const winCDLine = "Windows"
    Const officeCDLine = "Microsoft Office"
    Const noViso = "Visio"
    Const officeKeyReg = "offKey"
    Const winKeyReg = "winKey"


    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objTextFile = objFSO.OpenTextFile _
    ("keys.csv", ForReading)

    'Read the file into the array
    strFile = objTextFile.ReadAll
    arrKeys = Split(strFile, vbCrLf)

    For i = LBound(arrKeys) To UBound(arrKeys)
    'try to find the windows product key
    If(instr(arrkeys(i),winCDLine))Then
    winKey = getKey(arrKeys(i))
    writeReg winKey,winKeyReg
    End If
    'try to find the office product key
    If(InStr(arrKeys(i),noViso)) Then

    ElseIf(InStr(arrKeys(i),officeCDLine)) Then
    officeKey = getKey(arrKeys(i))
    writeReg officeKey,officeKeyReg
    End If
    Next

    Function getKey(strKeyLine)
    Dim temper
    Const KeyLoc = 2
    Const ProdLoc = 0

    temper = Split(strkeyLine,",")
    getKey = temper(prodloc) & "_" & temper(KeyLoc)

    End function


    Sub writeReg(strValue,StrValueName)

    Dim strComputer
    Dim oReg
    Dim wshShell

    Const HKEY_LOCAL_MACHINE = &H80000002
    Const strKeyPath = "SOFTWARE\TVG"
    Const strKeyPath64 = "SOFTWARE\Wow6432Node\TVG"
    Const is64Key = "SOFTWARE\Wow6432Node"

    strComputer = "."

    Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
    strComputer & "\root\default:StdRegProv")
    Set WshShell = WScript.CreateObject("WScript.Shell")

    'check for 64 bit
    If(OS64()) Then
    oReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath64
    oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath64,strValueName,strValue
    Else
    oReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath
    oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
    End If

    End Sub

    Function OS64()
    Dim objOS
    Dim colItems
    Dim objItem
    Dim strComputer

    strComputer = "."
    Set objOS = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
    Set colItems = objOS.ExecQuery("SELECT OSArchitecture FROM Win32_OperatingSystem")

    'this should fail on 32 bit XP
    On error resume next
    For Each objItem In colItems
    If(IsNull(objItem.OSArchitecture)) Then
    OS64 = False
    ElseIf(InStr(objItem.OSArchitecture,"64") > 0) Then
    OS64 = True
    Else
    OS64 = False
    End If
    Next
    On Error Goto 0

    'If(Error <> 0)) Then
    ' OS64 = False
    'End if
    End Function

    Also, dunno if this helps but this is the SQL for the License Checker that I run as a report. You can build it through the wizard but hey if this works as a copy paste into your environment, awesome, stop wasting time working on this.

    SELECT MACHINE.NAME AS SYSTEM_NAME, USER.FULL_NAME AS FIELD_26, OS_NAME, (SELECT MACHINE_CUSTOM_INVENTORY.STR_FIELD_VALUE FROM MACHINE_CUSTOM_INVENTORY WHERE MACHINE_CUSTOM_INVENTORY.ID=MACHINE.ID AND MACHINE_CUSTOM_INVENTORY.SOFTWARE_ID=24187) AS MACHINE_CUSTOM_INVENTORY_0_24187, (SELECT MACHINE_CUSTOM_INVENTORY.STR_FIELD_VALUE FROM MACHINE_CUSTOM_INVENTORY WHERE MACHINE_CUSTOM_INVENTORY.ID=MACHINE.ID AND MACHINE_CUSTOM_INVENTORY.SOFTWARE_ID=24456) AS MACHINE_CUSTOM_INVENTORY_0_24456, (SELECT MACHINE_CUSTOM_INVENTORY.STR_FIELD_VALUE FROM MACHINE_CUSTOM_INVENTORY WHERE MACHINE_CUSTOM_INVENTORY.ID=MACHINE.ID AND MACHINE_CUSTOM_INVENTORY.SOFTWARE_ID=24305) AS MACHINE_CUSTOM_INVENTORY_0_24305, (SELECT MACHINE_CUSTOM_INVENTORY.STR_FIELD_VALUE FROM MACHINE_CUSTOM_INVENTORY WHERE MACHINE_CUSTOM_INVENTORY.ID=MACHINE.ID AND MACHINE_CUSTOM_INVENTORY.SOFTWARE_ID=24186) AS MACHINE_CUSTOM_INVENTORY_0_24186 FROM MACHINE LEFT JOIN ASSET ON ASSET.MAPPED_ID = MACHINE.ID AND ASSET.ASSET_TYPE_ID=5 LEFT JOIN USER ON USER.ID = ASSET.OWNER_ID ORDER BY MACHINE_CUSTOM_INVENTORY_0_24186 desc, MACHINE_CUSTOM_INVENTORY_0_24187 desc, FIELD_26

    Cheers yall,
    -Phil - talkwithphil 10 years ago
  • What about SQL Will it pull an SQL key - annien1 9 years ago
  • Hi There, does this can work on newest K1000? I tried to do the office product key tracker. However, whenever I run the script all dependency was sent but the script unable to execute. Please help............ thank you in advanced - lovablemeila 8 years ago
  • Hi, I am a novice on K1000. I ran the script but found that it gave me fake product keys for Microsoft Office (MO) 2013 and 2016. I checked into ProduKey and it says that it doesn't support MO 2013 or 2016. Is there a way to get ProduKey to work with MO 2013 and 2016. Any suggestions would be helpful. Thank You. - JZeigler 6 years ago
  • Hi there, the skript works fine but it only shows the first Office Version that was found. So we have upgraded from Office 2007 to Office 2016 but it only shows the old Office 2007 Key. (On new mashines with only one Office 2016 Key it works fine) Can the script be extendet to show all found Office Keys in the Custom Inventory ? - BerghofGN 5 years ago
    • I do not have an answer for your question but I was wondering. Are you getting the correct Product keys for Office 2016? I couldn't get this script to give me correct product keys for Office 2013 or 2016. It would give me a product key, but it wasn't correct. - JZeigler 5 years ago
      • I believe Microsoft added more complexity to their Office product keys after 2010. It's very possible that the product keys you guys are seeing are not product keys, but "redemption" keys. I've never been successful at retrieving Office 2013 and up keys, only the redemption key and/or the last 5 characters of the actual key. Try running this command in a Windows command line, and analyze/compare your results:

        * Office 2013 (32-bit) on a 64-bit version of Windows

        cscript "C:\Program Files (x86)\Microsoft Office\Office15\OSPP.VBS" /dstatus

        * Office 2013 (64-bit) on a 64-bit version of Windows

        cscript "C:\Program Files\Microsoft Office\Office15\OSPP.VBS" /dstatus

        I'm assuming that the command is the same for Office 2016, just change the directory path to reflect 2016 (e.g. Office16 instead of Office15). - jcalvo@huntonbrady.com 5 years ago
  • I am a novice when it comes to scripting, but I get lost at one part of the instructions. It states, "Next thing we need to do is go to the scripting module and a new script.
    For script type select Online Shell Script.". How do I perform the aforementioned steps? I opened ProduKey.exe, ProduKey.chm, Text file, and Powershell. I couldn't find any option to create a new script or Online Shell Script. Please help! - anonymous_136850 5 years ago
    • That step is referring to what you do inside KACE itself. Are you using KACE? - JasonEgg 5 years ago
This post is locked
 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ