Solved

a Script to retrieve user profile name

Posted on 2009-07-08
10
561 Views
Last Modified: 2012-05-07
a Script to retrieve user profile name
I am looking for a script that ca retrieve the name of the user profile created on the workstation.
workstations are members of the domain and users have an account in the domain.

Sometimes when looking into C:\Documents and Settings, you can see username by itself and sometimes username.domainname.

it's hard to know which one is the user using.

Thanks
0
Comment
Question by:jskfan
  • 5
  • 4
10 Comments
 
LVL 1

Expert Comment

by:tojo2k
ID: 24805857
Is the user logged in?  The profile will be in an environment variable called USERPROFILE for each user.
0
 
LVL 3

Expert Comment

by:cmorbach
ID: 24806125
I modified this for you in VB.net to retrieve a list of all local users together with their profile:
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_21919448.html

See code:

The attached file contains the compiled binary - rename txt to exe - if you dont have vb.net installed.
Form:
 

Public Class Form1
 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim buf, ans As String

        Dim lp As New ListProfiles
 

        ans = ""

        ' Get profiles for the local PC

        For Each buf In lp.GetProfiles("")

            ans &= buf & vbCr

        Next
 

        MsgBox(ans)
 

    End Sub

End Class
 
 
 
 
 
 

Class:
 

Imports Microsoft.Win32

Imports System.Collections.Specialized

Imports System.Runtime.InteropServices
 
 

Public Class ListProfiles
 

    'BOOL LookupAccountSid(

    '  LPCTSTR lpSystemName,

    '  PSID lpSid,

    '  LPTSTR lpName,

    '  LPDWORD cchName,

    '  LPTSTR lpReferencedDomainName,

    '  LPDWORD cchReferencedDomainName,

    '  PSID_NAME_USE peUse

    ');

    Private Declare Auto Function LookupAccountSid Lib "advapi32.dll" ( _

        ByVal lpSystemName As String, _

        ByVal lpSid As IntPtr, _

        ByVal lpName As String, _

        ByRef cchName As Integer, _

        ByVal lpReferenceDomainName As String, _

        ByRef cchReferencedDomainName As Integer, _

        ByRef peUse As Integer _

    ) As Boolean
 

    'BOOL ConvertStringSidToSid(

    '  LPCTSTR StringSid,

    '  PSID* Sid

    ');

    Private Declare Auto Function ConvertStringSidToSid Lib "advapi32.dll" ( _

        ByVal StringSid As String, _

        ByRef Sid As IntPtr _

    ) As Boolean
 

    'BOOL ConvertSidToStringSid(

    '  PSID Sid,

    '  LPTSTR* StringSid

    ');

    Private Declare Auto Function ConvertSidToStringSid Lib "advapi32.dll" ( _

        ByVal Sid As IntPtr, _

        ByRef StringSid As IntPtr _

    ) As Boolean
 

    Private Const NAME_SIZE As Integer = 64
 

    Public Function GetProfiles(ByVal RemotePC As String) As StringCollection

        Dim ans As New StringCollection

        Dim reg_hklm, key, subkey As RegistryKey

        Dim keyname, UserID As String

        Dim RawSID() As Byte

        Dim RawProfile As String
 

        ' open the registry (could be remote)

        If RemotePC <> "" Then

            reg_hklm = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, RemotePC)

        Else

            reg_hklm = Registry.LocalMachine

        End If
 

        ' Get the list of profiles from the registry

        key = reg_hklm.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList", False)

        If Not IsNothing(key) Then

            ' loop thru each subket

            For Each keyname In key.GetSubKeyNames

                subkey = key.OpenSubKey(keyname, False)

                RawSID = CType(subkey.GetValue("SID", Nothing), Byte())

                RawProfile = subkey.GetValue("ProfileImagePath", Nothing)
 

                If Not IsNothing(RawSID) Then

                    UserID = SidToName(RemotePC, RawSID)

                Else

                    ' If we don't have an imbedded SID, then we

                    ' use the key name instead

                    UserID = SidToName(RemotePC, keyname)

                End If
 

                ' add the UserID to our String Collection

                ans.Add(UserID & " - " & RawProfile)

            Next

        End If
 

        Return ans

    End Function
 
 

    '

    ' Take a "raw" SID (as a byte array) and determine the User ID (used in

    ' GetProfiles) (overloaded)

    '

    Private Function SidToName(ByVal RemotePC As String, ByVal RawSid As Byte()) As String

        Dim Sid As IntPtr

        Dim gch As GCHandle

        Dim ans As String
 

        ' get a safe pointer to the SID array of bytes

        gch = GCHandle.Alloc(RawSid, GCHandleType.Pinned)

        Sid = Marshal.UnsafeAddrOfPinnedArrayElement(RawSid, 0)

        ans = SidToName(RemotePC, Sid)

        gch.Free()
 

        Return ans

    End Function
 

    '

    ' Take a String version of a SID and generate a User ID (used in

    ' GetProfiles) (overloaded)

    '

    Private Function SidToName(ByVal RemotePC As String, ByVal sid_string As String) As String

        Dim sid As IntPtr
 

        sid = StringToSID(sid_string)

        If IsNothing(sid) Then

            Return sid_string

        End If
 

        Return SidToName(RemotePC, sid)

    End Function
 

    '

    ' Take an IntPtr SID and generate the User ID (overloaded)

    '

    Private Function SidToName(ByVal RemotePC As String, ByVal sid As IntPtr) As String

        Dim UserName, name, domain_name As String

        Dim name_len, domain_len, peUse As Integer
 

        name_len = NAME_SIZE

        domain_len = NAME_SIZE

        name = Space(name_len)

        domain_name = Space(domain_len)
 

        ' look up the Account associated with that SID

        If LookupAccountSid(RemotePC, sid, name, name_len, domain_name, domain_len, peUse) = False Then

            ' if the lookup fails, return the SID as as string

            Return SIDtoString(sid)

        End If
 

        ' put the name parts together

        If domain_len > 0 Then

            UserName = Left(domain_name, domain_len) & "\" & Left(name, name_len)

        Else

            If RemotePC = "" Then

                RemotePC = Environment.MachineName

            End If

            UserName = RemotePC & "\" & Left(name, name_len)

        End If
 

        Return UserName

    End Function
 

    '

    ' Convert a "raw" SID (as a byte array) into a string (overloaded)

    '

    Private Function SIDtoString(ByVal sidbyte As Byte()) As String

        Dim sid As IntPtr

        Dim gch As GCHandle

        Dim ans As String
 

        ' get a safe pointer

        gch = GCHandle.Alloc(sidbyte, GCHandleType.Pinned)

        sid = Marshal.UnsafeAddrOfPinnedArrayElement(sidbyte, 0)

        ans = SIDtoString(sid)

        gch.Free()
 

        Return ans

    End Function
 

    ' Convert a SID into the string version of the SID

    '

    Private Shared Function SIDtoString(ByVal sid As IntPtr) As String

        Dim ans As String

        Dim pStr As IntPtr
 

        ConvertSidToStringSid(sid, pStr)

        ans = Marshal.PtrToStringAuto(pStr)

        Marshal.FreeHGlobal(pStr)
 

        Return ans

    End Function
 

    '

    ' Convert a string representation of a SID into a real SID

    '

    Private Function StringToSID(ByVal buf As String) As IntPtr

        Dim sid As IntPtr
 

        If ConvertStringSidToSid(buf, sid) = False Then

            Return Nothing

        End If
 

        Return sid

    End Function

End Class

Open in new window

WindowsApplication1.zip
0
 
LVL 3

Expert Comment

by:cmorbach
ID: 24806154
Basically the code above does the same like this script - but also converts the sid to a user name, so you know which profile belongs to which user
On Error Resume Next
 

Const HKEY_LOCAL_MACHINE = &H80000002
 

strComputer = "."

 

Set objRegistry=GetObject("winmgmts:\\" & _ 

    strComputer & "\root\default:StdRegProv")

 

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"

objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys

 

For Each objSubkey In arrSubkeys

    strValueName = "ProfileImagePath"

    strSubPath = strKeyPath & "\" & objSubkey

    objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE,strSubPath,strValueName,strValue

    Wscript.Echo strValue

Next

Open in new window

0
 

Author Comment

by:jskfan
ID: 24809937
your last script looks like is run as a logon script.
if I replace  the strComputer = "."  with strComputer = "Realcomputername or Ip address."
then run it with Psexec remotely would that work
but I want the output to a text file so that I can see the profile name
another thing I want to know about this script, does it retrieve the profile name if the user is logged off??

0
 
LVL 3

Expert Comment

by:cmorbach
ID: 24811507
I have added the last script just to show how to take the profiles out of the registry - so it takes ALL profiles even if the user is logged off (I think).
Here the code that writes a text file:
On Error Resume Next

 

Const HKEY_LOCAL_MACHINE = &H80000002

 

strComputer = "."

 

Set objRegistry=GetObject("winmgmts:\\" & _ 

    strComputer & "\root\default:StdRegProv")

 

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"

objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys

 

 

'Open file

Set fso = CreateObject("Scripting.FileSystemObject") 

Set txtstr = fso.CreateTextFile("profiles.txt", True)
 
 

'Output

For Each objSubkey In arrSubkeys

    strValueName = "ProfileImagePath"

    strSubPath = strKeyPath & "\" & objSubkey

    objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE,strSubPath,strValueName,strValue

    txtstr.WriteLine strValue

Next
 

txtstr.close

Open in new window

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

 

Author Comment

by:jskfan
ID: 24812570
I meant the:  strComputer = "."

Means the script can do the job only if you make it as a logon script, since the variable doesn't specify any computer name.

I would like to have a script that reads computer names or IP from a text file and output the result to another text file.
if you can modify your script to do so, that would be great.

0
 
LVL 3

Expert Comment

by:cmorbach
ID: 24819592
>I meant the:  strComputer = "."
"." is localhost
You can remotely connect to the registry of another system if you have the rights.


>Means the script can do the job only if you make it as a logon script
Why? I don't know what you mean. I don't take it as logon script. I testet it locally as logged on user and remotely on a computer where no one is logged on.


>since the variable doesn't specify any computer name.
ignore this fact - in you original question you just wanted "a Script to retrieve user profile name".
This script returns ALL user profiles registered on the machine it runs (or it connects to if you set strComputer to another value).


>I would like to have a script that reads computer names or IP from a text file
>and output the result to another text file
>if you can modify your script to do so, that would be great
So your goal is that you run the script let's say on the domain controler which collects all profiles stored on the clients given in text file?
0
 

Author Comment

by:jskfan
ID: 24820837
ok...to make it simple,
let's say there is a remote computer in the network named "RemComputer"
so in the script I can just replace ""strComputer = "."  with  strComputer = "RemComputer"
I will run the script from my compyter and this will work??



0
 
LVL 3

Accepted Solution

by:
cmorbach earned 500 total points
ID: 24820876
>ok...to make it simple,
(...so I like it)

>replace ""strComputer = "."  with  strComputer = "RemComputer"
>I will run the script from my compyter and this will work??
If you have the access rights (administrative rights) to RemComputer, then you get all locally registered profiles...try it!
It takes the values just from the Windows registry, no matter if a user is logged on at the _remote_ machine or not.

Didn't it work for you? Did you test it? I mean then you see what the file contails the script creates.
0
 

Author Closing Comment

by:jskfan
ID: 31601192
Thanks a lot it works
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

In this tutorial I will show you how to make a simple HTML bar chart with the usage of WhizBase, If you want more information about WhizBase please read my previous articles at http://www.experts-exchange.com/ARTH_5123186.html (http://www.experts-ex…
When you upgrade from Windows 8 to 8.1 or to Windows 10 or if you are like me you are on the Insider Program you may find yourself with many 450MB recovery partitions.  With a traditional disk that may not be a problem but with relatively smaller SS…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

747 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

10 Experts available now in Live!

Get 1:1 Help Now