Jump to content
EduGeek EdSec 2026 is Go! 27th Oct in Derby! Join us for a day of EdTech security focused talks, networking, and an evening social ×

Recommended Posts

Posted

I'm trying to read registry entries and append them to a text file (from a HTA app). I'd prefer not to call an external program (regedit or cmd). I'm having problems getting some of the extracted values to match.

 

This is one of the keys I am trying to extract:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1885954632-1506356648-996637233-11986]
"ProfileImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,44,00,72,\
 00,69,00,76,00,65,00,25,00,5c,00,44,00,6f,00,63,00,75,00,6d,00,65,00,6e,00,\
 74,00,73,00,20,00,61,00,6e,00,64,00,20,00,53,00,65,00,74,00,74,00,69,00,6e,\
 00,67,00,73,00,5c,00,73,00,77,00,69,00,6e,00,73,00,74,00,61,00,6c,00,6c,00,\
 00,00
"Sid"=hex:01,05,00,00,00,00,00,05,15,00,00,00,48,62,69,70,a8,2d,c9,59,31,7a,67,\
 3b,d2,2e,00,00
"Flags"=dword:00000000
"State"=dword:00000100
"CentralProfile"=""
"ProfileLoadTimeLow"=dword:dcd1fad3
"ProfileLoadTimeHigh"=dword:01c9e828
"Guid"="{7af97ce6-1ae2-49ce-8c84-ab4b503b16e3}"
"RefCount"=dword:00000000

 

And this is how it looks after my extraction:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\[s-1-5-21-1885954632-1506356648-996637233-11986]
"ProfileImagePath"=hex(2):
"Sid"=hex:
"Flags"=dword:0
"State"=dword:256
"CentralProfile"=""
"ProfileLoadTimeLow"=dword:-590218541
"ProfileLoadTimeHigh"=dword:30009384
"Guid"="{7af97ce6-1ae2-49ce-8c84-ab4b503b16e3}"
"RefCount"=dword:0

 

As you can see most of the values have been mangled. The "ProfileImagePath" and "Sid" are blank because the script returns a "Type Mismatch" error so I commented the code out. I'm not very proficient with VBS/HTA and have mostly hacked my script together with a lot of help from Google so far. My problem is with extracting and appending registry value types properly. This is my code:

objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes

For i=0 To UBound(arrValueNames)
objRegFile.Write """" & arrValueNames(i) & """="
Select Case arrValueTypes(i)
	Case REG_SZ
		objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue
		objRegFile.WriteLine """" & strValue & """"
	Case REG_EXPAND_SZ ' AKA hex(2)
		'objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue ' Type mismatch here
		objRegFile.WriteLine "hex(2):" & strValue
	Case REG_BINARY ' AKA hex
		'objRegistry.GetBinaryValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue ' Type mismatch here
		objRegFile.WriteLine "hex:" & strValue
	Case REG_DWORD
		objRegistry.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue
		objRegFile.WriteLine "dword:" & strValue
	Case REG_MULTI_SZ ' AKA hex(7)
		objRegistry.GetMultiStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue
		objRegFile.WriteLine "hex(7):" & strValue
End Select 
Next

 

Any help much appreciated.

Posted

Here you go. Please be aware it's still "rough" and needs tidying up. I have quite a few debug message boxes in there and some comments to myself. I still need to implement some error checking and a restore subroutine, and I may also split some code off from the "BackupProfile" subroutine into their own subs for reusability...

 

The idea is to be able to backup and restore local profiles without staff being present - until we get them onto network storage that is. To do that I need to get some info out of some registry keys (thanks to srochford for telling me which keys and which info is needed). I thought I'd try and automate it all in one script...

 

<br />
	' Ignore any errors<br />
	On Error Resume Next<br />
<br />
	' define some constants<br />
	Const HKEY_LOCAL_MACHINE = &H80000002<br />
	Const STR_GUID_PATH = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid"<br />
	Const ROOT_PROFILE_PATH = "HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\"<br />
	Const SID_STRING = "SidString"<br />
	Const REG_SZ = 1<br />
	Const REG_EXPAND_SZ = 2<br />
	Const REG_BINARY = 3<br />
	Const REG_DWORD = 4<br />
	Const REG_MULTI_SZ = 7<br />
	strComputer = "."<br />
<br />
	Dim arrProfiles()<br />
<br />
Sub Window_Onload<br />
	'window.resizeTo 640,480 'Causes errors - there is a known workaround I need to implement<br />
	GetProfiles()<br />
End Sub<br />
<br />
Function GetProfiles<br />
	output_area.innerHTML = ""<br />
	' Create a shell<br />
	Set WSHShell = CreateObject("WScript.Shell") <br />
	<br />
	' Open the Registry<br />
	Set objRegistry=GetObject("winmgmts:\\.\root\default:StdRegProv")<br />
	<br />
	' Extract the ProfileGUID entries from the registry returned in arrGUIDs<br />
	objRegistry.EnumKey HKEY_LOCAL_MACHINE, STR_GUID_PATH, arrGUIDs<br />
	 <br />
	' Process each of the entries in the ProfileGUID<br />
	intX = 0<br />
	For Each objSubkey In arrGUIDs<br />
	<br />
	    ' Extract the SID from the GUID entry<br />
		strRegPath = STR_GUID_PATH & "\" & objSubkey<br />
	    objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, strRegPath, SID_STRING, sidString<br />
	<br />
		' Extract the profile path from the ProfileList sub tree in the registry relating to the current GUID / SID<br />
		strProfileRegPath = ROOT_PROFILE_PATH & sidString<br />
		strRegKey = strProfileRegPath & "\ProfileImagePath"<br />
		strProfilePath = WSHShell.RegRead (strRegKey)<br />
		<br />
		' Replace %systemdrive% with "c:"<br />
		strProfilePath = replace(strProfilePath,"%SystemDrive%","C:")<br />
		<br />
		' Extract username from profilePath<br />
		strUsername = Right(strProfilePath, Len(strProfilePath)-InStrRev(strProfilePath,"\"))<br />
		<br />
		' might need to drop "STAFF" from end of user name, add code here<br />
		<br />
		' validity checking goes here<br />
		' exclude IT support from back-up<br />
		' exclude profiles of users no longer on the network<br />
		' exclude profiles of users who last used the system >= 3 months ?<br />
		<br />
		' Put profile information into an array<br />
		ReDim Preserve arrProfiles(intX)<br />
		' Comma delimeted data, use "Split" to recover<br />
		arrProfiles(intX) = strUsername & "," & objSubkey & "," & sidString & "," & strProfileRegPath & "," & strProfilePath<br />
		<br />
		' Create mutually exclusive radio buttons for the profile names<br />
		output_area.innerHTML = output_area.innerHTML & "<input type=""radio"" name=""ProfileOption"" value=""" & intX & """>" & strUsername & "<br><br>"<br />
		intX = intX + 1<br />
	Next<br />
	output_area.innerHTML = output_area.innerHTML & "<input id=runbutton  class=""button"" type=""button"" value=""Backup"" name=""backup_button""  onClick=""BackupProfile"">"<br />
End Function<br />
<br />
Sub BackupProfile<br />
	For Each objOption In ProfileOption<br />
		If objOption.Checked Then<br />
			'output_area.innerHTML = "<br>" & objOption.value & " chosen<br>" ' Debug<br />
			strChosenProfile = objOption.value<br />
		End If<br />
	Next<br />
	<br />
	' Use strChosenProfile to select the correct data from arrProfiles<br />
	arrProfile = Split(arrProfiles(strChosenProfile),",")<br />
	strUsername = arrProfile(0)<br />
	strGUID = arrProfile(1)<br />
	strSID = arrProfile(2)<br />
	strProfileRegPath = arrProfile(3)<br />
	strProfilePath = arrProfile(4)<br />
	<br />
	'debug<br />
	output_area.innerHTML = "Debug Message:<br>" & strUsername & "<br>" & strGUID & "<br>" & strSID & "<br>" & strProfileRegPath & "<br>" & strProfilePath<br />
	<br />
	' code to export Profile Registry Entries<br />
	Set objShell = CreateObject("WScript.Shell")<br />
	Set objFSO = CreateObject("Scripting.FileSystemObject")<br />
	<br />
	strScriptPath = location.pathname 'Full path to script<br />
		<br />
	MsgBox strScriptPath,0, "strScriptPath" 'Debug<br />
	<br />
	Set objFile = objFSO.GetFile(strScriptPath)<br />
<br />
	strScriptFolder = objFSO.GetParentFolderName(objFile) ' Folder where script located<br />
	<br />
	MsgBox strScriptFolder,0, "strScriptFolder" 'Debug<br />
	<br />
	strRootBackupFolder = strScriptFolder & "\Backups"<br />
	strProfileBackupFolder = strRootBackupFolder & "\" & strUsername<br />
	strBackupRegFile = strUsername & ".reg"<br />
	<br />
	MsgBox strProfileBackupFolder,0, "strProfileBackupFolder" 'Debug<br />
	MsgBox strBackupRegFile,0, "strBackupRegFile" 'Debug<br />
	<br />
	' Create "Backup" folder if it doesn't already exist<br />
	If objFSO.FolderExists(strRootBackupFolder) Then<br />
		Set objBackupFolder = objFSO.GetFolder(strRootBackupFolder)<br />
		MsgBox strRootBackupFolder & " already created " ' Debug<br />
	Else<br />
		Set objBackupFolder = objFSO.CreateFolder(strRootBackupFolder)<br />
		MsgBox "Just created " & strRootBackupFolder' Debug<br />
	End If<br />
	' Create folder for profilename<br />
	If objFSO.FolderExists(strProfileBackupFolder) Then<br />
		Set objBackupFolder = objFSO.GetFolder(strProfileBackupFolder)<br />
		MsgBox strProfileBackupFolder & " already created " ' Debug<br />
	Else<br />
		Set objBackupFolder = objFSO.CreateFolder(strProfileBackupFolder)<br />
		MsgBox "Just created " & strProfileBackupFolder' Debug<br />
	End If<br />
	<br />
	' Create registry backup file<br />
	' ProfileGuid bit:<br />
	Set objRegFile = objFSO.CreateTextFile(strProfileBackupFolder & "\" & strBackupRegFile, True, True)<br />
	objRegFile.WriteLine "Windows Registry Editor Version 5.00"<br />
	objRegFile.WriteBlankLines(1)<br />
	MsgBox "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid\" & strGUID & "]" ' Debug<br />
	objRegFile.WriteLine "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGuid\" & strGUID & "]"<br />
	objRegFile.WriteLine """SidString""=""" & strSID & """"<br />
	objRegFile.WriteBlankLines(1)<br />
	<br />
	Dim arrValueNames<br />
	Dim arrValueTypes<br />
	'ProfileList bit:<br />
	objRegFile.WriteLine "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\[" & strSID & "]"<br />
	MsgBox "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\[" & strSID & "]" ' Debug<br />
	<br />
	Set objRegistry=GetObject("winmgmts:\\.\root\default:StdRegProv")<br />
	'Set objRegistry=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")<br />
<br />
	strKeyPath = ROOT_PROFILE_PATH & strSID ' Includes "HKLM\" - need to remove<br />
	MsgBox "strKeyPath:" & strKeyPath 'Debug<br />
	'strKeyPath = Right(strKeyPath, len(strKeyPath)-InStr(strKeyPath,"\"))<br />
	strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" & "\" & strSID ' Debug<br />
	MsgBox "strKeyPath:" & strKeyPath 'Debug<br />
	<br />
	MsgBox "HKLM: " & HKEY_LOCAL_MACHINE & vbCrLf & "strKeyPath: " & strKeyPath & vbCrLf & "arrValueNames: " & arrValueNames & vbCrLf & "arrValueTypes: " & arrValueTypes 'Debug<br />
	objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes<br />
	<br />
	For i=0 To UBound(arrValueNames)<br />
		objRegFile.Write """" & arrValueNames(i) & """="<br />
		Select Case arrValueTypes(i)<br />
			Case REG_SZ<br />
				objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue<br />
				objRegFile.WriteLine """" & strValue & """"<br />
			Case REG_EXPAND_SZ ' AKA hex(2)<br />
				'objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue<br />
				objRegFile.WriteLine "hex(2):" & strValue<br />
			Case REG_BINARY ' AKA hex<br />
			    'objRegistry.GetBinaryValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue<br />
			    objRegFile.WriteLine "hex:" & strValue<br />
			Case REG_DWORD<br />
				objRegistry.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue<br />
				objRegFile.WriteLine "dword:" & strValue<br />
			Case REG_MULTI_SZ ' AKA hex(7)<br />
				objRegistry.GetMultiStringValue HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames(i), strValue<br />
				objRegFile.WriteLine "hex(7):" & strValue<br />
		End Select <br />
	Next<br />
	<br />
	objRegFile.Close<br />
	Set objRegFile = Nothing<br />
	<br />
	' Code to back up user data goes here<br />
	' Call MS's Backup with the profile name?<br />
	' Something like:<br />
	' %SystemRoot%\system32\ntbackup.exe backup "C:\Documents and Settings\profilename" /j "profilename backup" /f "logical disk path and filename.bkf" /v:yes /r:no /l:s /hc:on<br />
	' If I use that, don't want temp files and any other useless crap<br />
End Sub<br />
<br />




Profile Backup

     APPLICATIONNAME="ProfileBackup"
    SCROLL="yes"
    SINGLEINSTANCE="yes"
 VERSION="0.1"
 SINGLEINSTANCE="yes"
 SYSMENU="yes"
>




Please choose a profile to backup






Posted

Ok, I've just skimmed it and is there any reason why you want to export the information out as how regedit would export it out? That is:

 

"ProfileImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,44,00,72,\
 00,69,00,76,00,65,00,25,00,5c,00,44,00,6f,00,63,00,75,00,6d,00,65,00,6e,00,\
 74,00,73,00,20,00,61,00,6e,00,64,00,20,00,53,00,65,00,74,00,74,00,69,00,6e,\
 00,67,00,73,00,5c,00,73,00,77,00,69,00,6e,00,73,00,74,00,61,00,6c,00,6c,00,\
 00,00
"Sid"=hex:01,05,00,00,00,00,00,05,15,00,00,00,48,62,69,70,a8,2d,c9,59,31,7a,67,\
 3b,d2,2e,00,00
"Flags"=dword:00000000

 

Are you planning on using another application to do something else with the data? Could you not just have say ProfileImagePath="c:\documents and settings\user"?

Posted
I'd rather not use regedit to export the data. I think I've narrowed the problem down to the way I handle the data types. I think using "strValue" for each data type isn't going to work, I think I need to do some conversion to and from Long/Hex/Binary...
Posted
I'd rather not use regedit to export the data. I think I've narrowed the problem down to the way I handle the data types. I think using "strValue" for each data type isn't going to work, I think I need to do some conversion to and from Long/Hex/Binary...

 

My point is why are you trying export the information out as tho it was exported from regedit for example you could have the info exported as:

 

ProfileImagePath="c:\documents and settings\user"

 

Instead of what you are trying to do right now which is:

 

"ProfileImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,44,00,72,\
 00,69,00,76,00,65,00,25,00,5c,00,44,00,6f,00,63,00,75,00,6d,00,65,00,6e,00,\
 74,00,73,00,20,00,61,00,6e,00,64,00,20,00,53,00,65,00,74,00,74,00,69,00,6e,\
 00,67,00,73,00,5c,00,73,00,77,00,69,00,6e,00,73,00,74,00,61,00,6c,00,6c,00,\
 00,00

Posted
My point is why are you trying export the information out as tho it was exported from regedit for example you could have the info exported as:

 

ProfileImagePath="c:\documents and settings\user"

 

I haven't tested this, I thought I'd have to keep the data in the same format...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...