Domanda

I am trying to change the starting program for a particular user. I have some code that works fine on Windows Server 2003:

Set objUser = GetObject("WinNT://localhost/sysadmin")
objUser.TerminalServicesInitialProgram = "C:\myapp.exe"
objUser.TerminalServicesWorkDirectory = "C:\"
objUser.SetInfo

However, when I run it on a 2000 server, it fails on the first line, and I get the following error:

Error: The network path was not found.
Code: 80070035
Source: (null)

I found an alternate way to achieve the same thing:

Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set colUsers = GetObject("WinNT://" & strComputer)
colUsers.Filter = Array("user")
For Each objUser In colUsers
    If (InStr(objUser.Name, "sysadmin")) Then
        objUser.TerminalServicesInitialProgram = "C:\myapp.exe"
        objUser.TerminalServicesWorkDirectory = "C:\"
    End If
Next

Again, this works in 2003, but in 2000, it fails inside the If part of the code, and I get the following error:

Error: Object doesn't support this property or method: 'objUser.TerminalServicesInitialProgram'
Code: 800A01B6
Source: Microsoft VBScript runtime error

In both 2000 and 2003, you can go into Administrative Tools->Computer Management->System Tools->Local Users and Groups->Users, select the properties for the user, go to the Environment tab, and change the program file name under Starting program. That would make me think there has to be a way to access that property in 2000 if it can be done in 2003. I've searched the registry for my new app name after adding it, in hopes that I might be able to change the starting program there, but no luck.

EDIT: I added a new test user for this, incorporating the answer from Nilpo, and got past the part of creating the user object with something approximately like this line:

Set objUser = GetObject("LDAP://CN=joe,CN=Users,DC=lab,DC=server,DC=net")

I get the same error I mentioned above: Object doesn't support this property or method: 'objUser.TerminalServicesInitialProgram' So that means that four alternate methods for attempting to do this have failed. Does anyone have any other ideas for this?

È stato utile?

Soluzione 2

I'm reposting this answer from ServerFault, as I initially started researching this whole problem over there.


I finally found a way to do this in Windows 2000. It was a multi-step process. First, I wrote this script to run at logon:

Set WshNetwork = WScript.CreateObject("WScript.Network")
If WshNetwork.UserName = "sysadmin" Then
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    strLockFile = "C:\logonlock.txt"
    If objFSO.FileExists(strLockFile) Then
        If Now - objFSO.GetFile(strLockFile).DateLastModified < 0.0001 Then 'New file, means was double start, don't run
            objFSO.DeleteFile(strLockFile)
            objFSO.CreateTextFile(strLockFile)
            Set objFSO = Nothing
            WScript.Quit
        End If
    End If
    'File either doesn't exist, or is old, DO run
    If objFSO.FileExists(strLockFile) Then
        objFSO.DeleteFile(strLockFile)
    End If
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
    errResult = objWMIService.Create("C:\loginshell.exe", "C:\", null, intPosID)    
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colProcesses = objWMIService.ExecNotificationQuery ("Select * From __InstanceDeletionEvent " & "Within 1 Where TargetInstance ISA 'Win32_Process'")
    Do Until False = True
        Set objProcess = colProcesses.NextEvent
        If objProcess.TargetInstance.ProcessID = intPosID Then
            objFSO.CreateTextFile(strLockFile)
            Set WshShell = WScript.CreateObject("WScript.Shell")
            WshShell.Run "%COMSPEC% /c ""C:\Program Files\Resource Kit\logoff.exe"" /n /f", 0, False
            Exit Do
        End If
    Loop
Else
    Set WshNetwork = Nothing
End If

Windows 2000 doesn't come with a logoff executable, but there is a Resource Kit download for 2000 that includes it, and it appears that all our 2000 servers have it. I had to include this logonlock file code because there is an issue with the group policy, where it enacts a loopback action, causing the script to run twice. It is possible to turn that off, but because we're not 100% if any of the servers may need it, we left it on and just came up with a workaround.

Next, I needed to write a script to add this to the local group policy logon scripts. A few snippets of code for this:

Set oShell = CreateObject("Wscript.Shell") 
strScriptFile = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\system32\GroupPolicy\User\Scripts\scripts.ini"

That scripts.ini file is where the vbs file is added in order to be called at logon. It will look something like this:

[Logon]
0CmdLine=C:\MyScript.vbs
0Parameters=

I had to write code to add my script to that file. I'll leave the details as an exercise for the reader. :)

Finally, I had to modify the file I found thus:

strGptFile = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\system32\GroupPolicy\gpt.ini"

gpt.ini has a few lines that must be modified to make the logon script listed above actually run. Here's what it looks like initially:

[General]
gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=0
gPCUserExtensionNames= 

The version numbers could be nonzero, and there could already be IDs on the names lines. The last two lines are the ones I had to modify for my logon script. First, the version value has to be incremented by 65536 whenever the gpt.ini file is updated. Second, you must add the following two IDs to the gPCUserExtensionNames= line:

{42B5FAAE-6536-11D2-AE5A-0000F87571E3} {40B66650-4972-11D1-A7CA-0000F87571E3}

It will end up looking something like this:

gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=65536
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]

Don't forget to include the square brackets, and the Version value has to be incremented every time. Something else I discovered much later on was that sometimes the last line is not in the file at all, and must be added from scratch.

So, it took a ton of playing around, but I was able to programmatically install a logon script. I hope someone else can benefit from this monstrosity someday.

Altri suggerimenti

Here's another method using WMI:

Const STARTUP_PROGRAM = "C:\myapp.exe"
Const STARTUP_FOLDER = "c:\"

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery _
    ("Select * from Win32_TSEnvironmentSetting")

For Each objItem in colItems
    errResult = objItem.InitialProgram(STARTUP_PROGRAM, STARTUP_FOLDER)
Next

What you are finding out so painstakingly is that none of these methods are supported on Windows 2000. In fact, every one of them is only supported on Windows XP and newer.

However, there is one other way using LDAP. And I believe there is a good possibility that it works on Windows 2000 Server.

Set objUser = GetObject _
    ("LDAP://cn=MyerKen,ou=Management,dc=NA,dc=fabrikam,dc=com")

objUser.TerminalServicesInitialProgram = "C:\myapp.exe"
objUser.TerminalServicesWorkDirectory = "c:\"

objUser.SetInfo
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top