Solved

VB.NET WMI Enumerate Local Accounts / Profiles

Posted on 2006-06-29
4
1,377 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
ID: 17017633
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
ID: 17018057
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
ID: 17018526
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
ID: 17041984
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

777 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