Solved

a Script to retrieve user profile name

Posted on 2009-07-08
10
569 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
[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
  • 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
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 

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
 

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

Turn Insights into Action

Communication across every corner of your business is essential to increase the velocity of your application delivery and support pipeline. Automate, standardize, and contextualize your communication processes with xMatters.

Question has a verified solution.

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

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…
This is a little timesaver I have been using for setting up Microsoft Small Business Server (SBS) in the simplest possible way. It may not be appropriate for every customer. However, when you get a situation where the person who owns the server is i…
Windows 8 comes with a dramatically different user interface known as Metro. Notably missing from the new interface is a Start button and Start Menu. Many users do not like it, much preferring the interface of earlier versions — Windows 7, Windows X…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

696 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