Eu finalmente encontrei uma maneira de fazer isso no Windows 2000. Foi um processo de várias etapas. Primeiro, eu escrevi este script para ser executado no 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
O Windows 2000 não vem com um executável de logoff, mas há um download do Resource Kit para 2000 que o inclui, e parece que todos os nossos 2000 servidores o possuem. Eu tive que incluir esse código de arquivo logonlock porque há um problema com a diretiva de grupo, onde ele executa um loopback , fazendo com que o script seja executado duas vezes. É possível desativar isso, mas como não estamos 100%, se algum dos servidores precisar dele, nós o deixamos ligado e apenas criamos uma solução alternativa.
Em seguida, eu precisava escrever um script para adicionar isso aos scripts de logon de diretiva de grupo local. Alguns trechos de código para isso:
Set oShell = CreateObject("Wscript.Shell")
strScriptFile = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\system32\GroupPolicy\User\Scripts\scripts.ini"
Esse arquivo scripts.ini é onde o arquivo vbs é adicionado para ser chamado no logon. Será algo parecido com isto:
[Logon]
0CmdLine=C:\MyScript.vbs
0Parameters=
Eu tive que escrever código para adicionar meu script a esse arquivo. Vou deixar os detalhes como um exercício para o leitor. :)
Finalmente, eu tive que modificar o arquivo que encontrei assim:
strGptFile = oShell.ExpandEnvironmentStrings("%SYSTEMROOT%") & "\system32\GroupPolicy\gpt.ini"
O gpt.ini tem algumas linhas que devem ser modificadas para que o script de logon listado acima seja executado. Aqui está o que parece inicialmente:
[General]
gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=0
gPCUserExtensionNames=
Os números de versão podem ser diferentes de zero, e já pode haver IDs nas linhas de nomes. As duas últimas linhas são as que eu tive que modificar para o meu script de logon. Primeiro, o valor da versão deve ser incrementado em 65536 sempre que o arquivo gpt.ini for atualizado. Em segundo lugar, você deve adicionar os dois IDs a seguir à linha gPCUserExtensionNames=
:
{42B5FAAE-6536-11D2-AE5A-0000F87571E3}
{40B66650-4972-11D1-A7CA-0000F87571E3}
Vai acabar parecendo assim:
gPCFunctionalityVersion=0
gPCMachineExtensionNames=
Version=65536
gPCUserExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B66650-4972-11D1-A7CA-0000F87571E3}]
Não se esqueça de incluir os colchetes e o valor da Versão deve ser incrementado a cada vez . Outra coisa que descobri muito mais tarde foi que às vezes a última linha não está no arquivo e deve ser adicionada do zero.
Então, foi preciso muito, mas consegui instalar programaticamente um script de logon. Espero que alguém possa se beneficiar dessa monstruosidade algum dia.