StdRegProv creates user profile

Anything VBScript-related, including Windows Script Host, WMI, ADSI, and more.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
awmueller
Posts: 2
Joined: Fri Dec 07, 2007 12:38 am

StdRegProv creates user profile

Post by awmueller » Fri Dec 07, 2007 12:38 am

Guys,

When I run the following script on a client OS (2000 and XP) a local user profile is created for the user that is executing the script but when I run it on a server OS (2000 and 2003) it doesn't create a profile. The profile is created when the first method is called (EnumValues).

This section of script is only part of a larger one that scans enterprise networks (23000 clients) and I don't want to have profiles 'hanging around' on every client. I get the same results if I use a Domain Admin account or just a normal user account that is a member of the local Administrators group on each of the machines. Any insight would be greatly appreciated.

Heres the code (sorry but formatting goes away outside PrimalScript):

'=========================================================================='' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0'' NAME: GatherMachineData.vbs'' AUTHOR: Aaron Mueller' DATE : 10/11/2007'' COMMENT: Data Gathering script (WMI and Remote Registry) (Version 1.0)'' Version 1.0' Modifications:' Initial release (broken out from DataGatheringScript)''==========================================================================Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002Const wbemFlagConnectUseMaxWait = &h80Const WbemAuthenticationLevelPkt = 4 ' Short name: Pkt - Authenticates that all data received is from the expected client.Const wbemImpersonationLevelImpersonate = 3 ' Short name: Impersonate - Allows objects to use the credentials of the caller. ' This is the recommended impersonation level for Scripting API for WMI calls.
Dim g_strComputerFQDN, strNameSpace, strUser, strPassword, strLocaleDim strAuthority, iSecurityFlags, objLocator, objSWbemServices, objRegDim strKeyPath, strValueName, intRetVal, arrValueNames(), arrValueTypes()
'g_strComputerFQDN = "xppromachine.test.local"'g_strComputerFQDN = "srv2003eemember.test.local"g_strComputerFQDN = "server2000adv.test.local"strNameSpace = "rootdefault"strUser = ""strPassword = ""strLocale = ""strAuthority = ""iSecurityFlags = CLng( wbemFlagConnectUseMaxWait )'' Start the WMI queries'Set objLocator = CreateObject("WbemScripting.SwbemLocator")objLocator.Security_.AuthenticationLevel = wbemAuthenticationLevelPktobjLocator.Security_.Privileges.AddAsString "SeSecurityPrivilege"objLocator.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonateOn Error Resume NextSet objSWbemServices = objLocator.ConnectServer( g_strComputerFQDN, strNameSpace, strUser, strPassword, strLocale, strAuthority, iSecurityFlags )Set objReg = objSWbemServices.Get("StdRegProv")'Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate,(Security)}!" & g_strComputerFQDN & "rootdefault:StdRegProv")If ( Err.Number <> 0 ) Then On Error GoTo 0 WScript.Echo "No Access to Registry - Error: " & Err.NumberElse On Error GoTo 0 strKeyPath = "SYSTEMCurrentControlSetControlPriorityControl" strValueName = "Win32PrioritySeparation" On Error Resume Next intRetVal = objReg.EnumValues( HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes ) If ( Err.Number <> 0 ) Then On Error goto 0 WScript.Echo "Error " & intRetVal & " occurred reading registry key " & strKeyPath Else On Error goto 0 WScript.Echo "Registry read successful" End IfEnd If

User avatar
awmueller
Posts: 2
Joined: Fri Dec 07, 2007 12:38 am

StdRegProv creates user profile

Post by awmueller » Sat Dec 08, 2007 5:54 am

Here is the whole scenario:

Machines: Fully patched Windows 2003 w/SP1 Domain Controller with all FSMO roles, DHCP and DNS, a fully patched Windows 2003 w/SP1 member server, and a fully patched Windows XP w/SP2.

Accounts: I added a domain user (test.user) with no privileges. I made the test.user a member of the local administrators group on the member server and the XP machine.

Test Scenario1: Logon the XP machine as test.user and execute your modified script from this post against the member server and no profile is created on the member server. I log on as the domain administrator and run the script - no profile is created on the member server. I then open a command window using 'runas' with the test.user account and execute the script - no profile is created on the member server. Logoff the XP machine.

Test Scenario2: Logon the member server as test.user and execute the modified script against the XP machine and a profile is created for the test.user account on the XP machine (this is the same script except the machine name was changed). I delete the test.user profile from the XP machine. I logon to the member server as the domain admin and execute the script - profile created on the XP machine. Delete profile and use 'runas' to execute as test.user - profile created on the XP machine.

I've repeated this scenario using 2000 server, 2000 workstation and get the same results as above - if I run the script against a remote "client" OS, a profile is created on that machine. If I run the script against a remote "server" OS, no profile is created on that machine. It doesn't matter which context I use to run the script as long as the user is a member of the local administrators group on the remote computer.

Since I don't log into the remote machine directly (I only authentice), I'm not sure why I should get a profile created at all. I was surprised when I recently started running the scripts against clients and this started happening.

I'm sure that I'll figure out how to "clean up" after the script runs against a client but I would really like to know why the same script behaves differently on a server OS than it does on a client OS.

User avatar
jvierra
Posts: 13717
Joined: Tue May 22, 2007 9:57 am
Contact:

StdRegProv creates user profile

Post by jvierra » Sun Dec 09, 2007 5:37 am

Some testing verifies what you have seen. On XP machines a remote profile is created when using StdRegProv. This may be a requirement for loading the registry although I can't see why.

We should search the knowledgebase to see if this has been noted.

There are fundamental differences between server and client products that may also cominto play. Some more detailed docs on this would be helpful.

User avatar
contras
Posts: 1
Joined: Mon Dec 10, 2007 1:38 am

StdRegProv creates user profile

Post by contras » Mon Dec 10, 2007 1:47 am

Nevertheless, quering remote registry with reg.exe does not create profile on XP machines. So questions are what API does reg.exe use for reaching remote registry and is there a way to use this API from WHS.

User avatar
jvierra
Posts: 13717
Joined: Tue May 22, 2007 9:57 am
Contact:

StdRegProv creates user profile

Post by jvierra » Mon Dec 10, 2007 5:33 am

Here is a sippet or two of code that can get remote registry keys. It is available on XP at least and should be available on WS2003. It uses AxtiveDS.


The code gets registry and file security descriptors and partially decoides to SDDL.

There are a couple of other method calls that willretrieve the key values. The key is specified with the computer name as part of the key path. This class uses teh extended registry API in it's implementation and has been around in some form since Windows 2000 Server.

Sorry I don't have time to convert it to a remote registry function but most of the info on how to use it is in the code. The SDK constants are in teh SDK or are defined on "AxtiveDS" control. O was usinig this under MSAxxess which exposes these constants if a reference is set. TO use in sxript you will need to provide some "Const" from the SDK. This is one thing I would need to finish to fibish the port to script.

This was part of a project I was contracted to do but theclient cancelled adter I had about 20 hours into this conversion. They insisted that there was a direct way to get registry SDDL from any Windows based system using only script. I think theey are still searching as I haven't seen ther tool working yet.

Windows Vista and beyond have this capability built into WMI classes. In Windows we have only had SUBINACL to retrieve registry SDDL and REG to retrieve remote registry values.

If I get time I might convert this and deliver it asd a blog as it is an untouched but useful technique. For anyone who may wish t do this before I can get to it the following code might be of some help.

Code: Select all

Sub test()
    Debug.Print GetObjectSDDL("file", "c:boot.ini")(0)
    Debug.Print GetObjectSDDL("registry", "omegaHKEY_LOCAL_MACHINESOFTWAREMicrosoft")(0)
End Sub
Function GetObjectSDDL(object_type, object_path)
    ' object_type = "file"
    '               "share"
    '               "registry"
    Dim oType
    Select Case UCase(object_type)
        Case "FILE": oType = 1
        Case "SHARE": oType = 2
        Case "REGISTRY": oType = 3
        Case Else
             GetObjectSDDL = "Bad type"
            Exit Function
    End Select
    Dim ad     'As New ActiveDs.ADsSecurityUtility
    Dim sd     'As ActiveDs.SecurityDescriptor
    Dim sacl  'As Object ActiveDs.AccessControlList
    Dim dac l 'As Object ActiveDs.AccessControlList
    Dim sddl  ' Securty Descriptor Definition Language String
    
    Set ad = CreateObject("ADsSecurityUtility")
    Set sd = ad.GetSecurityDescriptor(object_path, oType, 1)
    
    sddl = ConvertSDOptionsToSDDL(sd)
    sddl = sddl & SDControlCOnvertToSDDL(sd.control)
    sddl = sddl & ACEConvertToSDDL(sd.SystemAcl)
    sddl = sddl & ACEConvertToSDDL(sd.DiscretionaryAcl)
    
     GetObjectSDDL = sddl
End Function

Function ConvertSDOptionsToSDDL(sd)
    Dim sddl
    
    sddl = "("
    sddl = sddl & sd.Owner & ","
    sddl = sddl & sd.DaclDefaulted & ","
    sddl = sddl & sd.SaclDefaulted & ","
    sddl = sddl & sd.GroupDefaulted & ","
    sddl = sddl & sd.OwnerDefaulted & ","
    sddl = sddl & sd.Revision
    sddl = sddl & ")"
    ConvertSDOptionsToSDDL = sddl
End Function
Function SDControlCOnvertToSDDL(sd_control)
    Dim sddl
    sddl = 0
    
    If sd_control And ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ Then sddl = sddl + ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ
    If sd_control And ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED Then sddl = sddl + ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED
    If sd_control And ADS_SD_CONTROL_SE_DACL_DEFAULTED Then sddl = sddl + ADS_SD_CONTROL_SE_DACL_DEFAULTED
    If sd_control And ADS_SD_CONTROL_SE_DACL_PRESENT Then sddl = sddl + ADS_SD_CONTROL_SE_DACL_PRESENT
    If sd_control And ADS_SD_CONTROL_SE_DACL_PROTECTED Then sddl = sddl + ADS_SD_CONTROL_SE_DACL_PROTECTED
    If sd_control And ADS_SD_CONTROL_SE_GROUP_DEFAULTED Then sddl = sddl + ADS_SD_CONTROL_SE_GROUP_DEFAULTED
    If sd_control And ADS_SD_CONTROL_SE_OWNER_DEFAULTED Then sddl = sddl + ADS_SD_CONTROL_SE_OWNER_DEFAULTED
    If sd_control And ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ Then sddl = sddl + ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ
    If sd_control And ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED Then sddl = sddl + ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED
    If sd_control And ADS_SD_CONTROL_SE_SACL_DEFAULTED Then sddl = sddl + ADS_SD_CONTROL_SE_SACL_DEFAULTED
    If sd_control And ADS_SD_CONTROL_SE_SACL_PRESENT Then sddl = sddl + ADS_SD_CONTROL_SE_SACL_PRESENT
    If sd_control And ADS_SD_CONTROL_SE_SACL_PROTECTED Then sddl = sddl + ADS_SD_CONTROL_SE_SACL_PROTECTED
    If sd_control And ADS_SD_CONTROL_SE_SELF_RELATIVE Then sddl = sddl + ADS_SD_CONTROL_SE_SELF_RELATIVE
    
    SDControlCOnvertToSDDL = "(" & sddl & ")"
    
End Function
Function ACEConvertToSDDL(acl)
    Dim ace 'As ActiveDs.AccessControlEntry
    Dim sddl
    
    If Not (acl Is Nothing) Then
    
        For Each ace In acl
            ace_sddl = "("
            ace_sddl = ace_sddl & ace.Trustee
            ace_sddl = ace_sddl & "}"
            sddl = sddl & ace_sddl
        Next
        
        
    End If
    
    ACEConvertToSDDL = sddl
    
End Function
Function Uni2Ansi(s)
    For i = 6 To Len(s) Step 2
        Uni2Ansi = Uni2Ansi & Mid(s, i, 1)
    Next
End Function
jvierra2007-12-10 12:50:15

Locked