/build/static/layout/Breadcrumb_cap_w.png

HOW TO: Track Windows and Office Product keys

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.

0 Comments   [ + ] Show comments

Answers (30)

Answer Summary:
Posted by: dchristian 12 years ago
Red Belt
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.
Posted by: dchristian 13 years ago
Red Belt
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.

Comments:
  • 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. - sangeeta2013 10 years ago
Posted by: GeekSoldier 10 years ago
Red Belt
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!

Posted by: airwolf 13 years ago
Red Belt
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.
Posted by: dchristian 13 years ago
Red Belt
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.

Comments:
  • What modifications need to be made to use Magic Jellybean? - toucan911 11 years ago
Posted by: airwolf 13 years ago
Red Belt
0
I wasn't aware that Magic Jelly Bean can finally decrypt the newer keys. Good to know!
Posted by: awenzel@kace.com 13 years ago
Senior Purple Belt
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
Posted by: dchristian 13 years ago
Red Belt
0
Anthony,

Have you tried running magic jelly bean manually?
Posted by: awenzel@kace.com 13 years ago
Senior Purple Belt
0
I have not tried it manually. I will try it though.
Posted by: mtrainor 13 years ago
Senior Yellow Belt
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?
Posted by: dchristian 13 years ago
Red Belt
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.
Posted by: mtrainor 13 years ago
Senior Yellow Belt
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.
Posted by: pmcguire 13 years ago
Senior Yellow Belt
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?
Posted by: dchristian 13 years ago
Red Belt
0
I'm currently rewriting this to incorporate the version and office 2010.

Hope to post an update soon.
Posted by: Capt.Morgan 13 years ago
Orange Belt
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.
Posted by: dchristian 13 years ago
Red Belt
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!
Posted by: Capt.Morgan 13 years ago
Orange Belt
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.
Posted by: HMcWhorter 13 years ago
Orange Belt
0
Hey Dave,

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

How sure are you of this product?

- Hamilton
Posted by: dchristian 13 years ago
Red Belt
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
Posted by: Capt.Morgan 13 years ago
Orange Belt
0
Works great. Awesome job.
Posted by: paddyl 12 years ago
Orange Belt
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
Posted by: paddyl 12 years ago
Orange Belt
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).
Posted by: dchristian 12 years ago
Red Belt
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.
Posted by: paddyl 12 years ago
Orange Belt
0
David,
Thanks a million. Working perfectly now
Posted by: bruno71 12 years ago
Senior Yellow Belt
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.
Posted by: dchristian 12 years ago
Red Belt
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)
Posted by: bruno71 12 years ago
Senior Yellow Belt
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?
Posted by: billythekid45 12 years ago
Senior Yellow Belt
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
Posted by: bberry186 10 years ago
Second Degree Blue Belt
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


Comments:
Posted by: jdornan 10 years ago
Red Belt
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
Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Don't be a Stranger!

Sign up today to participate, stay informed, earn points and establish a reputation for yourself!

Sign up! or login

View more:

Share

 
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