Solved

VB.NET WMI Enumerate Local Accounts / Profiles

Posted on 2006-06-29
4
1,390 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

734 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