[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 167
  • Last Modified:

Why vbscript displays my Active Directory details, not the remote user?

The attached vbscript accepts a computer name as input,  then returns assorted details about the person logged onto that computer from Active Directory. The problem is that whenever I input a computer name that no one is currently logged onto, the script returns my personal information from Active Directory (i.e., my username, my phone number, my email address, etc..) I'm a little lost on how to prevent that. It does work fine whenever someone is currently logged onto a remote host in that it reveals all of their AD information instead. How would you rememdy this? And by chance is there a simple fix for the "\" that echoes after the manager's last name?
strComputer = InputBox("Enter computer name:")
If Ping(strComputer) = True Then
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
	Set colUser = objWMIService.ExecQuery("Select UserName from Win32_ComputerSystem")
	For Each objUser In colUser
		strUserName = objUser.UserName
	Next
	If InStr(strUserName, "\") > 0 Then strUserName = Mid(strUserName, InStrRev(strUserName, "\") + 1)
	strUserADsPath = Get_LDAP_User_Properties("user", "samAccountName", strUserName, "adsPath")
	If Left(strUserADsPath, 7) = "LDAP://" Then
		Set objUser = GetObject(strUserADsPath)
		strDisplayName = objUser.DisplayName
		strPhoneNumber = objUser.telephoneNumber
		strManager = objUser.Manager
		strMail = objuser.mail
		If strManager <> "" Then strManager = Left(Split(strManager, "=")(1), Len(Split(strManager, "=")(1)) - 3)
		MsgBox "Username: " & strUserName & VbCrLf & _
		"Display Name: " & strDisplayName & VbCrLf & _
		"Phone Number: " & strPhoneNumber & VbCrLf & _
		"Email: " & strMail & VbCrLf & _
		"Manager: " & strManager
		
	Else
		MsgBox "Could not find ADsPath for " & strUserName
	End If
Else
	MsgBox strComputer & " did not respond to ping."
End If

Function Ping(strComputer)
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
	If boolCode = 0 Then
		Ping = True
	Else
		Ping = False
	End If
End Function

Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
      
      ' This is a custom function that connects to the Active Directory, and returns the specific
      ' Active Directory attribute value, of a specific Object.
      ' strObjectType: usually "User" or "Computer"
      ' strSearchField: the field by which to seach the AD by. This acts like an SQL Query's WHERE clause.
      '				It filters the results by the value of strObjectToGet
      ' strObjectToGet: the value by which the results are filtered by, according the strSearchField.
      '				For example, if you are searching based on the user account name, strSearchField
      '				would be "samAccountName", and strObjectToGet would be that speicific account name,
      '				such as "jsmith".  This equates to "WHERE 'samAccountName' = 'jsmith'"
      '	strCommaDelimProps: the field from the object to actually return.  For example, if you wanted
      '				the home folder path, as defined by the AD, for a specific user, this would be
      '				"homeDirectory".  If you want to return the ADsPath so that you can bind to that
      '				user and get your own parameters from them, then use "ADsPath" as a return string,
      '				then bind to the user: Set objUser = GetObject("LDAP://" & strReturnADsPath)
      
      ' Now we're checking if the user account passed may have a domain already specified,
      ' in which case we connect to that domain in AD, instead of the default one.
      If InStr(strObjectToGet, "\") > 0 Then
            arrGroupBits = Split(strObjectToGet, "\")
            strDC = arrGroupBits(0)
            strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
            strObjectToGet = arrGroupBits(1)
      Else
      ' Otherwise we just connect to the default domain
            Set objRootDSE = GetObject("LDAP://RootDSE")
            strDNSDomain = objRootDSE.Get("defaultNamingContext")
      End If

      strBase = "<LDAP://" & strDNSDomain & ">"
      ' Setup ADO objects.
      Set adoCommand = CreateObject("ADODB.Command")
      Set adoConnection = CreateObject("ADODB.Connection")
      adoConnection.Provider = "ADsDSOObject"
      adoConnection.Open "Active Directory Provider"
      adoCommand.ActiveConnection = adoConnection

 
      ' Filter on user objects.
      'strFilter = "(&(objectCategory=person)(objectClass=user))"
      strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"

      ' Comma delimited list of attribute values to retrieve.
      strAttributes = strCommaDelimProps
      arrProperties = Split(strCommaDelimProps, ",")

      ' Construct the LDAP syntax query.
      strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
      adoCommand.CommandText = strQuery
      ' Define the maximum records to return
      adoCommand.Properties("Page Size") = 100
      adoCommand.Properties("Timeout") = 30
      adoCommand.Properties("Cache Results") = False

      ' Run the query.
      Set adoRecordset = adoCommand.Execute
      ' Enumerate the resulting recordset.
      strReturnVal = ""
      Do Until adoRecordset.EOF
          ' Retrieve values and display.    
          For intCount = LBound(arrProperties) To UBound(arrProperties)
                If strReturnVal = "" Then
                      strReturnVal = adoRecordset.Fields(intCount).Value
                Else
                      strReturnVal = strReturnVal & VbCrLf & adoRecordset.Fields(intCount).Value
                End If
          Next
          ' Move to the next record in the recordset.
          adoRecordset.MoveNext
      Loop

      ' Clean up.
      adoRecordset.Close
      adoConnection.Close
      Get_LDAP_User_Properties = strReturnVal

End Function

Open in new window

0
jcb431
Asked:
jcb431
  • 6
  • 3
1 Solution
 
FarWestCommented:
I think this is the cause of the problem

      For Each objUser In colUser
            strUserName = objUser.UserName
      Next

so that means you take the last one in colUser, and you are accessing the machine via WMI, it always happend that when there is a logged on user it will be the last object but when know one so you are the last object,
I think you need to add something related to logon type to get only interactive or local logon  in the query if this is possible in the query, or just do nothing if it is your username ( this is not a good solution becuase you will still have the chance to get users evene if they do network resource access)
0
 
jcb431Author Commented:
As in interactive (user) session # where the username <> me ?
0
 
jcb431Author Commented:
Or where session name = console and username <> me?
0
Technology Partners: 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!

 
jcb431Author Commented:
Think I'm getting somewhere. What I need to have returned is the username where the sessionname is "console" and the state is "active". Perhaps the Win32_ComputerSystem WMI class is not the one I really need to use?
0
 
jcb431Author Commented:
Set colUser = objWMI.ExecQuery _
    ("Select * from Win32_LogonSession Where LogonType = 2").........perhaps
0
 
FarWestCommented:
I think it will do the trick, better than <> me
did you find "LogonType" as session parameter?
0
 
FarWestCommented:
yes it is ( I will answer my self :) )
Copyclass Win32_LogonSession : Win32_Session
{
  string   AuthenticationPackage;
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   LogonId;
  uint32   LogonType;
  string   Name;
  datetime StartTime;
  string   Status;
};
0
 
jcb431Author Commented:
Thats what I saw on MSDN, but when I tried the following script to see what values it would return, they were nothing like my expectations. I thought I would see something along the lines of running qwinsta.exe from the CLI.
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogonSession")
For Each objItem in colItems
    Wscript.Echo "AuthenticationPackage: " & objItem.AuthenticationPackage
    Wscript.Echo "Caption: " & objItem.Caption
    Wscript.Echo "Description: " & objItem.Description
    Wscript.Echo "InstallDate: " & objItem.InstallDate
    Wscript.Echo "LogonId: " & objItem.LogonId
    Wscript.Echo "LogonType: " & objItem.LogonType
    Wscript.Echo "Name: " & objItem.Name
    Wscript.Echo "StartTime: " & objItem.StartTime
    Wscript.Echo "Status: " & objItem.Status
Next

Open in new window

0
 
jcb431Author Commented:
I haven't tried this yet, but it might work if I ran the script with a service account.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now