Solved

Python code examples on how to read Windows Registry

Posted on 2010-11-17
20
2,656 Views
Last Modified: 2012-08-13
I need to write a Python script that will read and display to the screen or a file specified keys of the Windows Registry. How can I do this?
0
Comment
Question by:wayy2be
  • 13
  • 7
20 Comments
 
LVL 28

Expert Comment

by:pepr
ID: 34163052
There is the standard module called _winreg in Python -- see http://docs.python.org/library/_winreg.html
0
 
LVL 28

Expert Comment

by:pepr
ID: 34163153
Basically, it is a wrapper around the Windows API.  This way it should be used as Windows OS says it should be used.  If you have (say) a C++ code, you can easily rewrite it to Python.  Fortunately, the resulting code is much more brief.  Of course, you can write your own function that takes arguments as you need, and then it calls the _winreg functions.

See the sample below that reads the MDAC version from the registry.  It prints the following on my computer:

C:\tmp\___python\wayy2be\Q_26622655>python a.py
6.1.7600.16385
import _winreg

def getMDACversion():
    
    # Open the key and return the handle object.
    hKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 
                          "Software\\Microsoft\\DataAccess")
                          
    # Read the value.                      
    result = _winreg.QueryValueEx(hKey, "FullInstallVer")

    # Return only the value from the resulting tuple (value, type_as_int).
    return result[0]


print getMDACversion()

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 34163170
Sorry, I forgot to close the handle (the _winreg.CloseKey(hKey)).  See the corrected sample below.
import _winreg

def getMDACversion():
    
    # Open the key and return the handle object.
    hKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 
                          "Software\\Microsoft\\DataAccess")
                          
    # Read the value.                      
    result = _winreg.QueryValueEx(hKey, "FullInstallVer")

    # Close the handle object.
    _winreg.CloseKey(hKey)

    # Return only the value from the resulting tuple (value, type_as_int).
    return result[0]


print getMDACversion()

Open in new window

0
 

Author Comment

by:wayy2be
ID: 34164392
Thanks for the response. I am trying to have this script read the registry and scan the keys and print them. I need the script to read and cycle though several values, each are numbered like url1, url2 etc.  

# Read the value.                      
    result = _winreg.QueryValueEx(hKey, "FullInstallVer")

I can change the above to read the key url1, but how can I modify it to use a wildcard since we dont know how many keys will be there?
0
 
LVL 28

Expert Comment

by:pepr
ID: 34167947
Do you know where the values are located?  If yes, you can get more details about the key via the _winreg.QueryInfoKey() and access the values from inside via EnumValue(). See the snippet below.  It prints the following info on my computer (long url values shortened for brevity here):

C:\tmp\_Python\wayy2be\Q_26622655.html>python b.py
0 4
('url1', u'http://websearch.ask.com/redirect?client=...1FD75CEEBF33', 1)
('url2', u'http://partners.microsoft.com/', 1)
('url3', u'http://www.google.cz/', 1)
('url4', u'http://pctuning.tyden.cz/navody/upravy...-lets_dance_22?start=5', 1)
import _winreg

def printCurrentUserIETypedURLs():
    
    # Open the key and return the handle object.
    hKey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 
                           r'Software\Microsoft\Internet Explorer\TypedURLs')
                          #^ notice the 'r' here -- then backslashes need not 
                          #  to be doubled
                              
    # Get the information about the key.
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)
    print subkeyCnt, valuesCnt
    
    # Retrieve the value tuples (name, value, type).
    for n in xrange(valuesCnt):
        print _winreg.EnumValue(hKey, n)
        
    # Close the handle object.
    _winreg.CloseKey(hKey)


printCurrentUserIETypedURLs()

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 34167976
Try the above sample. Then you should specify your needs in more details.
0
 

Author Comment

by:wayy2be
ID: 34181575
That works, thanks. But how do I get the data when there are several user profiles on the box?  How can I make the script run through and list the data for each user? As  far as the code above can you explain how it works?  I am trying to learn Python.  Thanks for your great help!
0
 
LVL 28

Expert Comment

by:pepr
ID: 34185985
Well, the work with the registry is Windows specific and it is rather heavy handed with respect to how it could be implemented in Python. The Windows Registry consists of several trees.  Their roots are named with the well known identifiers (like HKEY_CURRENT_USER).  That tree identification is passed to OpenKey() as the first argument.  The HKEY_CURRENT_USER points to one of the subtrees of the tree HKEY_USERS.  This way, you want to process the users from inside that tree.  See http://technet.microsoft.com/en-us/library/cc976337.aspx for details.  The users are assigned so called Security ID that represents them.  When displayed as a string they look like "S-1-5-21-1000062535-2000000004-1488888878-1554".  If you find shorter SID's, they are probably related to system parts that may behave as users sometimes.

Run regedit program to look at your registry.

The
for n in xrange(valuesCnt):

Open in new window

is a for loop that is not typical for Python.  Rather, it is typical for C or C-family languages.  Here it generates a sequence 0, 1, ..., valuesCnt-1.  That value is assigned to the n variable.

The
_winreg.EnumValue(hKey, n)

Open in new window

returns tuple for the value at the index.  (Again, this is not typical name and behaviour for the Python.  It comes directly from the Windows OS kernel.)  The number of values was earlier found via the
_winreg.QueryInfoKey(hKey)

Open in new window

.
0
 
LVL 28

Expert Comment

by:pepr
ID: 34186000
Bad typesetting experiment.  Think about the "code" as about inlines in the above text.
0
 

Author Comment

by:wayy2be
ID: 34193450
I think I am missing it, especially the part where I can make the script display the data for each SID under that key....
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 28

Expert Comment

by:pepr
ID: 34194510
OK. Let's do it in steps.  Firstly, here is the modification (also function name changed).  Run the regedit.exe, unfold the HKEY_USERS and copy your SID to the argument of the function call below.  It should do the same thing that the above script for HKEY_CURRENT_USER.  Notice how the key in the registry is written in a string.  The earlier

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs

can be written in my case also as (there are decimal numerals instead of the x'es below)

HKEY_USERS\S-1-5-21-1xxxxxxxx5-2xxxxxxxx4-1xxxxxxxx8-1154\Software\Microsoft\Internet Explorer\TypedURLs

From that point of view, you can pass the SID (S-1-5-21-1xxxxxxxx5-2xxxxxxxx4-1xxxxxxxx8-1154) to the function and concatenate it with the '\Software\Microsoft\Internet Explorer\TypedURLs'.  The HKEY_USERS is a kind of concatenaded by the .OpenKey() method.

Try to understand that.  I will post soon the further step.
import _winreg

def theUserSID_IETypedURLs(sid):
    
    # Open the IE typed URLs for the sid and return the handle object.
    hKey = _winreg.OpenKey(_winreg.HKEY_USERS, 
                    sid + r'\Software\Microsoft\Internet Explorer\TypedURLs')
                              
    # Get the information about the key.
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)
    print subkeyCnt, valuesCnt
    
    # Retrieve the value tuples (name, value, type).
    for n in xrange(valuesCnt):
        print _winreg.EnumValue(hKey, n)
        
    # Close the handle object.
    _winreg.CloseKey(hKey)


theUserSID_IETypedURLs('S-1-5-21-1xxxxxxxx5-2xxxxxxxx4-1xxxxxxxx8-1154')

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 34194742
Now, let's retrieve the subkeys from the HKEY_USERS.  Not all of them are related to the users.
0
 
LVL 28

Expert Comment

by:pepr
ID: 34194815
(sorry, badly attached code)
import _winreg

def usersSubkeys():
    hKey = _winreg.OpenKey(_winreg.HKEY_USERS, '')
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)

    # Retrieve the subkeys.
    for n in xrange(subkeyCnt):
        print _winreg.EnumKey(hKey, n)
        
    _winreg.CloseKey(hKey)


usersSubkeys()

Open in new window

0
 
LVL 28

Expert Comment

by:pepr
ID: 34194838
Now the code that searches the URLs in all subkeys of the HKEY_USERS.  Not all subkeys are related to the users.  This means that they probably do not contain the urls.  The code below solves that via capturing the exception and throwing another.

The code below introduces also what is called a "generator function" in Python.  The function can be used for example in for loops and its usage behaves as generator of a sequence (each time one item).  The yield command instead of the return command is used inside the body of the function.

See below.  The userSIDs() actually does not return only the user's SIDs.  It returns also the other subkeys -- it is basically the same as the code in the upper example.  The difference is that it uses the yield instead of the print command.  Then it can be called in the for loop as here:

for sid in userSIDs():
    print sid

The theUserSID_IETypedURLs() was also modified to get the earlier behaviour.  Study the code and ask what are you interested in.

import _winreg

def theUserSID_IETypedURLs(sid):
    
    # Open the IE typed URLs for the sid and return the handle object. The list
    # of the URLs may not be present.  Try it and throw the StopIteration early
    # if no URL is there.
    try: 
        hKey = _winreg.OpenKey(_winreg.HKEY_USERS, 
                    sid + r'\Software\Microsoft\Internet Explorer\TypedURLs')
    except:
        raise StopIteration
                                
    # Get the information about the key.
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)
    print subkeyCnt, valuesCnt
    
    # Retrieve the value tuples (name, value, type).
    for n in xrange(valuesCnt):
        yield _winreg.EnumValue(hKey, n)[1]  # yield the url's only
        
    # Close the handle object.
    _winreg.CloseKey(hKey)


def userSIDs():   # this generator function should be enhanced
    hKey = _winreg.OpenKey(_winreg.HKEY_USERS, '')
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)

    # Generate the subkeys.
    for n in xrange(subkeyCnt):
        yield _winreg.EnumKey(hKey, n)  # notice the yield instead of return
        
    _winreg.CloseKey(hKey)


for sid in userSIDs():   # here the generator is used to get the SIDs
    print sid
    for url in theUserSID_IETypedURLs(sid):
        print ' ', url

Open in new window

0
 

Author Comment

by:wayy2be
ID: 34301260
Please note that this question is not abandoned. I was away for holiday.

pepr:  Thank you very much for the code, I will try it today and and test it. Thanks again for being very thorough and helpful in helping me understand the code and processes.
0
 
LVL 28

Expert Comment

by:pepr
ID: 34312506
No problem :)
0
 

Author Comment

by:wayy2be
ID: 34340035
pepr,

That works great!  Thank you. I am learning alot via this exercise!  Is there a way to covert the sid to the actual user name and what type of account it is (admin or regular user, local group membership etc)?

What books would you recommend I use to get really good at Python, I really enjoy it.

Thanks
0
 
LVL 28

Accepted Solution

by:
pepr earned 500 total points
ID: 34342623
This is less Python related and more MS Windows related.  I am not very good in it.  However, you should probably use the so called pywin32 extension (http://sourceforge.net/projects/pywin32/) by Mark Hammond (http://sourceforge.net/users/mhammond).  Then you should use the win32security module from that package.  If I recall correctly, the pywin32 was available as compiled binary installation earlier.  However, the sourceforge contains only the sources and you need to compile it using the MS Visual C++ (probably some free version will be sufficient -- I did not dig into details).  Or you may find the package precompiled elsewhere.  After successfull installation, try the following snippet:

import _winreg
import win32security

def theUserSID_IETypedURLs(sid):
    
    # Open the IE typed URLs for the sid and return the handle object. The list
    # of the URLs may not be present.  Try it and throw the StopIteration early
    # if no URL is there.
    try: 
        hKey = _winreg.OpenKey(_winreg.HKEY_USERS, 
                    sid + r'\Software\Microsoft\Internet Explorer\TypedURLs')
    except:
        raise StopIteration
                                
    # Get the information about the key.
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)
    print subkeyCnt, valuesCnt
    
    # Retrieve the value tuples (name, value, type).
    for n in xrange(valuesCnt):
        yield _winreg.EnumValue(hKey, n)[1]  # yield the url's only
        
    # Close the handle object.
    _winreg.CloseKey(hKey)


def userSIDs():   # this generator function should be enhanced
    hKey = _winreg.OpenKey(_winreg.HKEY_USERS, '')
    subkeyCnt, valuesCnt, modtime = _winreg.QueryInfoKey(hKey)

    # Generate the subkeys.
    for n in xrange(subkeyCnt):
        yield _winreg.EnumKey(hKey, n)  # notice the yield instead of return
        
    _winreg.CloseKey(hKey)


for sid in userSIDs():   # here the generator is used to get the SIDs
    print sid
    try:
        binsid = win32security.GetBinarySid(sid)                              # here ti convert textual SID to an object
        name, domain, type_id = win32security.LookupAccountSid(None, binsid)  # here you get the related info
        print (name, domain, type_id)       # I am lazy, so tuple formed to separate the values by commas and enclose in ()
        for url in theUserSID_IETypedURLs(sid):
            print ' ', url
    except:
        pass # ignore any error

Open in new window


You can see here that not every SID is related to a user.  I did not play further with that.  Also, you should probably get the users' SIDs from somewhere else.  The example here is rather dirty and uses mostly the trial/failure of various SIDs from HKEY_USERS.  The official documentation says that you should  search for SIDs in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList (see http://support.microsoft.com/kb/154599/EN-US/).
0
 

Author Comment

by:wayy2be
ID: 34452365
Actually I ran the code above without anything else and it worked very well!
0
 

Author Comment

by:wayy2be
ID: 34480445
Thanks for the help and for leading me in the right direction!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Installing Python 2.7.3 version on Windows operating system For installing Python first we need to download Python's latest version from URL" www.python.org " You can also get information on Python scripting language from the above mentioned we…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
Learn the basics of while and for loops in Python.  while loops are used for testing while, or until, a condition is met: The structure of a while loop is as follows:     while <condition>:         do something         repeate: The break statement m…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now