用vbscript更改windows server启动程序:2003年有效,2000年失败

用vbscript更改windows server启动程序:2003年有效,2000年失败,vbscript,windows-server-2000,Vbscript,Windows Server 2000,我正在尝试更改特定用户的启动程序。我有一些在Windows Server 2003上运行良好的代码: Set objUser = GetObject("WinNT://localhost/sysadmin") objUser.TerminalServicesInitialProgram = "C:\myapp.exe" objUser.TerminalServicesWorkDirectory = "C:\" objUser.SetInfo 但是,当我在2000服务器上运行它时,它在第一行失败

我正在尝试更改特定用户的启动程序。我有一些在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年,您可以进入
管理工具->计算机管理->系统工具->本地用户和组->用户
,选择用户的属性,转到
环境
选项卡,并更改
启动程序
下的程序文件名。这会让我认为,如果能在2003年实现这一目标,就必须有办法在2000年进入该房产。在添加新应用程序名称后,我在注册表中搜索了它,希望能在那里更改启动程序,但运气不好


编辑:我为此添加了一个新的测试用户,加入了Nilpo的答案,并通过了创建用户对象的部分,大致如下所示:

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

我遇到了上面提到的相同错误:
对象不支持以下属性或方法:“objUser.TerminalServicesInitialProgram”
,这意味着尝试执行此操作的四种替代方法已失败。有人对此有其他想法吗?

下面是使用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。我相信它很有可能在Windows2000Server上运行

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

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

objUser.SetInfo

我从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
该scripts.ini文件是添加vbs文件以便在登录时调用的位置。它看起来像这样:

[Logon]
0CmdLine=C:\MyScript.vbs
0Parameters=
gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=65536
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]
我必须编写代码才能将脚本添加到该文件中。我将把细节留给读者作为练习。:)

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

strGptFile = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\system32\GroupPolicy\gpt.ini"
ini中有几行必须修改才能使上面列出的登录脚本实际运行。以下是它最初的样子:

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

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

它最终会看起来像这样:

[Logon]
0CmdLine=C:\MyScript.vbs
0Parameters=
gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=65536
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]
别忘了包括方括号,版本值必须每次递增。我后来还发现,有时最后一行根本不在文件中,必须从头开始添加


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

这是有希望的,但到目前为止,我也没能让它发挥作用。我很难找出创建用户对象的完整可分辨名称所需的所有对象。此链接很好地解释了DNs。我为此添加了一个新的测试用户,并通过了使用以下行创建用户对象的部分:Set objUser=GetObject(“LDAP://CN=joe,CN=Users,DC=lab,DC=server,DC=net”)我得到了与我上面提到的相同的错误:对象不支持此属性或方法:“objUser.ternalservicesinitialprogram”我想我可能被卡住了(