We all know there are a number of easy ways to determine the computer’s logged in username, but what if we want to get the account used to sign into the associated Office account?!
This was the quandary I was asked to answer recently. Much to my amazement, Microsoft has not made any way available to use for developers.
So what is one to do?
Well, a little investigative work, and I was able to determine this information was actually being stored in the registry
Computer\HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common\ServicesManagerCache\Identities\1226b2b6f1792736_LiveId\WLINBOX_SKYDRIVE_1226b2b6f1792736_97
Obviously, adjust the 15.0 depending on the version of Office that is installed.
When the user is signed in, then the UserDisplayName will provide you with the logged in account, in my case the e-mail address used to log in. Do note that if the user isn’t signed in then that key will not exist in the registry at all.
Knowing all of this we can then make a simple little function to read the key value, something along the lines of:
'---------------------------------------------------------------------------------------
' Procedure : GetOfficeSignUserDisplayName
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Determine the MS Office Login UserName/E-mail Account
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, None required
'
' Usage:
' ~~~~~~
' ? GetOfficeSignUserDisplayName
' returns -> john.harlod@live.com
'
' Revision History:
' Rev Date(yyyy-mm-dd) Description
' **************************************************************************************
' 1 2020-10-07 Initial Release
'---------------------------------------------------------------------------------------
Function GetOfficeSignUserDisplayName() As String
Dim oReg As Object
Dim sKeyValue
Const HKEY_CURRENT_USER = &H80000001
On Error GoTo Error_Handler
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
oReg.GetStringValue HKEY_CURRENT_USER, _
"Software\Microsoft\Office\15.0\Common\ServicesManagerCache\Identities\1226b2b6f1792736_LiveId\WLINBOX_SKYDRIVE_1226b2b6f1792736_97", _
"UserDisplayName", _
sKeyValue
GetOfficeSignUserDisplayName = sKeyValue
Error_Handler_Exit:
On Error Resume Next
If Not oReg Is Nothing Then Set oReg = Nothing
Exit Function
Error_Handler:
If Err.Number = 94 Then
MsgBox "The user does not appear to be logged in presently or you have specified the wrong version of Office in the Key Path."
Else
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: GetOfficeSignUserDisplayName" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
End If
Resume Error_Handler_Exit
End Function
You could easily modify the above to simply return an empty string or NULL when the user is not logged in, something like:
'---------------------------------------------------------------------------------------
' Procedure : GetOfficeSignUserDisplayName
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Determine the MS Office Login UserName/E-mail Account
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, None required
'
' Usage:
' ~~~~~~
' ? GetOfficeSignUserDisplayName
' returns -> john.harlod@live.com
'
' Revision History:
' Rev Date(yyyy-mm-dd) Description
' **************************************************************************************
' 1 2020-10-07 Initial Release
'---------------------------------------------------------------------------------------
Function GetOfficeSignUserDisplayName() As String
Dim oReg As Object
Dim sKeyValue
Const HKEY_CURRENT_USER = &H80000001
On Error GoTo Error_Handler
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
oReg.GetStringValue HKEY_CURRENT_USER, _
"Software\Microsoft\Office\15.0\Common\ServicesManagerCache\Identities\1226b2b6f1792736_LiveId\WLINBOX_SKYDRIVE_1226b2b6f1792736_97", _
"UserDisplayName", _
sKeyValue
GetOfficeSignUserDisplayName = sKeyValue
Error_Handler_Exit:
On Error Resume Next
If Not oReg Is Nothing Then Set oReg = Nothing
Exit Function
Error_Handler:
If Err.Number <> 94 Then
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: GetOfficeSignUserDisplayName" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
End If
Resume Error_Handler_Exit
End Function
I hope this will help a few of you out there. I’m still amazed that such functionality isn’t native within Office.
Unfortunately my company has an anti malware virus checker and recognises this as suspicious. There has to be an easier way!!!
I’m unaware of any other approach. I searched trying to find this information and couldn’t locate any way to do so, this is when I started profiling my system to figure out how/where this was being stored in the registry and eventually came up with this code (which simply reads a registry key). The fact that a virus/malware software blocks this is a little nuts! I’d just create an exception (also report it to them).
I’m thinking that there may be a way using PowerShell, but you’d need the ability to install the MSOnline cmdlet on all the PCs. Then, you could look at what the Get-MsolUser cmdlet has to offer. Just an idea that I haven’t explored though.
Thanks for this – it is a great start! I’m getting ready to do a video on Azure SQL+AD connectivity with Access and so I landed here. I needed to go into regex and get my own ID which was different (the bit before _LiveID) in order for it to work. So, there might be a need to search keys for _LiveID before looking at the value. I believe this will work for most scenarios, but I think it only finds the identity of the windows logged in user LiveID/OneDrive identity. I think 95% of the time this will match with the user logged into Office. However, when I logged into Office with a different account, the change was not detected in that key. After closing and opening Office, a new identity key was indeed created with the suffix _ADAL on it. So, I don’t know which one is actually logged into Office at a particular moment.
Interesting rabbit hole to go down!
I’m sorry to spoil your day, but this approach is flawed on multiple levels…
1. The long number (1226b2…) must not be hardcoded, because it *may* be an candidate for the identity you are looking for and thus different for everyone using this.
2. The suffix “_LiveId” seems to depend on the authentication mechanism and will be “_ADAL” (=Azure Active Directory Authentication Library) more recently.
3. There is no sub key prefixed “WLINBOX_SKYDRIVE_” on my machine even though I am logged into OneDrive Business (I verified it!).
4. There is a entry prefixed “WLMOUNTED_SKYDRIVE_”, but this contains the data of a personal account, which is *not* the one I’m currently singed in with the OneDrive Business client.
5. In the ServicesManagerCache\Identities\[$IdentityGuid] sub branch of the registry there is data for 5 different MS accounts. The one in the above key [$IdentityGuid] would be the most likely correct one for me, but I don’t think this can be relied on. I rather assume it will be the [$IdentityGuid] of the very first one you logged in to, which is not necessarily the one you are looking for right now.
Thanks Philipp.
You’re not spoiling anything. It’s always good to get more information.
I use my site to share information. This code works just fine for the client I developed it for, but may not work in all cases.
In business enterprise setups, I have read you can use AD to get the info.
I have also read, like Office, you need to query half-dozen different registry keys.
As mentioned in the comments, you can also attack this via PowerShell, which may be the best option in reality.
I don’t know as I stopped digging once I had functional code that worked for my needs, but I still share in the hopes it helps others.
It still amazes me how, once again, Microsoft has dropped the ball. They provide no way to retrieve office build no. Nor do they provide a way to identify the logged user account. Basic stuff, completely overlooked, even after years of people asking for it.
I’m sure your comments will help others.
Do you have a solution to share?
I found this page in a Google search. As with lots of others I want to track the users that change data on a specific Worksheet range.
If you don’t know the user identity because the user could be sitting at any pc could the logic be to look through the registry at the different identity folders at ..ServicesManagerCache\Identities\.. and either directly, or by using the list of folders then look to see if one of them has a UserDisplayName entry? Does it only have an entry if it is the current logged in user or does it retain them?
Thoughts? Any ideas of how to go about the identity list search?
For a snippet independent of the Office version, see https://stackoverflow.com/a/79696289/1719931
When I wrote mine there was only 15.0 to worry about, but making it more flexible is a great improvement.
If you’re running this in Office, you probably don’t even need to read the Reg Key to get the Version and can simply use:
Application.Version