Изменение программы запуска Windows Server с помощью VBScript: работает в 2003 году, не работает в 2000 - PullRequest
0 голосов
/ 23 марта 2012

Я пытаюсь изменить стартовую программу для конкретного пользователя. У меня есть код, который отлично работает на 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. Это заставило бы меня думать, что должен быть способ получить доступ к этому свойству в 2000 году, если это можно будет сделать в 2003 году. Я поискал в реестре новое имя приложения после его добавления в надежде, что смогу изменить запуск программы есть, но не повезло.

РЕДАКТИРОВАТЬ : я добавил для этого нового тестового пользователя, включив ответ от 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' Так что это означает, что четыре альтернативных метода для попытки сделать это потерпели неудачу. У кого-нибудь есть другие идеи по этому поводу?

Ответы [ 2 ]

2 голосов
/ 23 марта 2012

Вот еще один метод, использующий 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
0 голосов
/ 16 мая 2012

Я публикую этот ответ от 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 серверов. Я должен был включить этот код файла logonlock, потому что есть проблема с групповой политикой, когда он выполняет действие loopback , в результате чего скрипт запускается дважды. Это можно отключить, но поскольку мы не на 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= 

Номера версий могут быть ненулевыми, и в строках имен уже могут быть идентификаторы. Последние две строки - те, которые мне пришлось изменить для моего сценария входа. Во-первых, значение версии должно увеличиваться на 65536 при каждом обновлении файла gpt.ini. Во-вторых, вы должны добавить следующие два идентификатора в строку 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 должно увеличиваться каждый раз . Еще кое-что, что я обнаружил гораздо позже, заключалось в том, что иногда последняя строка вообще отсутствует в файле и должна добавляться с нуля.

Итак, я потратил массу усилий, но мне удалось программно установить скрипт входа в систему. Я надеюсь, что когда-нибудь кто-нибудь еще сможет извлечь выгоду из этого чудовища.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...