|
Компьютерный форум OSzone.net » Серверные продукты Microsoft » Microsoft Windows NT/2000/2003 » [решено] Как ограничить количество запущенных копий приложения на терминальном сервере? |
|
[решено] Как ограничить количество запущенных копий приложения на терминальном сервере?
|
Vladimir Сообщения: 1070 |
Профиль | Отправить PM | Цитировать
Q: Можно ли на терминальном сервере Windows Server 2003 ограничить одновременное количество запусков определённой программы терминальным пользователям?
Цель: Имея Z пользователей терминальных, и N лицензий на Office 2003, как на сервере ограничить количество загрузок приложений Office, не более N-ти одновременно? Возможно ли это? A: Стандартных способов ограничения по количеству копий процесса я не смог найти, однако в WMI командах есть возможность выполнять отображение количество запущенных процессов. Поэтому я обратился к Центру сценариев и составил небольшой сценарий, который, работая резидентно – отслеживает процессы загрузки приложения , например блокнота (notepad.exe) или калькулятора (calc.exe) - по счетчику отслеживает количество работающих приложений. При этом, он виден как процесс wscript.exe в диспетчере задач. В целях понимания работы программы даны всплывающие окна, потом их можно убрать. * Для добавления других приложений можно модифицировать данные файла конфигурации (например, вместо notepad.exe указать winword.exe, добавить WinRAR и т.д.) ** Сценарий, указанный тут, предназначем для запуска в приложении Cscript.exe. Поэтому если программой для запуска сценариев по умолчанию она не является на вашей системе - вам необходимо добавить перед сценарием имя программу "cscript", например, cscript watcher.vbs. Скрипт watcher.vbs Set Args = WScript.Arguments ' ******************************************* ' Script, that allow to limit quantity of the ' started applications on a terminal server. ' The names of applications and the maximum ' quantity of simultaneously started spears ' are stored in config file. ' ' @authors: SkyF, hasherfrog ' @site: oszone.net ' CONST FIELDS = 3 CONST PSNAME = 0 CONST PSNUMB = 1 CONST PSMAXN = 2 Dim thePsArray ( ) Dim nToWatch nToWatch = 0 Function AddPsToWath( name, number ) ReDim Preserve thePsArray ( FIELDS, nToWatch ) thePsArray(PSNAME, nToWatch) = name thePsArray(PSNUMB, nToWatch) = number thePsArray(PSMAXN, nToWatch) = number addPsToWatch = nToWatch nToWatch = nToWatch + 1 End Function ' ******************************************* Sub ReadPsWatchFile(filename) Dim fso, f ' On Error Resume Next Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.OpenTextFile(filename, 1, False) if Err.Number<>0 then call Error_(0) else while not f.atEndOfStream s = f.ReadLine ms = Split(s, " ", -1, vbBinaryComapre) s1 = ms(0) n2 = CInt(ms(1)) n = AddPsToWath(s1, n2) Err.Clear wend f.Close end if End Sub ' ******************************************* Sub StartUpWatcher() strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colMonitoredEvents = objWMIService.ExecNotificationQuery _ ("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE " _ & "Targetinstance ISA 'Win32_Process'") Do While 1 Set objLatestProcess = colMonitoredEvents.NextEvent For psn=0 to nToWatch-1 If objLatestProcess.TargetInstance.Name = thePsArray(PSNAME, psn) Then Select Case objLatestProcess.Path_.Class Case "__InstanceCreationEvent" thePsArray(PSNUMB, psn) = thePsArray(PSNUMB, psn) - 1 If thePsArray(PSNUMB, psn) < 0 then objLatestProcess.TargetInstance.Terminate Wscript.Echo "Вы запустили лишнюю копию программы "& objLatestProcess.TargetInstance.Name _ & " - разрешенный лимит только " & thePsArray(PSMAXN, psn) End If Case "__InstanceDeletionEvent" thePsArray(PSNUMB, psn) = thePsArray(PSNUMB, psn) + 1 End Select End If Next Loop End Sub ' ******************************************* for i=0 to Args.count-1 If Args(i) = "-f" Then iaFilename = Args(i+1) End If Next If iaFilename<>"" Then Set fso = CreateObject("Scripting.FileSystemObject") If (fso.FileExists(iaFilename)) Then Call ReadPsWatchFile(iaFilename) If nToWatch=0 Then Wscript.Echo "File is empty." Else Call StartUpWatcher() End If Else Wscript.Echo "File exists not." End If Else Wscript.Echo "watcher.vbs -f config.txt" End If После запуска сценария - он запускается резидентно и выполняет перехват событий запуска процесса, сравнивает название процесса с заранее заданными и в случае совпадения - передает управление счетчику. Если лимит будет исчерпан - для нового процесса будет вызван метод завершения. Процесс может быть запущен из любой терминальной сессии, а сценарий должен запускаться от имени системы (те при запуске ОС) Любые изменения приветствуются! ЗЫ полезные ссылки: http://www.microsoft.com/technet/scr.../shop0505.mspx http://www.microsoft.com/technet/com...ts/sg0103.mspx http://msdn.microsoft.com/library/de..._processes.asp (тут иной вариант - через получение списка из процессов – можно тоже попробовать) Благодарим за доработку скрипта hasherfrog |
|
Отправлено: 16:53, 15-04-2006 |
Новый участник Сообщения: 2
|
Профиль | Отправить PM | Цитировать добавить в список автозапускаемых программ строку
Прошу прощения, а где это надо добавлять? Сервер 2008 SP2, пользователь Администратор логинится автоматически. Думал, в свойствах пользователя прописать файл, который запускался бы при запуске - бесполезно (выдает ошибку при логине и сеанс завершается). Добавил в папку "Автозагрузка" - не работает! Через планировщик пытался (запускаю от имени SYSTEM) - задание просто висит в статусе "Это задание выполняется в настоящий момент", в процессах он есть, но ничего не происходит Плюнул на все, зашел терминально под Администратором, запустил, всё работает! Только если другие пользователи запускают лишние копии, то ругань идет в сеанс Администратору. Убрал из скрипта строки: Wscript.Echo "Вы запустили лишнюю копию программы "& objLatestProcess.TargetInstance.Name _ & " - разрешенный лимит только " & thePsArray(PSMAXN, psn) В общем, помогите правильно прописать этот скрипт в автозагрузке (если можно в подробностях - как для дебилов). Спасибо! |
Отправлено: 20:01, 28-08-2011 | #31 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Железных Дел Мастер Сообщения: 24528
|
Профиль | Сайт | Отправить PM | Цитировать Цитата S_M:
Поставь его запуск в соотв. раздел реестра, подраздел RUN, пусть стартует под консольной учеткой, если таковая предусмотрена. |
|
------- Отправлено: 21:10, 28-08-2011 | #32 |
Новый участник Сообщения: 2
|
Профиль | Отправить PM | Цитировать Поставь его запуск в соотв. раздел реестра, подраздел RUN
Поставил, перегрузил сервер - ничего не поменялось. В процессах программы нет, ограничения не работают. Блин. Есть у кого-нибудь готовый кусок реестра с прописанной программулиной? Ну, капец просто. Элементарщина вроде, а не получается. Кошмар. пусть стартует под консольной учеткой Это как? |
Отправлено: 21:54, 31-08-2011 | #33 |
Железных Дел Мастер Сообщения: 24528
|
Профиль | Сайт | Отправить PM | Цитировать Цитата S_M:
|
|
------- Отправлено: 22:13, 31-08-2011 | #34 |
Новый участник Сообщения: 1
|
Профиль | Отправить PM | Цитировать Запускается на хосте один раз резидентно. Всё оттестировано и работает.
Set Args = WScript.Arguments ' ******************************************* ' Script, that allow to limit quantity of the ' started applications on a terminal server. ' The names of applications and the maximum ' quantity of simultaneously started spears ' are stored in config file. ' ' @authors: SkyF, hasherfrog ' @site: oszone.net ' CONST FIELDS = 3 CONST PSNAME = 0 CONST PSNUMB = 1 CONST PSMAXN = 2 Dim thePsArray ( ) Dim nToWatch nToWatch = 0 Function AddPsToWath( name, number ) ReDim Preserve thePsArray ( FIELDS, nToWatch ) thePsArray(PSNAME, nToWatch) = name thePsArray(PSNUMB, nToWatch) = number thePsArray(PSMAXN, nToWatch) = number addPsToWatch = nToWatch nToWatch = nToWatch + 1 End Function ' ******************************************* Sub ReadPsWatchFile(filename) Dim fso, f ' On Error Resume Next Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.OpenTextFile(filename, 1, False) if Err.Number<>0 then call Error_(0) else while not f.atEndOfStream s = f.ReadLine ms = Split(s, " ", -1, vbBinaryComapre) s1 = ms(0) n2 = CInt(ms(1)) n = AddPsToWath(s1, n2) Err.Clear wend f.Close end if End Sub 'Протоколирование в одноимённый log файл Sub AppLog( aMessage ) Dim fso, f, flnm, renflnm, dtmstr flnm = Replace(Wscript.ScriptFullName,".vbs",".log") Set fso = CreateObject("Scripting.FileSystemObject") If (fso.FileExists(flnm)) Then Set f = fso.GetFile(flnm) If f.Size > 100000 then dtmstr = Replace(Replace(Replace(FormatDateTime(Now),"/","-"),":",".")," ","-") renflnm = Replace(flnm,".log","-" & dtmstr & ".log") f.Move renflnm End If Set f = Nothing End If Set f = fso.OpenTextFile(flnm, 8, True) f.WriteLine FormatDateTime(Now) & " - " & aMessage f.Close End Sub '******************************************** Function CountUserProcess( ProcessName, ProcessId ) Dim strNameOfUser,strOwnerProcess,strDomain CountUserProcess = 0 Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId=" & CStr(ProcessId) ) For Each objProcess in colProcessList colProps = objProcess.GetOwner(strOwnerProcess, strDomain) Next AppLog "-- ProcessName-" & ProcessName & ", ProcessId-" & CStr(ProcessId) & ", strOwnerProcess-" & strOwnerProcess & ", strDomain-" & strDomain Set colProcessList = Nothing Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where Name='" & ProcessName & "'") For Each objProcess in colProcessList colProps = objProcess.GetOwner(strNameOfUser, strDomain) AppLog "strNameOfUser-" & strNameOfUser if strNameOfUser = strOwnerProcess then CountUserProcess = CountUserProcess + 1 end if Next End Function ' ******************************************* Sub StartUpWatcher() Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set colMonitoredEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE Targetinstance ISA 'Win32_Process'") Do While 1 Set objLatestProcess = colMonitoredEvents.NextEvent For psn=0 to nToWatch-1 If objLatestProcess.TargetInstance.Name = thePsArray(PSNAME, psn) Then If objLatestProcess.Path_.Class = "__InstanceCreationEvent" Then psCount = CountUserProcess(objLatestProcess.TargetInstance.Name, objLatestProcess.TargetInstance.ProcessId) 'Wscript.Echo thePsArray(PSNAME, psn), psCount iF psCount > thePsArray(PSNUMB, psn) Then Applog "Count of process " & objLatestProcess.TargetInstance.Name & " is " & Cstr(psCount) & "... Terminate last process." objLatestProcess.TargetInstance.Terminate End If End If End If Next Loop End Sub ' ******************************************* for i=0 to Args.count-1 If Args(i) = "-f" Then iaFilename = Args(i+1) End If Next If iaFilename<>"" Then Set fso = CreateObject("Scripting.FileSystemObject") If (fso.FileExists(iaFilename)) Then Call ReadPsWatchFile(iaFilename) If nToWatch=0 Then Wscript.Echo "File is empty." Else Call StartUpWatcher() End If Else Wscript.Echo "File exists not." End If Else Wscript.Echo "watcher.vbs -f config.txt" End If |
Отправлено: 06:00, 17-05-2016 | #35 |
Новый участник Сообщения: 1
|
Профиль | Отправить PM | Цитировать Спасибо огромное!
Я понимаю, что тема давно забыта, но есть ситуации, когда некоторым пользователям того-же терминального сервера нельзя ограничивать ресурсы. Генеральному не объяснишь, что "нехорошо так делать"! ) Я выкрутился добавив строки if strNameOfUser = "Director" then CountUserProcess = 1 end if после подсчета процессов у пользователя. Было бы неплохо вынести это в конфигурационный файл... |
Отправлено: 17:15, 27-09-2017 | #36 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Win 2003 SP1 - Как ограничить количество подключений под одним логином? | allzero | Microsoft Windows NT/2000/2003 | 7 | 19-01-2009 14:19 | |
Разное - Количество одновременно запущенных приложений или окон | Sandjar | Microsoft Windows 2000/XP | 7 | 21-05-2008 16:28 | |
[решено] Как на терминальном сервере 2003 у каждого нового юзера задать тему оформления? | Angry Demon | Microsoft Windows NT/2000/2003 | 7 | 23-10-2006 11:17 | |
[решено] Как в списке принтеров на терминальном сервере сделать только 1 принтер,а не все | rooty | Microsoft Windows NT/2000/2003 | 7 | 23-09-2005 08:38 | |
Как ограничить количество одновреммено качаемых файлов ? | allalone | Сетевые технологии | 8 | 22-05-2004 03:12 |
|