Activate Windows 8 Pro in SCCM Task Sequence using key from BIOS MSDM table

UPDATED:

I got a tip from Guillaume in the comments that makes this a lot easier:

$key = wmic path softwarelicensingservice get oa3xoriginalproductkey

# Key is on the second line
$realkey = $key[2]

cscript //B “%windir%\system32\slmgr.vbs” -ipk $realkey
cscript //B “%windir%\system32\slmgr.vbs” -ato

 


I often deploy Windows 8 Pro to computers. SCCM 2012 does not have support for activating computers with key stored in BIOS.

To get around this problem we compiled an c++ application that extracts the key from the MSDM table in bios and created a simple PS-script to activate windows.

Compiled version of the application:

GetWin8Key.exe

C++ code:

// #include "stdafx.h"
#include "Windows.h"
#include
#include "stdio.h"

int _tmain(int argc, _TCHAR* argv[])
{
DWORD FirmwareTableProviderSignature;
PVOID pFirmwareTableBuffer;
DWORD BufferSize;
UINT BytesWritten;
DWORD FirmwareTableID;
DWORD *pFirmwareTableID;
BOOL foundTable = FALSE;
BOOL verbose = FALSE;

if (argc > 1) {
if (wcscmp(argv[1], _T("-v")) == 0)
verbose = TRUE;
}

FirmwareTableProviderSignature = 'ACPI';
pFirmwareTableBuffer = NULL;
BufferSize = NULL;

// get buffer size, call with null values
BufferSize = EnumSystemFirmwareTables(FirmwareTableProviderSignature,
NULL,
NULL);

// alloc memory
pFirmwareTableBuffer = malloc(BufferSize);

// enum acpi tables
BytesWritten = EnumSystemFirmwareTables(FirmwareTableProviderSignature,
pFirmwareTableBuffer,
BufferSize);

// enumerate ACPI tables, look for MSDM table
pFirmwareTableID = (DWORD*)pFirmwareTableBuffer;
for (int i = 0; i < BytesWritten/4; i++)
{
FirmwareTableID = *pFirmwareTableID;
if (verbose) printf("%.*sn", 4, pFirmwareTableID);
if (FirmwareTableID == _byteswap_ulong('MSDM')) {
if (verbose) printf("Found MSDM tablen");
foundTable = TRUE;
break;
}
pFirmwareTableID++;
}

if (foundTable) {
// get buffer size, call with null values
BufferSize = GetSystemFirmwareTable (FirmwareTableProviderSignature,
FirmwareTableID,
NULL,
NULL);
// alloc memory
pFirmwareTableBuffer = malloc(BufferSize);

BytesWritten = GetSystemFirmwareTable(FirmwareTableProviderSignature,
FirmwareTableID,
pFirmwareTableBuffer,
BufferSize);

/*
Table description form Miocrosoft at: http://go.microsoft.com/fwlink/p/?LinkId=234834

Microsoft Software Licensing Tables (SLIC and MSDM)
http://msdn.microsoft.com/library/windows/hardware/hh673514
Byte Byte
Field Lenght Offset Description
====== ===== ====== ===========
Signature 4 0 MSDM
Length 4 4 Length, in bytes, of the entire table.
Revision 1 8 0x01
Checksum 1 9 Checksum of the entire table.
OEMID 6 10 An OEM-supplied string that identifies the OEM.
OEM Table ID 8 16 Optional motherboard/BIOS logical identifier.
OEM Revision 4 24 OEM revision number of the table for the supplied OEM Table ID.
Creator ID 4 28 Vendor ID of the utility that created the table.
Creator Revision 4 32 Revision of the utility that created the table.
Software Licensing Structure Variable length 36 Proprietary data structure that contains all the licensing
data necessary to enable Windows activation.
Details can be found in the appropriate Microsoft OEM
licensing kit by first visiting the Microsoft OEM website
(http://www.microsoft.com/oem/pages/index.aspx).
*/

BYTE *Signature = (BYTE*)memset(malloc(4+1), NULL, 4+1);
UINT Length;
BYTE Revision;
BYTE Checksum;
BYTE *OEMID = (BYTE*)memset(malloc(6+1), NULL, 6+1);
BYTE *OEMTbleID = (BYTE*)memset(malloc(8+1), NULL, 8+1);
BYTE OEMRev;
BYTE *CreatorID = (BYTE*)memset(malloc(4+1), NULL, 4+1);
UINT CreatorRev;
UINT SLS_Size = BytesWritten - 36;
BYTE *SLS = (BYTE*)memset(malloc(SLS_Size), NULL, SLS_Size);
UINT SLS_Version;
UINT SLS_Reserved;
UINT SLS_DataType;
UINT SLS_DataReserved;
UINT SLS_DataLenght;
BYTE *ProductKey = (BYTE*)memset(malloc(30+1), NULL, 30+1);

memcpy_s(Signature, 4+1, (BYTE*)pFirmwareTableBuffer + 0, 4);
Length = *(DWORD*)((BYTE*)pFirmwareTableBuffer + 4);
Revision = *((BYTE*)pFirmwareTableBuffer + 8);
Checksum = *((BYTE*)pFirmwareTableBuffer + 9);
memcpy_s(OEMID, 6+1, (BYTE*)pFirmwareTableBuffer + 10, 6);
memcpy_s(OEMTbleID, 8+1, (BYTE*)pFirmwareTableBuffer + 16, 8);
OEMRev = *(DWORD*)((BYTE*)pFirmwareTableBuffer + 24);
memcpy_s(CreatorID, 4+1, (BYTE*)pFirmwareTableBuffer + 28, 4);
CreatorRev = *(DWORD*)((BYTE*)pFirmwareTableBuffer + 32);
memcpy_s(SLS, SLS_Size, (BYTE*)pFirmwareTableBuffer + 36, SLS_Size);
SLS_Version = *(DWORD*)((BYTE*)SLS);
SLS_Reserved = *(DWORD*)((BYTE*)SLS + 4);
SLS_DataType = *(DWORD*)((BYTE*)SLS + 8);
SLS_DataReserved = *(DWORD*)((BYTE*)SLS + 12);
SLS_DataLenght = *(DWORD*)((BYTE*)SLS + 16);
memcpy_s(ProductKey, SLS_DataLenght, (BYTE*)SLS + 20, SLS_DataLenght);

if (verbose) {
printf("Signature : %sn", Signature);
printf("Length : %dn", Length);
printf("Revision : %dn", Revision);
printf("Checksum : %dn", Checksum);
printf("OEMID : %sn", OEMID);
printf("OEM Table ID : %sn", OEMTbleID);
printf("OEM Revision : %dn", OEMRev);
printf("Creator ID : %sn", CreatorID);
printf("Creator Revision : %dn", CreatorRev);
printf("SLS Version : %dn", SLS_Version);
printf("SLS Reserved : %dn", SLS_Reserved);
printf("SLS Data Type : %dn", SLS_DataType);
printf("SLS Data Reserved : %dn", SLS_DataReserved);
printf("SLS Data Lenght : %dn", SLS_DataLenght);
printf("Key : %sn", ProductKey);
/*printf ("nnPress [Enter] to continue . . .");
fflush (stdout);
getchar();*/
} else {
printf("%s", ProductKey);
}
}

return 0;
}

Powershell-script to Activate:

################################
### GetWin8Key v1.0           ##
### By Christoffer Stolpestad ##
################################

$currentpath = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$key = .GetWin8Key.exe
cscript //B "%windir%\system32\slmgr.vbs" -ipk $key
cscript //B "%windir%\system32\slmgr.vbs" -ato

Comments

    1. I have never tried using it in a MDT-sequence but I can not see any reason why that should not work.
      Try creating an application, select source dir containing the script files and command line: powershell.exe -Command “set-ExecutionPolicy Unrestricted -Force; .GetWin8Key.ps1; set-ExecutionPolicy Restricted -Force”
      I’m actually not sure if you have to specify the full path for the script or not.

      Hope this was kind of helpful
      //Christoffer

  1. To run it silent i edited GetWin8Key.ps1
    cscript //B “c:windowssystem32slmgr.vbs” /ipk $key
    cscript //B “c:windowssystem32slmgr.vbs” /ato

    Add it as an application in MDT 2013 with command:
    powershell.exe -ExecutionPolicy Unrestricted -File .GetWin8Key.ps1 -NonInteractive

  2. Hi
    my laptop total crash and I must disassembly spi flash from motherboard =>first i’m saving old bios to BIN =>then programing other uefi bios from other (my model motherboard ersion) laptop from internet.. Uff =>laptop resurrection but I lost my windows 8 key and I can’t activation in other blocked key..

    how exctract from dump.BIN my oryginal W8 key ???

    thanks and best regards

  3. It may be specific to our environment but we are getting the key with the following command (example is with powershell):

    $key = wmic path softwarelicensingservice get oa3xoriginalproductkey

    # Key is on the second line
    $realkey = $key[2]

    cscript //B “%windir%\system32\slmgr.vbs” -ipk $realkey
    cscript //B “%windir%\system32\slmgr.vbs” -ato

    1. That is awesome!
      I don’t know how long this has been possible but that’s way easier 🙂
      Thank you for sharing!

Leave a Reply

Your email address will not be published. Required fields are marked *