- Monitoring Microsoft 365 with SCOM and the NiCE Active 365 Management Pack - Tue, Feb 7 2023
- SCOM.Addons.MailIn: Monitor anything that can send email with SCOM - Mon, May 25 2020
- Display a user’s logged-on computer in Active Directory Users and Computers (ADUC) - Mon, Jan 21 2019
Making the currently logged-on computer retrievable from Active Directory and showing it directly within ADUC can be useful for troubleshooting.
To store information in Active Directory, you have to follow these steps:
- Allow user objects to update an (unused) attribute by themselves
- Create a VBScript that writes the current logged-on computer into that attribute
- Create and link a Group Policy Object (GPO) that calls the script on user logon processes
And these are the steps to retrieve information from ADUC:
- Modify the Active Directory object to customize the ADUC context menu
- Place a subfolder in netlogon to ensure the script has domain-wide distribution
- Write a VBScript that receives the selected user, gathers required information from Active Directory, and displays it
Allow user objects to update an Active Directory attribute
As a domain administrator, open ADUC and activate the advanced features.
Right-click the organizational unit (OU) where user accounts are located, and go to Properties > Security > Advanced > SELF > Edit.
ADUC showing the Permissions tab for a user's OU
Change to the Properties tab, scroll down, and tick Allow for the Read and Write street attribute.
(Microsoft uses the "st" attribute to store and display the street address.)
Confirm all open windows by clicking OK and close ADUC.
VBScript to store the computer name in the user object
Open Notepad or another text editor of your choice and place the following lines of code into it.
' ********************************************************************** ' ' VBScript: AD-User-UpdateAttributes.vbs ' ' Author: Ruben ' Date: 2018-12-21 ' Version: 1 ' ' Description: ' Sets the "street" attribute to the computer name ' ' Attention: ' This VB script comes with ABSOLUTELY NO WARRANTY; for details ' see gnu-gpl. This is free software, and you are welcome ' to redistribute it under certain conditions; see gnu-gpl for details. ' ' ********************************************************************** ' Authenticating against active directory with Kerberos Const ADS_SECURE_AUTHENTICATION = 1 Const ADS_FAST_BIND = 32 Const ADS_USE_SIGNING = 64 Const ADS_USE_SEALING = 128 Dim objDSE, objConn, objRS, objdso, objADSUser, objWShell, strDefaultNamingContext, strADSUser, strComputerName Set objWShell = CreateObject("WScript.Shell") ' Get username and computername from the environment variables strUserID = objWShell.ExpandEnvironmentStrings("%USERNAME%") strComputerName = objWShell.ExpandEnvironmentStrings("%COMPUTERNAME%") ' Binding to Active Directory using ADO (+Kerberos) Set objdso = GetObject("LDAP:") Set objDSE = GetObject("LDAP://rootDSE") Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADSDSOObject" objConn.Properties("ADSI Flag") = ADS_SECURE_AUTHENTICATION + ADS_USE_SEALING + ADS_USE_SIGNING + ADS_FAST_BIND objConn.Open "Active Directory Provider" strDefaultNamingContext = "<LDAP://" & objDSE.Get("defaultNamingContext") &">" ' Searching User object in Active Directory and initiating an ojbect Set objRS = objConn.Execute (strDefaultNamingContext &";(sAMAccountName="&strUserID&");sAMAccountName,ADsPath;SubTree") ' If the user was found the computername will be stored in the street attribute. If objRS.RecordCount < 1 Then WScript.Quit(1) Else If Not IsNull(objRS.Fields.Item("ADsPath").Value) Then strADSUser = objRS.Fields.Item("ADsPath").Value Set objADSUser = objdso.OpenDSObject(strADSUser,vbNullString,vbNullString,ADS_SECURE_AUTHENTICATION + ADS_USE_SEALING + ADS_USE_SIGNING + ADS_FAST_BIND) If strComputerName <> " " Then objADSUser.Put "street", strComputerName End If objADSUser.SetInfo End If End If Set objRS = Nothing objConn.Close
Creating and linking a Group Policy Object (GPO)
Open the Group Policy Management Console (GPMC), select the OU where users are located, and either create a new GPO or modify an existing one. Navigate to User Configuration > Windows Settings > Scripts (Logon/Logoff) > Logon.
Copy the script into the folder revealed by clicking on Show Files. Confirm the open windows and close the GPO configuration. After refreshing, the GPO will look like the picture below.
Close GPMC.
Customizing the ADUC user context menu
The Admin-Context-Menu attribute in Active Directory allows placing custom entries in the context menu of computers, users, groups and other objects in ADUC. It is in the Configuration partition of Active Directory and requires modifying Enterprise Admin permissions.
Open ADSIEDIT.MSC as an enterprise admin, navigate to Configuration > CN=Configuration, CN=DisplaySpecifiers > CN=409 > CN=user-Display, and choose Properties:
Select adminContextMenu, click Edit, and add the following line:
5,IT: Show currently logged-on computer,\\nwtraders.msft\netlogon\ADUCExtensions\AD_Get-UserInfos.vbs
- 5 specifies the order; if already in use, choose another number
- IT: Show the currently logged-on computer; the text appears in the context menu
- mfst is the name of this domain
- ADUCExtensions is a folder we need to be create
Confirm the dialog boxes and close ADSIEDIT.
Place a subfolder in netlogon
This ensure that the script has domain-wide distribution. Log on to a domain controller, navigate to the netlogon share, and create a folder named ADUCExtensions. Keep the permissions but ensure that nobody except administrators can change the folder content.
VBScript to retrieve the computer name
The script below retrieves the computer name from the selected user object. Open Notepad or another text editor of your choice and place the following lines of code into it.
Name the file AD_Get-UserInfos.vbs and store it in the previously created folder ADUCExtensions.
' ********************************************************************** ' ' VBScript: AD_Get-UserInfos.vbs ' ' Author: Ruben ' Date: 2018-12-26 ' Version: 1 ' ' Description: ' This script displays some additional user information by receiving ' the input from right-clicking a user object in ADUC. ' ' Attention: ' This VB script comes with ABSOLUTELY NO WARRANTY; for details ' see gnu-gpl. This is free software, and you are welcome ' to redistribute it under certain conditions; see gnu-gpl for details. ' ' ********************************************************************** 'Authenticating against active directory with Kerberos Const ADS_SECURE_AUTHENTICATION = 1 Const ADS_FAST_BIND = 32 Const ADS_USE_SIGNING = 64 Const ADS_USE_SEALING = 128 Dim objDSE, objConn, objRS, objdso, objADSUser, objWShell Dim arrUserAccountData, strDefaultNamingContext, strLine, strADSUser, strStaffCN, strInpUserID Set wshArguments = WScript.Arguments Set objUser = GetObject(wshArguments(0)) strInpUserID = objUser.SamAccountName Set objWShell = CreateObject("WScript.Shell") 'Binding to Active Directory using ADO (+Kerberos) to get the distinguished name of the user object Set objdso = GetObject("LDAP:") Set objDSE = GetObject("LDAP://rootDSE") Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADSDSOObject" objConn.Properties("ADSI Flag") = ADS_SECURE_AUTHENTICATION + ADS_USE_SEALING + ADS_USE_SIGNING + ADS_FAST_BIND objConn.Open "Active Directory Provider" strDefaultNamingContext = "<LDAP://" & objDSE.Get("defaultNamingContext") &">" Set objRS = objConn.Execute (strDefaultNamingContext &";(sAMAccountName="&strInpUserID&"); sAMAccountName,ADsPath;SubTree") If objRS.RecordCount < 1 Then MsgBox "Error: No ADS - User found: " &strInpUserID WScript.Quit(1) Else If Not IsNull(objRS.Fields.Item("ADsPath").Value) Then strADSUser = objRS.Fields.Item("ADsPath").Value Set objADSUser = objdso.OpenDSObject(strADSUser,vbNullString,vbNullString,ADS_SECURE_AUTHENTICATION + ADS_USE_SEALING + ADS_USE_SIGNING + ADS_FAST_BIND) strStaffCN = objADSUser.Get("cn") If Not IsNull(objADSUser.street) And Not IsEmpty(objADSUser.street) Then strComputerName = objADSUser.street Else strComputerName = "Computername not found in AD." End If If Err.Number <> 0 Then MsgBox "Error occured while gathering information for: " & strADSUser &" "& Err.Description Err.Clear Else MsgBox "Current Computer:" & vbTab & strComputerName & VbCrLf & _ VbCrLf, vbInformation, "IT: Additional user information for" & vbTab &strStaffCN End If End If End If Set objRS = Nothing objConn.Close
Allow some time to replicate the changes and then see if everything works.
Subscribe to 4sysops newsletter!
Questions and comments are welcome as usual. Please use the feedback form below.
pretty cool trick! Nice article, super clear and to the point.
Thanks Mike 🙂
looks cool, but before I go too far, will this method show all computers and servers the user is logged into without running the code multiple times.
Thanks
Hi Peter,
with this solution you will only have the current logged on computer stored in the user object.
If you have the requirement to store all computers a user logs on a modification of the first script is required.
Let me know if you need it.
The SELF user has all attrributes grayed out. I cannot change them. I am not sure if I can disable inheritance or not without causing a problem (in case that is stopping me). I am a domain admin.
Hi Randy,
it’s hard to answering without seeing your screen or knowing your environment. What I suggest though would be:
– Create a new OU / Sub-OU
– Move 1 or 2 users into that OU
– Customize the aCL
– Test the solution above
– Check if something is not working anymore. If there is move the users back to origin
According to my experience. You can safely stop inheritance, clear all permissions and and only the ones that you think of. If something is not working you can check the option again and restore the permissions. –> Test it with a test-user before doing it in production 😉
Hope it could help.
Script AD_Get-UserInfos.vbs.vbs not running.
Line 31
char 1
Error: Subsript out of range
Code: 800A0009
Source: Microsoft VBScript runtime error
I don't know VBA at all
Hi Viktor,
Subscript out of range is thrown in vbs when an empty array is accessed for data.
you can check the array for emptiness with the following code.
If UBound(wshArguments) >= 0 Then
Set objUser = GetObject(wshArguments(0))
End If
Where would you put the below statement and is that all you need to do for the script to work?
If UBound(wshArguments) >= 0 Then
Set objUser = GetObject(wshArguments(0))
End If
WOW