Solved

VB.NET WMI Enumerate Local Accounts / Profiles

Posted on 2006-06-29
4
1,361 Views
Last Modified: 2012-06-27
I need a VB.NET WMI function to return a list of local profiles on a machine.  The machine will be connected to a domain, but i dont need domain information, just a list of who has a profile on that perticular machine.  Can someone please help me with this function, I have been trying for days to produce one myself but I am getting nowhere fast as I am very new to WMI programming, and I am running out of time even faster for this project to be completed.  

The end result of the function: I wish to add to a listbox the names of the profiles found on the machine. This code will be run from the machine locally.
0
Comment
Question by:UFIT-TSS
  • 2
  • 2
4 Comments
 
LVL 41

Expert Comment

by:graye
Comment Utility
WMI probably isn't a good tool for doing this... the closest you'll find is the Win32_Desktop class, which will give you the "desktop settings" for the users.  However, it will only look at the profiles that are currently loaded.  So if a PC is shared by several people, you'll only get the current user (and a bunch of system-level users).

An easier (and more accurate) way would be to look at the registry.  Here is a chunk of code that will give you an idea of how to do what you want.  (it's just a cut-n-paste, so they'll be things missing, and tons of stuff in the sample you should ignore)

    '
    ' Get information about the User Profiles and mount all of the User's
    ' registry hives.
    ' Note: The registry hives mounted here are used in: GetEmail, GetInternet,
    ' GetMapped, GetShares, and GetStartup.  We do not update the "reference
    ' count" for the hive, so it's possible that some other program might
    ' umount the hive before we read from it.
    '
    Public Sub GetProfiles()
        If IsWin32 Then
            Dim DefaultUserProfile, keyname, ImagePath, ProfileName, UserID, LoadedHives() As String
            Dim key, subkey, testkey As RegistryKey
            Dim flags, num_users As Integer
            Dim ld As LongDate
            Dim RawSID() As Byte
            Dim admin, we_mounted_it As Boolean
            Dim dr As SOSOSDataSet.ProfilesRow

            ImagePath = ""
            keyname = ""
            Try
                ' the mounting of registry hives is a tightly held privilege
                ' that is not enabled by default (even for administrators)
                admin = Misc.IsAdmin()

                ' make a list of hives that are currently loaded
                LoadedHives = reg_hku.GetSubKeyNames

                ' get the listing of profiles from the registry
                key = reg_hklm.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList", False)
                If Not IsNothing(key) Then
                    ' loop thru each subkey
                    num_users = 0
                    For Each keyname In key.GetSubKeyNames
                        subkey = key.OpenSubKey(keyname, False)
                        flags = CInt(subkey.GetValue("Flags", -1))

                        ' we only want "human" profiles (WinNT doesn't have
                        ' this flag, but it also doesn't list non-human keys)
                        If flags = 0 Or OSVer = 4.0 Then
                            num_users += 1
                            ImagePath = subkey.GetValue("ProfileImagePath", "").ToString
                            ' We have to substitute the values for our expanded
                            ' enivronmental variables with those of the remote
                            ' PC!
                            If RemotePC <> "" Then
                                ImagePath = ImagePath.Replace(Environment.ExpandEnvironmentVariables("%SystemRoot%"), SystemRoot)
                            End If
                            If Directory.Exists(Misc.ConvUNC(RemotePC, ImagePath)) Then
                                ld.date_hi = CInt(subkey.GetValue("ProfileLoadTimeHigh", 0))
                                ld.date_lo = CInt(subkey.GetValue("ProfileLoadTimeLow", 0))
                                RawSID = CType(subkey.GetValue("SID", Nothing), Byte())
                                ProfileName = Path.GetFileName(ImagePath)
                                If Not IsNothing(RawSID) Then
                                    UserID = Misc.SidToName(RemotePC, RawSID)
                                Else
                                    ' If we don't have an imbedded SID, then we
                                    ' use the key name instead
                                    UserID = Misc.SidToName(RemotePC, keyname)
                                End If

                                ' Let's mount the user's hive (if it isn't
                                ' already mounted)
                                we_mounted_it = False
                                If admin AndAlso Array.IndexOf(LoadedHives, keyname) < 0 Then
                                    ' Since we're doing this remotely, the path
                                    ' to the hive is relative to the remote PC
                                    If Misc.MountHive(RemotePC, keyname, ImagePath & "\NTUSER.DAT") = 0 Then
                                        we_mounted_it = True
                                        ' we tag the ones that we mounted with
                                        ' an asterisk
                                        ProfileList.Add(ImagePath, "*" & keyname)
                                    End If
                                End If

                                dr = ds.Profiles.NewProfilesRow
                                dr.ID_Profile = ID
                                dr.Profile = Left(ProfileName, ds.Profiles.ProfileColumn.MaxLength)
                                dr.Profile_Path = Left(ImagePath, ds.Profiles.Profile_PathColumn.MaxLength)
                                If UserID <> "" Then
                                    dr.Profile_Owner = Left(UserID, ds.Profiles.Profile_OwnerColumn.MaxLength)
                                End If

                                If OSVer = 4.0 Or admin = False Then
                                    ' This is a bit crude, but it's better than
                                    ' nothing
                                    dr.Profile_IsAdmin = False
                                    If Not IsNothing(ds.Admins.FindByID_AdminAdmin_UserID(ID, UserID)) Then
                                        dr.Profile_IsAdmin = True
                                    End If
                                Else
                                    dr.Profile_IsAdmin = Misc.IsRemoteAdmin(MachineName, reg_hku, UserID)
                                End If
                                If ld.Long64 > 0 Then
                                    ' Not supported in WinNT or WinVista
                                    dr.Profile_LastLoad = Date.FromFileTime(ld.Long64)
                                End If
                                ds.Profiles.AddProfilesRow(dr)

                                ' Let's do a "test run" to verify that the
                                ' hive got mounted and that current user has
                                ' permission to read it.  We do this here
                                ' rather than in each one of the "dependent"
                                ' methods.
                                Try
                                    testkey = reg_hku.OpenSubKey(keyname & "\Control Panel", False)
                                    If Not IsNothing(testkey) Then
                                        testkey.Close()
                                    End If
                                    If we_mounted_it = False Then
                                        ProfileList.Add(ImagePath, keyname)
                                    End If
                                Catch
                                    ' if this test fails, then this key
                                    ' won't appear in the ProfileList
                                End Try
                            End If
                        End If
                        subkey.Close()
                    Next

                    DefaultUserProfile = key.GetValue("DefaultUserProfile", "Default User").ToString
                    key.Close()

                    ' Update the PC table's NumUser field
                    If ds.PC.Count > 0 Then
                        ds.PC(0).PC_NumUsers = num_users
                    End If

                    ' manually create an entry for the Default User
                    If ds.Profiles.Count > 0 Then
                        Dim parts() As String

                        dr = ds.Profiles.NewProfilesRow
                        dr.ID_Profile = ID
                        dr.Profile = DefaultUserProfile

                        ' use an existing entry as a prototype
                        parts = ds.Profiles(0).Profile_Path.Split("\"c)
                        parts(parts.Length - 1) = DefaultUserProfile
                        ImagePath = Join(parts, "\")
                        dr.Profile_Path = Left(ImagePath, ds.Profiles.Profile_PathColumn.MaxLength)
                        dr.Profile_IsAdmin = False
                        ds.Profiles.AddProfilesRow(dr)

                        we_mounted_it = False
                        If admin AndAlso Array.IndexOf(LoadedHives, DefaultUserProfile) < 0 Then
                            ' Since we're doing this remotely, the path
                            ' to the hive is relative to the remote PC
                            If Misc.MountHive(RemotePC, DefaultUserProfile, ImagePath & "\NTUSER.DAT") = 0 Then
                                we_mounted_it = True
                                ' we tag the ones that we mounted with
                                ' an asterisk
                                ProfileList.Add(ImagePath, "*" & DefaultUserProfile)
                            End If
                        End If
                    End If
                End If
            Catch ex As Exception
                dr = ds.Profiles.NewProfilesRow
                dr.ID_Profile = ID
                dr.Profile = "Error"
                dr.Profile_IsAdmin = False
                dr.Profile_Path = Left("Error: " & ex.Message, ds.Profiles.Profile_PathColumn.MaxLength)
                ds.Profiles.AddProfilesRow(dr)
                Misc.ErrorLog(ex, MachineName, "Profiles", Misc.ErrLogLevel.Errors)
            End Try
        End If
    End Sub
0
 

Author Comment

by:UFIT-TSS
Comment Utility
I think that I may be able just to use a file system object to collect the names of the folders in the Documents and Settings folder. Anyone know how to do that?
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
Comment Utility
Yep, that works too :)

There's a couple of "gotcha's"...  You'll get profiles for machine accounts, You'll get the name of the account as it existed when the profile was created (so if a user name has changed, it will not be reflected in the directory name)

http://msdn2.microsoft.com/en-us/library/6ff71z1w.aspx
0
 

Author Comment

by:UFIT-TSS
Comment Utility
That works good enough for what i need, thank you for the help. Sometimes there is just an easier way to do something with a little creative thinking.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

772 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

11 Experts available now in Live!

Get 1:1 Help Now