限制用户多点并发登录之二“脚本”篇
在这篇文章中,我将为大家介绍如何通过登录/注销脚本来限制用户的多点并发登录。这是一系列文章之一,如果您对前面的测试环境不是很了解,或者对这个话题比较感兴趣,那么请参看前面的文章:
《限制用户多点并发登录之一“登录到”篇》
废话就不多说了,请看如下操作:
1) 打开GPMC,为Test OU创建并链接一条名为“限制用户多点并发登录”的GPO。如图1和2所示。如果没有安装GPMC组策略管理控制台,请直接在Test OU右键属性上创建并链接一条GPO。
附件
- (45.51 KB)
-
2008-1-14 14:25
- (9.36 KB)
-
2008-1-14 14:25
2) 将以下内容分别存为logon.vbs和logoff.vbs
以下内容请存为logon.vbs
Dim oNet, sUser, sComputer, ServerLog
ServerLog = "\\dc.a.com\log$\"
Set oNet = CreateObject("Wscript.Network")
sUser = oNet.UserName
sComputer = oNet.ComputerName
Set oNet = Nothing
Dim fso, f1, WshShell, argu, alllog, lastlog
Dim FileName
FileName=ServerLog & sUser & ".txt"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not (fso.FileExists(FileName)) Then
Set f1 = fso.CreateTextFile(FileName,True)
f1.WriteLine sUser & " " & sComputer
f1.Close
Set WshShell = Wscript.CreateObject("Wscript.Shell")
argu = FileName & "/T/E/G" & sUser & ":f /R Everyone"
WshShell.run("cacls " & argu)
Set WshShell = Nothing
End If
Set f1 = fso.OpenTextFile(FileName, 1, True)
alllog = f1.readall
f1.Close
Set f1 = fso.OpenTextFile(FileName, 1, True)
lastlog = f1.readline
f1.Close
If Left(lastlog, 5) = "logon" Then
If InStr(lastlog,sComputer) < 1 Then
Set f1 = fso.OpenTextFile(FileName, 2, True)
f1.WriteLine (lastlog & Chr(13) & Chr(10) & "FailLogon:" & Now() & " " & sUser & " at " & scomputer & Chr(13) & Chr(10) & alllog)
f1.Close
Set WshShell = Wscript.CreateObject("Wscript.Shell")
Dim i,OldComputer
i=InStr(lastlog,"at")
OldComputer=Right(lastlog,Len(lastlog)-i-2)
WshShell.popup "对不起:此账号已经在 " & OldComputer & " 上登入使用!出现此提示,如是你还没有登录,说明你的账号被盗,请及时上报IT支持,谢谢合作!!!" , 30
Set WshShell = Nothing
Dim os, retcode
For Each os In GetObject("Winmgmts:{impersonationLevel=impersonate,(shutdown,remoteshutdown)}!//" + sComputer).InstancesOf("Win32_OperatingSystem")
retcode = os.Win32ShutDown(4, 0)
Next
Wscript.quit
Else
Set f1 = fso.OpenTextFile(FileName, 2, True)
f1.WriteLine ("logon: " & Now() & " " & sUser & " at " & sComputer & Chr(13) & Chr(10) & alllog)
f1.Close
End If
Else
Set f1 = fso.OpenTextFile(FileName, 2, True)
f1.WriteLine ("logon: " & Now() & " " & sUser & " at " & sComputer & Chr(13) & Chr(10) & alllog)
f1.Close
End If
Set f1 = Nothing
Set fso = Nothing
Wscript.quit
以下内容请存为logoff.vbs
dim oNet,sUser,sComputer,ServerLog
ServerLog = "\\dc.a.com\log$\"
set oNet=createobject("Wscript.Network")
sUser=oNet.UserName
sComputer=oNet.ComputerName
set oNet=nothing
dim fso,f1,alllog,lastlog
Dim FileName
FileName=ServerLog & sUser & ".txt"
set fso=createobject("Scripting.filesystemobject")
set f1=fso.opentextfile(FileName,1,true)
lastlog=f1.readline
f1.close
set f1=fso.opentextfile(FileName,1,true)
alllog=f1.readall
f1.close
if left(lastlog,5)="logon" Then
If InStr(lastlog,sComputer) > 0 Then
Set f1=fso.opentextfile(FileName,2,true)
f1.writeline("logoff: " & Now() & " " & suser & " at " & scomputer & Chr(13) & chr(10) & alllog)
f1.close
End If
end if
set f1=nothing
set fso=nothing
wscript.quit
说明:
1. 运行该登录和注销脚本后,会在共享文件夹中写下log文件,其中记录了域用户在工作站上的登录注销记录
2. 请确保用户对共享文件夹有合适的写权限,否则脚本运行肯定报错
3. 脚本中共享文件夹路径\\dc.a.com\log$\,请替换为自己实际的路径,最好为共享文件夹设置为隐藏共享,避免用户浏览到里面的内容而加以改动
3) 编辑“限制用户多点并发登录”策略,找到“用户配置”“Windows设置”“脚本(登录/注销)”。将以上两个脚本分别部署为登录和注销脚本,如图3和4
附件
- (57.45 KB)
-
2008-1-14 14:27
- (58.92 KB)
-
2008-1-14 14:27
4)在DC上的设置就完成了。回到客户端ClientA,执行一下命令gpupdate /force后注销再登录,或者直接重启计算机让其生效。同样,我们拿Bob这个帐号来验证。在ClientA上输入Bob的用户名和密码后,成功登录。如图5为Bob登录后,运行set命令得到的结果,从中我们可以看出,Bob已登录到ClientA上。
附件
- (66.02 KB)
-
4) 同理,回到客户端ClientB上,执行一下命令gpupdate /force后注销再登录,或者直接重启计算机让其生效。我们仍然拿Bob这个帐号来验证。在ClientB上输入Bob的用户名和密码,如图6,尽管能登录进去,但是很快就可以看到如图7的信息,提示Bob这个帐号已经在ClientA上登录。点击“确定”或者关闭按钮后(或者直接等待30秒),系统就会自动注销,如图8所示。
附件
- (27.61 KB)
-
2008-1-14 14:28
- (50.68 KB)
-
2008-1-14 14:28
- (36.46 KB)
-
2008-1-14 14:28
5) 上面介绍的方法简单又实用,只需要在服务端部署脚本即可,不需要客户端任何额外的设置。能确保任何时刻都只有一个帐号在使用。而且,提供的日记记录信息也有不少用处,至少比在DC上查看安全审核策略要来得更直观。以下我简单介绍一下log中记录的信息:
附件
- (32.14 KB)
-
2008-1-14 14:29
Logon一行记录的是某某用户于某某时间成功登录了哪台工作站;该处值为Logoff时则表示,某某用户于某某时间成功从哪台工作站注销了。
FailLogon则记录的是登录失败的信息。为什么会登录失败?是因为当前使用的帐号已经在别处登录。
从图中第二行记录可以看出,Bob这个帐号试图在ClientB上登录,但是因为当前已经在ClientA上登录(第一行Logon记录),所以就“FailLogon”啦。
需要说明的是,除第一行外,日志都会以时间的先后顺序将登录注销事件记录下来,后发生的事件靠上。但是第一行例外,它记录的是当前某帐号目前在哪台工作站上,如果再次用这个帐号在别处登录,那么登录脚本就首先会检查第一行记录,如果记录的是logon,而且at后面的工作站不和当前工作站相同的话,就会触发注销脚本,然后给出提示信息。如果第一行记录的是logoff,则表明该帐号当前已经处于注销未登录状态,所以就不会再检测at后面的工作站名,直接让该帐号可以再在别处登录。这也是整个登录脚本执行的原理。如上图所示,第一行记录就表明,Bob这个帐号已经在ClientA上登录,且没有注销,不能在别处登录。只能在ClientA上登录。
说到这,也许您会问我,如果我用Bob这个帐号在ClientA上登录后,突然停电了,根本就没有按正常的方式运行注销脚本,那么该Bob帐号还能在别处登录吗?
问题很好,我们来分析一下。突然停电,Bob就肯定不会运行注销脚本,既然不会运行注销脚本,那么就不会往log文件中的第一行添加logoff字段,根据前面介绍的脚本执行原理可以得出结论,Bob这个帐号肯定就不能在别处登录了。因为脚本在检测的时候,会发现log文件里面依然记录的是Bob还在ClientA上登录着呢。
如果我想再用Bob在别处登录,那如何解决这个问题呢?
解决方法有两个:
1. 将bob.txt日志文件中的第一行logon改为logoff,让脚本在检测的时候认为Bob已经注销,从未允许在别处登录
2. 不修改logon值,直接修改at 后面的工作站名。例如我将ClientA改为ClientB,则脚本会以为Bob这个用户当前登录的是ClientB,从而允许“继续在ClientB上登录”。