0

我正在尝试更改特定用户的启动程序。我有一些在 Windows Server 2003 上运行良好的代码:

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

但是,当我在 2000 服务器上运行它时,它在第一行失败,并且出现以下错误:

错误:未找到网络路径。
代码:80070035
来源:(空)

我找到了另一种实现相同目标的方法:

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

同样,这在 2003 年有效,但在 2000 年,它If在代码部分内部失败,我收到以下错误:

错误:对象不支持此属性或方法:'objUser.TerminalServicesInitialProgram'
代码:800A01B6
来源:Microsoft VBScript 运行时错误

在 2000 和 2003 中,您可以进入Administrative Tools->Computer Management->System Tools->Local Users and Groups->Users,选择用户的属性,转到Environment选项卡,然后在Starting program. 这会让我认为如果可以在 2003 年完成,那么必须有一种方法可以在 2000 年访问该属性。添加后我在注册表中搜索了我的新应用程序名称,希望我能够更改在那里启动程序,但没有运气。

编辑:我为此添加了一个新的测试用户,并结合了 Nilpo 的答案,并通过了类似于以下行的内容创建用户对象的部分:

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

我得到了与上面提到的相同的错误:Object doesn't support this property or method: 'objUser.TerminalServicesInitialProgram' 这意味着尝试执行此操作的四种替代方法都失败了。有没有人对此有任何其他想法?

4

2 回答 2

2

这是使用 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

您费力地发现,Windows 2000 不支持这些方法。事实上,只有 Windows XP 和更新版本才支持这些方法。

但是,还有另一种使用 LDAP 的方法。而且我相信它很有可能在 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
于 2012-03-23T05:05:22.550 回答
0

我从 ServerFault 重新发布了这个答案,因为我最初开始在那里研究整个问题。


我终于在 Windows 2000 中找到了一种方法。这是一个多步骤的过程。首先,我编写了这个脚本以在登录时运行:

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 不附带注销可执行文件,但有一个用于 2000 的资源工具包下载,其中包括它,而且似乎我们所有的 2000 服务器都有它。我必须包含此登录锁定文件代码,因为组策略存在问题,它执行环回操作,导致脚本运行两次。可以将其关闭,但因为我们不是 100% 是否有任何服务器可能需要它,所以我们将其保持打开状态,只是想出了一个解决方法。

接下来,我需要编写一个脚本来将其添加到本地组策略登录脚本中。为此的一些代码片段:

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

该 scripts.ini 文件是添加 vbs 文件以便在登录时调用的位置。它看起来像这样:

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

我必须编写代码才能将我的脚本添加到该文件中。我将把细节留给读者作为练习。:)

最后,我不得不修改我找到的文件:

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

gpt.ini 有几行必须修改才能使上面列出的登录脚本真正运行。这是它最初的样子:

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

版本号可能不为零,并且名称行上可能已经有 ID。最后两行是我必须为我的登录脚本修改的行。首先,每当更新 gpt.ini 文件时,版本值必须增加 65536。其次,您必须将以下两个 ID 添加到该gPCUserExtensionNames=行:

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

它最终会看起来像这样:

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

不要忘记包括方括号,并且每次都必须增加 Version 值。我后来发现的另一件事是,有时最后一行根本不在文件中,必须从头开始添加。

所以,花了很多时间,但我能够以编程方式安装登录脚本。我希望有一天其他人可以从这个怪物中受益。

于 2012-05-15T21:28:10.417 回答