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
[link]http://www.nirsoft.net/utils/produkey.zip[/link]

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.
Answer Summary:
Cancel
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
This method works great on Windows XP, but it won't work on newer software versions such as Windows 7. Microsoft has changed the algorithm used to hide the product key in the registry.
Answered 12/01/2010 by: airwolf
Tenth Degree Black Belt

Please log in to comment
0
Thats why we use magic jelly bean to find the product keys for us. :)

Magic jelly bean is able to retrieve the product keys and save the information to a text file.

The VB script parses through that file and writes the Keys to the registry.

I've had success with office 2003 & 2007, winXP and 7 (32 and 64 bit).

Let me know if it works for you.
Answered 12/01/2010 by: dchristian
Red Belt

  • What modifications need to be made to use Magic Jellybean?
Please log in to comment
0
I wasn't aware that Magic Jelly Bean can finally decrypt the newer keys. Good to know!
Answered 12/01/2010 by: airwolf
Tenth Degree Black Belt

Please log in to comment
0
I used this and it was very succesful on most. I did have a win7 Machine that displayed BBBBB-BBBBB-BBBBB-BBBBB-BBBBB as the product key for Windows 7. I am using an MSDN issued retail key. Anyone else run into the same issue?

-Anthony
Answered 12/31/2010 by: awenzel@kace.com
Senior Purple Belt

Please log in to comment
0
Anthony,

Have you tried running magic jelly bean manually?
Answered 01/03/2011 by: dchristian
Red Belt

Please log in to comment
0
I have not tried it manually. I will try it though.
Answered 01/05/2011 by: awenzel@kace.com
Senior Purple Belt

Please log in to comment
0
For the most part it worked like a charm. Having a bit of trouble with obtaining the product key from Windows 7 machines. Returned nothing but B's I also tried the suggestion to run magic jelly bean manually on the local machine. Obviously I'm not doing something right. Thoughts?
Answered 01/17/2011 by: mtrainor
Senior Yellow Belt

Please log in to comment
0
I have been reading up on this.

I believe this is caused by the product key not being stored in the registry.

The main offender being volume licenses of Windows.
Answered 01/17/2011 by: dchristian
Red Belt

Please log in to comment
0
That was quick! I Windows 7 machine I ran this against was load with an OEM version. The same machine reported the office key just fine. I'll play around with this and see what kind of results I get on a larger sampling. Appreciate the quick response.
Answered 01/17/2011 by: mtrainor
Senior Yellow Belt

Please log in to comment
0
Thanks alot this worked perfectly. One thing i would like to know is how to add the Version of windows or Office to the report? Can a column be added that lists what version is installed on that machine?
Answered 01/31/2011 by: pmcguire
Senior Yellow Belt

Please log in to comment
0
I'm currently rewriting this to incorporate the version and office 2010.

Hope to post an update soon.
Answered 02/02/2011 by: dchristian
Red Belt

Please log in to comment
0
David,

Theoretically you would just need to modify the SQL Code. I currently have my DBA working on the SQL script. Assuming the client is installed (since we ran the script) we know what version the Operating System is along with what version of Office is installed.

From there we take the Computer Name, which is obtained when running the script, and query the database to see what Operating System and version of Office is installed.
Answered 02/02/2011 by: Capt.Morgan
Orange Belt

Please log in to comment
0
Technically you could do this for the OS version.
SELECT M.NAME, M.OS_NAME,
MCI.STR_FIELD_VALUE 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 OS_NAME, PRODUCT_KEY


But finding the Office is gonna be tricky because of all the entries.

I think the cleanest way to do it would be through the code.

If you get it first please share!
Answered 02/02/2011 by: dchristian
Red Belt

Please log in to comment
0
After a lot of trial and error and unexplainable issues we have finally produced a working query.

I used the KACE Software Inventory to determine what versions of Office we had installed so it would need to be modified for your environment.

SELECT M.NAME,
S.DISPLAY_NAME,
MCI.STR_FIELD_VALUE AS PRODUCT_KEY
FROM SOFTWARE S
LEFT JOIN MACHINE_SOFTWARE_JT ON (MACHINE_SOFTWARE_JT.SOFTWARE_ID = S.ID)
LEFT JOIN MACHINE M ON (M.ID = MACHINE_SOFTWARE_JT.MACHINE_ID)
LEFT JOIN MACHINE_CUSTOM_INVENTORY MCI ON (M.ID = MCI.ID)
WHERE ((S.DISPLAY_NAME = 'Microsoft Office Basic 2007'
or S.DISPLAY_NAME = 'Microsoft Office Basic Edition 2003'
or S.DISPLAY_NAME = 'Microsoft Office Professional 2007'
or S.DISPLAY_NAME = 'Microsoft Office Professional Plus 2007'
or S.DISPLAY_NAME = 'Microsoft Office Standard 2007'
or S.DISPLAY_NAME = 'Microsoft Office Ultimate 2007'
or S.DISPLAY_NAME = 'Microsoft Office XP Professional'
or S.DISPLAY_NAME = 'Microsoft Office XP Small Business'))
GROUP BY M.ID
ORDER BY DISPLAY_NAME asc, M.NAME asc


*** EDIT ***

Updated finally working query.
Answered 02/03/2011 by: Capt.Morgan
Orange Belt

Please log in to comment
2
Hey everybody.

I re-wrote the code to use a new tool (now a keyfinder from nirsoft).

This revision now pulls office 2010 keys and gives you the version of windows and office!

Make sure you go through everything again from the top because its all different.

Hope this helps, let me know if it works for you!

Thanks again to Vacuna for helping me put this together and for all your feedback.
Answered 02/14/2011 by: dchristian
Red Belt

  • dcchristian,
    I am trying to use your code to retrieve Office 2010 and windows product keys. But can't seem to find the updated code with keyfinder. Could you please repost the updated code?
    Do I just create a new shell script and run it? does the keyfinder.exe need to be specified with a path?

    would appreciate your response.
Please log in to comment
0
Hey Dave,

Every time I unzip the produkey.zip McAfee deletes it.

How sure are you of this product?

- Hamilton
Answered 02/14/2011 by: HMcWhorter
Orange Belt

Please log in to comment
0
Hamilton,

Nirsoft makes great products.

Most key finders / password recovery programs will set off AV.

Here is a link to nirsofts false positive page.
http://www.nirsoft.net/false_positive_report.html
Answered 02/15/2011 by: dchristian
Red Belt

Please log in to comment
0
Works great. Awesome job.
Answered 02/15/2011 by: Capt.Morgan
Orange Belt

Please log in to comment
0
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).


Hi,
Ive been trying to finish this but I think Im doing the above bit wrong. Would you be able to tell me exactly when in the script i do this?

Thanks in advance

Paddy
Answered 08/26/2011 by: paddyl
Orange Belt

Please log in to comment
0
Think Im doing this part wrong. Any help much appreciated. Thanks

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).
Answered 08/26/2011 by: paddyl
Orange Belt

Please log in to comment
0
This is going to be done under the scripting module in the kbox.

After adding a new script, change your script type to shell.

Towards the bottom of the page you'll see the script text.
Answered 08/26/2011 by: dchristian
Red Belt

Please log in to comment
0
David,
Thanks a million. Working perfectly now
Answered 08/31/2011 by: paddyl
Orange Belt

Please log in to comment
0
Beautiful Solution! It seems to be working good for me. Can you expound a little bit on the part where you said...

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.


How would you separate the Office version from the key in the registry?

Thanks.
Answered 10/04/2011 by: bruno71
Senior Yellow Belt

Please log in to comment
0
You could do this using custom inventory rules.

If you head over to inventory->software->add new.

There'll be a box for custom inventory.

Hit the gold question mark for an explanation on the syntax.

Your going to want to use a Registry Value Equals.

RegistryValueEquals(registryPath, valueName, value)
Answered 10/05/2011 by: dchristian
Red Belt

Please log in to comment
0
But since there is only 1 registry entry for the Office key, the value is stored as "Office Version Name_Product-Key" With the custom inventory rules, can you separate the value at the "_" ...?

Such as creating a software item for each version of Office...and then the custom inventory rule would be an IF statement.
For example: IF the_first_part_of_the_registry_value = "Office 2007 Professional Plus" THEN save_the_second_part_as_the_key

Is that possible? Or would something need to be done in the original script to make separate registry values for different versions of Office?
Answered 10/05/2011 by: bruno71
Senior Yellow Belt

Please log in to comment
3
If you don't care about the keys just use the "regular" software entries.

The custom inventory would be if you were creating a software for EACH key.

That way you could track the keys individually.
Answered 10/10/2011 by: dchristian
Red Belt

Please log in to comment
0
This is such a God send, you have no idea how much time this is going to save me! Thank you! Thank you! Thank you!

Dchristian you are the MAN!

-Brad
Answered 11/25/2011 by: billythekid45
Senior Yellow Belt

Please log in to comment
0

I have a question about this, this may be a dumb questions but do I need to enter any info into this script? I keep getting erro messages when I run the script

Answered 05/17/2013 by: bberry186
Second Degree Blue Belt

  • This content is currently hidden from public view.
    Reason: Removed by member request
    For more information, visit our FAQ's.
  • This content is currently hidden from public view.
    Reason: Removed by member request
    For more information, visit our FAQ's.
Please log in to comment
1

If I'm reading the later entries in this thread correctly, there's no way to natively extract the product key data without using a 3rd party app such as magic jellybean or nirsoft? I'm just trying to clarify if this is a script that will depend on a software title being present on the machine to work, or if the script will work without one of the 3rd party titles. Thanks!

Answered 05/17/2013 by: GeekSoldier
Red Belt

Please log in to comment
0

There is a simple VBScript only solution to get Win7 Keys

 

 'Constants for our registry query
const HKEY_LOCAL_MACHINE = &H80000002 
sRegistryKeyName = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
sRegistryValueName = "DigitalProductId"

function GetProductKey
	'Get the raw product key data 
	dim pValues()
	Set poRegistry=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
	poRegistry.GetBinaryValue HKEY_LOCAL_MACHINE,sRegistryKeyName,sRegistryValueName,pValues

	Dim sArrayPID
	sArrayPID = Array()

	'In that data, positions 52-66 contain our product id info
	'We copy to an array so we can decrypt

	For i = 52 to 66
		'Increase our array size by one
		ReDim Preserve sArrayPID( UBound(sArrayPID) + 1 )
		'Insert our value into the end if the array
		sArrayPID(UBound(sArrayPID)) = pValues(i)
	Next

	'Consants for our product key
	Dim sProductKeyChars
	sProductKeyChars = Array("B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9")

	For i = 24 To 0 Step -1
		k = 0
		For j = 14 To 0 Step -1
			k = k * 256 Xor sArrayPID(j)
			sArrayPID(j) = Int(k / 24)
			k = k Mod 24
		Next
		sProductKey = sProductKeyChars(k) & sProductKey
		'Adds the - between the key sections
		if i Mod 5 = 0 And i <> 0 Then sProductKey = "-" & sProductKey
	Next
	GetProductKey = sProductKey
end function

function GetOSVersion
	Set SystemSet = GetObject("winmgmts:").InstancesOf ("Win32_OperatingSystem") 
	for each System in SystemSet 
		GetOSVersion = Trim(System.Caption) & " (" & System.Version & ")"
	next 
end function 

wscript.echo GetOSVersion & ", " & GetProductKey
Answered 05/17/2013 by: jdornan
Red Belt

Please log in to comment
Answer this question or Comment on this question for clarity