Announcement

Collapse
No announcement yet.

Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Machine

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Machine

    XP Pro SP3 with all patches up to November release destination computers
    Server 2003 Domain
    Vista SP1 with all patches up to November release source computer
    GPO set to allow port exceptions for WMI along with remote execution

    My scripts all run at logon currently and retrieve different pieces of information for the currently logged on user, from mapped drives to folder contents to network printers. I'm trying to reduce the logon time and also adding more flexability to my small arsenal of admin scripts. The one I'm using as a test retrieves the printers for a user. If I run the script as myself I can only retrieve the information if I am a local admin on the computer; I understand that only local admins can get the info remotely from a wmi kb from Microsoft. All users are local admins on their specific computer. When I run the script as my domain admin user(who is also a local admin on the remote machine), I get the correct information, for the domain admin user. I am looking for a way to "impersonate" the currently logged on user on the remote machine so I can run the script to retrieve their settings, while logged on as me from my workstation. Below is what I have now:

    Code:
    strComputer = inputbox("computer name")
    strNamespace = "root\cimv2"
    strUser = inputbox("username")
    strPassword = inputbox("password")
    Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objwbemLocator.ConnectServer _
    (strComputer, strNamespace, strUser, strPassword)
    Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
     
    For Each objPrinter in colPrinters
    If objPrinter.Attributes And 64 Then 
    strPrinterType = "Local"
    Else
    strPrinterType = "Network"
    End If
    strPrinters = strPrinters & objPrinter.Name & " -- " & strPrinterType & vbCrLf
    Next
    Msgbox strPrinters
    Any ideas?
    Last edited by biggles77; 3rd December 2009, 15:13.

  • #2
    Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

    have you heard of Scriptomatic from the microsoft ScriptingGuys ? Download that and see if it helps..
    it does all my scripting for me..

    also - check out powershell and see if that might help
    Please do show your appreciation to those who assist you by leaving Rep Point https://www.petri.com/forums/core/im.../icon_beer.gif

    Comment


    • #3
      Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

      this is a script I have to enumerate mailbox sizes.. I've bolded the part i think may assist.

      Option Explicit
      On Error Resume Next

      Dim ServerList ' List of computers to check
      Dim server ' Current computer to check
      Dim fso ' File System Object
      Dim strWinMgmts ' Connection string for WMI
      Dim objWMIExchange ' Exchange Namespace WMI object
      Dim listExchange_Mailboxs ' ExchangeLogons collection
      Dim objExchange_Mailbox ' A single ExchangeLogon WMI object
      Dim logfile ' Output file

      Const cWMINameSpace = "root/MicrosoftExchangeV2"
      Const cWMIInstance = "Exchange_Mailbox"
      Const LOG_FILE = "MailboxSize.csv"


      '--------------------------------------
      ' Set up the array of email servers
      '--------------------------------------
      ServerList = Array("abcdefghi")

      '--------------------------------------
      ' Set up log file
      '--------------------------------------
      set fso = CreateObject("Scripting.FileSystemObject")
      Set logfile = fso.CreateTextFile(LOG_FILE)
      logfile.WriteLine("""Display Name"",""Mailbox Size"",""Mailbox TotalItems""")


      ' Create the object string, indicating WMI (winmgmts), using the
      ' current user credentials (impersonationLevel=impersonate),
      ' on the computer specified in the constant cComputerName, and
      ' using the CIM namespace for the Exchange provider.
      WScript.Echo "Starting now"

      'The rest of the script will fetch mailbox sizes for our servers. Mailbox sizes are in Kilobytes.
      For Each server in ServerList
      WScript.Echo "Starting " & server & " search."
      strWinMgmts = "winmgmts:{impersonationLevel=impersonate}!//" & server & "/" & cWMINameSpace
      'WScript.Echo strWinMgmts

      Set objWMIExchange = GetObject(strWinMgmts)

      ' Verify we were able to correctly set the object.
      If Err.Number <> 0 Then
      WScript.Echo "ERROR: Unable to connect to the WMI namespace."
      Else
      'The Resources that currently exist appear as a list of
      'Exchange_Mailbox instances in the Exchange namespace.
      Set listExchange_Mailboxs = objWMIExchange.InstancesOf(cWMIInstance)

      ' Were any Exchange_Mailbox Instances returned?
      If (listExchange_Mailboxs.count > 0) Then
      ' If yes, do the following:
      ' Iterate through the list of Exchange_Mailbox objects.
      For Each objExchange_Mailbox in listExchange_Mailboxs

      ' Display the value of the Size property.
      logfile.WriteLine("""" & objExchange_Mailbox.MailboxDisplayName & """,""" & objExchange_Mailbox.Size & """,""" & objExchange_Mailbox.TotalItems & """")

      Next
      Else
      ' If no Exchange_Mailbox instances were returned, display that.
      WScript.Echo "WARNING: No Exchange_Mailbox instances were returned."
      End If
      End If
      Next

      Wscript.Echo "Completed"
      note that I did not write this script,and I do not remember where I found it.. I made minor modifications - basically to filter it down to only what i wanted.
      Please do show your appreciation to those who assist you by leaving Rep Point https://www.petri.com/forums/core/im.../icon_beer.gif

      Comment


      • #4
        Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

        Yup; i downloaded the scriptomatic a while ago. I've got the beginner and advanced vbscript awards from the games in 2007 and 2008, but my problem is I only know what I need to figure out. If I need to do a particular task, I figure out the code, or at least try to.

        I'll definately try out the impersonate code. I've seen a few examples of that around, I just didn't know the syntax that would work for me. I see you echo the variables after they are constructed; I do that too. Even thoug I've been writing my scripts for about three years now I still don't trust myself.

        Comment


        • #5
          Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

          Moved to the Scripting forum where it will get more answers

          Comment


          • #6
            Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

            I tried the impersonation and it didn't work. I also tried impersonate=delegate and just got an error. If there was a way to query AD for the user's password, then I could just pull that into the script and it would be running the remote WMI query using the remote user's credentials. I'll keep trying and hopefully something works.

            Comment


            • #7
              Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

              Originally posted by cseiter View Post
              I tried the impersonation and it didn't work. I also tried impersonate=delegate and just got an error. If there was a way to query AD for the user's password, then I could just pull that into the script and it would be running the remote WMI query using the remote user's credentials. I'll keep trying and hopefully something works.
              You can use Impersonate so that the service can access system resources on behalf of the caller.
              For WMI versions 1.5 and newer, the default impersonationLevel setting is Impersonate.

              wbemImpersonationLevelImpersonate allows objects to use the credentials of the caller. This is the recommended impersonation level for Scripting API for WMI calls.

              wbemImpersonationLevelDelegate allows objects to permit other objects to use the credentials of the caller. You can use this impersonation level for scripting API for WMI calls, but may constitute an unnecessary security risk since it allows a script to use your credentials on a remote computer and then enables that remote computer to use your credentials to other objects and on another remote computer.

              _
              Below is a script that can list the actual printers for the currently logged on user on a remote machine. That information comes from the registry on the remote computer. By determing first and then using the SID of that user the script is able to read and write the user's HKCU hive, from where you are able to manage the user's printers.

              Note,
              This sample script uses the GetObject function directly to connect to WMI on a Remote Computer. To be able to use alternate credendials here, you could start the script with the cscript host runned as an user that is member of the domain admins group. It is however still possible to use the ConnectServer function, like you using in your script, to provide alternate credendials for remote connections. http://msdn.microsoft.com/en-us/libr...90(VS.85).aspx

              Code:
              ' Script (Version 1.1.0) to enumerate
              ' Printers of the currently logged on user on a remote machine
              ' By Remco Simons [NL] 2009
              ' http://forums.petri.com/showthread.php?t=42359
              
              ' *********************************************************************
              ' This script also support RDP-sessions and
              ' RDP-printers on the remote computer!
              ' *********************************************************************
              
              Const HKEY_USERS = &H80000003
              Const col1       = 33
              DIM objShell
              
              
              strComputer = "NameOfRemoteComputer"
              
              
              If IsPingable(strComputer) = TRUE Then
              
               Set objSWbemServices = GetObject( _
                 "winmgmts:{impersonationLevel=impersonate}!\\" _
                 & strComputer & "\root\cimv2")
              
               Set colSessions = objSWbemServices.ExecQuery _
                  ("Select * from Win32_LogonSession " _
                  & "Where LogonType = 2 OR LogonType = 10")
              
               If colSessions.Count > 0 Then
                 For Each objSession in colSessions
              
                   If objSession.LogonType = 2 Then
                     Logontype = "Session at Console"
                   Else
                     Logontype = "RDP-session"
                   End If
              
                   Set colList = objSWbemServices.ExecQuery("Associators of " _
                       & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "}" _
                       & " Where AssocClass=Win32_LoggedOnUser Role=Dependent" )
              
                   For Each objItem in colList
                     strUser = objItem.Name
                     strDomain = objItem.Domain
                     strSID = objItem.SID
              
                     rem If LCase(strDomain & "\" & strUser) = LCase(strLogon) _
                     rem   Then exit For
                     strLogon = strDomain & "\" & strUser
              
                     strSession = vbNewline & Logontype & " (started: " _
                       & objSession.StartTime & ")" & vbNewline _
                       & objItem.FullName & " logged on to " & strComputer
              
              '### Begin enum ###
                     Set objReg = GetObject( _
                       "winmgmts:{impersonationLevel=impersonate}!\\" _
                       & strComputer & "\root\default:StdRegProv")
              
                     ' eNUM Printer Devices
                     strKeyPath1 = strSID & "\Software\Microsoft\Windows NT" _
                       & "\CurrentVersion\Devices"
                     Set oMethod = objReg.Methods_("EnumValues")
                     Set oInParam = oMethod.inParameters.SpawnInstance_()
                     oInParam.hDefKey = HKEY_USERS
                     oInParam.sSubKeyName = strKeyPath1
                     Set oOutParam = objReg.ExecMethod_("EnumValues", oInParam)
              
                     For i=0 To UBound(oOutParam.Properties_("sNames"))
                       sName = oOutParam.Properties_("sNames")(i)
              
                       objReg.GetStringValue HKEY_USERS,strKeyPath1,sName,dwValue
                       If InStr(1,dwValue,"winspool,",1) = 1 Then
              
                         If InStr(1,dwValue,"winspool,TS",1) = 1 Then
                           PRNlist = PRNlist & tblPrinters(sName) & _
                             "TS-printer" & vbNewline
              
                         ElseIf Instr(sName, "\\") = 1 Then
                           sName = Mid(sName, inStrRev(sName, "\")+1)
                           PRNlist = PRNlist & tblPrinters(sName) & _
                             "network printer" & vbNewline
              
                         Else
                           PRNlist = PRNlist & tblPrinters(sName) & _
                             "local printer" & vbNewline
                         End If
                       End If
                     Next
              '### End enum ###
              
                     Wscript.echo strSession & vbNewline & PRNlist
                     PRNlist = Empty
              
                   Next
                 Next
               End If
              End If
              
              Function tblPrinters(sName)
                 Dim sep, lName, intSpaces
                 sep = " "
                 If Len(sName) > col1 Then sep = "*"
              
                 ' Trim Printername
                 sName = Left(sName, col1) : lName = Len(Trim(sName))
                 If sep = "*" And lName < col1 _
                   Then sName = Trim(sName) & String(col1-lName,"*")
              
                 lName = Len(sName) : intSpaces = col1 - lName
                 tblPrinters = " - " & sName & space(intSpaces) & sep & "= "
              End Function
              
              Function IsPingable(ByVal strHost)
                ' http://www.rlmueller.net/PingComputers.htm
                ' function returns "False" (0) or "True" (-1)
                If Not IsObject(objShell) _
                  Then Set objShell = _
                    CreateObject("WScript.Shell")
                With objShell
                  Select Case .Run("%comspec% /c" _
                    & " ping.exe -n 1 -w 750 " & strHost _
                    & " | find/i ""TTL="" >nul 2>&1", 0, True)
                  Case 0
                    IsPingable = True
                  Case Else
                    IsPingable = False
                  End Select
                End With
              End Function
              \Rems
              Last edited by Rems; 7th December 2009, 12:57.

              This posting is provided "AS IS" with no warranties, and confers no rights.

              __________________

              ** Remember to give credit where credit's due **
              and leave Reputation Points for meaningful posts

              Comment


              • #8
                Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

                The script version below uses the ConnectServer function instead of the GetObject function to connect to WMI on a Remote Computer. To make the connection the scipt will ask for for Computername, Username and Password.

                Note,
                Unlike the GetObject function, you cannot use the ConnectServer function to connect to the WMI service on the local computer.


                Code:
                ' Script (Version 2.1.0) to enumerate
                ' Printers of the currently logged on user on a remote machine
                ' By Remco Simons [NL] 2009
                ' http://forums.petri.com/showthread.php?t=42359
                
                ' *********************************************************************
                ' This script also support RDP-sessions and
                ' RDP-printers on the remote computer!
                ' *********************************************************************
                
                Const WBEM_FLAG_CONNECT_USE_MAX_WAIT = &H80 '(Connection timeout 2 min)
                Const HKEY_USERS = &H80000003
                Const col1       = 33
                DIM objShell
                
                Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
                ' Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
                ' http://msdn.microsoft.com/en-us/library/aa393067(VS.85).aspx
                
                strComputer = inputbox("computer name")
                sAdmin = inputbox("username")
                sPassw = inputbox("password")
                
                If IsPingable(strComputer) = TRUE Then
                
                 Set objSWbemServices = objSWbemLocator.ConnectServer _
                   (strComputer, "root\CIMV2","" & sAdmin & "","" & sPassw & "" _
                   ,,,WBEM_FLAG_CONNECT_USE_MAX_WAIT)
                 objSWbemServices.Security_.ImpersonationLevel = 3
                
                 Set colSessions = objSWbemServices.ExecQuery _
                    ("Select * from Win32_LogonSession " _
                    & "Where LogonType = 2 OR LogonType = 10")
                
                 If colSessions.Count > 0 Then
                   For Each objSession in colSessions
                
                     If objSession.LogonType = 2 Then
                       Logontype = "Session at Console"
                     Else
                       Logontype = "RDP-session"
                     End If
                
                     Set colList = objSWbemServices.ExecQuery("Associators of " _
                         & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "}" _
                         & " Where AssocClass=Win32_LoggedOnUser Role=Dependent" )
                
                     For Each objItem in colList
                       strUser = objItem.Name
                       strDomain = objItem.Domain
                       strSID = objItem.SID
                
                       rem If LCase(strDomain & "\" & strUser) = LCase(strLogon) _
                       rem   Then exit For
                       strLogon = strDomain & "\" & strUser
                
                       strSession = vbNewline & Logontype & " (started: " _
                         & objSession.StartTime & ")" & vbNewline _
                         & objItem.FullName & " logged on to " & strComputer
                
                '### Begin enum ###
                       Set objServices = objSWbemLocator.ConnectServer _
                         (strComputer, "root\default","" & sAdmin & "","" & sPassw & "" _
                         ,,,WBEM_FLAG_CONNECT_USE_MAX_WAIT)  ' ,objCtx)
                       objServices.Security_.ImpersonationLevel = 3
                       Set objReg = objServices.Get("StdRegProv")
                
                       ' eNUM Printer Devices
                       strKeyPath1 = strSID & "\Software\Microsoft\Windows NT" _
                         & "\CurrentVersion\Devices"
                       Set oMethod = objReg.Methods_("EnumValues")
                       Set oInParam = oMethod.inParameters.SpawnInstance_()
                       oInParam.hDefKey = HKEY_USERS
                       oInParam.sSubKeyName = strKeyPath1
                       Set oOutParam = objReg.ExecMethod_("EnumValues", oInParam)
                
                       For i=0 To UBound(oOutParam.Properties_("sNames"))
                         sName = oOutParam.Properties_("sNames")(i)
                
                         objReg.GetStringValue HKEY_USERS,strKeyPath1,sName,dwValue
                         If InStr(1,dwValue,"winspool,",1) = 1 Then
                
                           If InStr(1,dwValue,"winspool,TS",1) = 1 Then
                             PRNlist = PRNlist & tblPrinters(sName) & _
                               "TS-printer" & vbNewline
                
                           ElseIf Instr(sName, "\\") = 1 Then
                             sName = Mid(sName, inStrRev(sName, "\")+1)
                             PRNlist = PRNlist & tblPrinters(sName) & _
                               "network printer" & vbNewline
                
                           Else
                             PRNlist = PRNlist & tblPrinters(sName) & _
                               "local printer" & vbNewline
                           End If
                         End If
                       Next
                '### End enum ###
                
                       Wscript.echo strSession & vbNewline & PRNlist
                       PRNlist = Empty
                
                     Next
                   Next
                 End If
                End If
                
                Function tblPrinters(sName)
                   Dim sep, lName, intSpaces
                   sep = " "
                   If Len(sName) > col1 Then sep = "*"
                
                   ' Trim Printername
                   sName = Left(sName, col1) : lName = Len(Trim(sName))
                   If sep = "*" And lName < col1 _
                     Then sName = Trim(sName) & String(col1-lName,"*")
                
                   lName = Len(sName) : intSpaces = col1 - lName
                   tblPrinters = " - " & sName & space(intSpaces) & sep & "= "
                End Function
                
                Function IsPingable(ByVal strHost)
                  ' http://www.rlmueller.net/PingComputers.htm
                  ' function returns "False" (0) or "True" (-1)
                  If Not IsObject(objShell) _
                    Then Set objShell = _
                      CreateObject("WScript.Shell")
                  With objShell
                    Select Case .Run("%comspec% /c" _
                      & " ping.exe -n 1 -w 750 " & strHost _
                      & " | find/i ""TTL="" >nul 2>&1", 0, True)
                    Case 0
                      IsPingable = True
                    Case Else
                      IsPingable = False
                    End Select
                  End With
                End Function
                \Rems

                This posting is provided "AS IS" with no warranties, and confers no rights.

                __________________

                ** Remember to give credit where credit's due **
                and leave Reputation Points for meaningful posts

                Comment


                • #9
                  Re: Need Help Adjusting VBScript With WMI To Impersonate Logged On User On Remote Mac

                  for some reason the
                  Code:
                       Set colList = objSWbemServices.ExecQuery("Associators of " _
                           & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "}" _
                           & " Where AssocClass=Win32_LoggedOnUser Role=Dependent" )
                  returns an empty collection. I get the correct logonid and there are items in the win32_loggedonuser that have the same logonid, but it won't return the matching user for it.
                  I'll keep trying when I can.

                  Comment

                  Working...
                  X