|
Компьютерный форум 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 |
Пользователь Сообщения: 90
|
Профиль | Отправить PM | Цитировать Нужно ограничить количество одновременно запускаемых программ для пользователей терминального доступа на w2k3.
Подскажите как это можно сделать? |
------- Отправлено: 13:31, 05-06-2006 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 208
|
Профиль | Отправить PM | Цитировать В групповых политиках:
User Configuration\Administrative Templates\Windows Components\Windows Explorer---> Maximum number of recent documents Maximum number of recent documents Enabled Maximum number of recent documents 15 (15 -кол-во приложений) |
Отправлено: 17:46, 05-06-2006 | #3 |
Сообщения: 25151
|
Профиль | Сайт | Отправить PM | Цитировать |
------- Отправлено: 16:50, 06-06-2006 | #4 |
Железных Дел Мастер Сообщения: 24690
|
Профиль | Сайт | Отправить PM | Цитировать проверил я предложенные варианты... вопрос не решен. Озвучу промежуточные результаты:
1) указанное foss: не то. Кто дружит с английским, поймет описание предложенного параметра: Цитата:
2.1) Прежде всего, суммируются все инстанции названных процессов. То есть, если я запущу два калькулятора, то два нотепада я запустить уже не смогу 2.2) Нет возврата счетчика в обратное состояние, если одна из копий закрывается. Ессно, я понимаю, что скрипт набросан на скорую руку. В содержимом разобрался, но с визуал бейсиком не дружен, посему: 1) можно ли создать массив из связок имя_процесса-кол-во_копий 2) можно ли добавлять в этот массив компоненты динамически, а не прописывать в скрипте 3) можно ли отслеживать завершение работы копии и делать соответствующие изменения в счетчике (с удалением единицы массива при закрытии последней из копий данного процесса) |
||
------- Отправлено: 13:36, 06-07-2006 | #5 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать ShaddyR, я очень скоренько наборосал...
Не все проблемы решены. Set Args = WScript.Arguments ' ******************************************* 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 colMonitoredProcesses = objWMIService. _ ExecNotificationQuery("select * from __InstanceCreationEvent" _ & " within 1 where TargetInstance isa 'Win32_Process'") Set colMonitorProcessesd = objWMIService.ExecNotificationQuery _ ("SELECT * FROM __InstanceDeletionEvent " & _ "WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' ") Do While 1 Set objLatestProcess = colMonitoredProcesses.NextEvent For psn=0 to nToWatch-1 If objLatestProcess.TargetInstance.Name = thePsArray(PSNAME, psn) Then thePsArray(PSNUMB, psn) = thePsArray(PSNUMB, psn) - 1 ' Wscript.Echo "Num: "& thePsArray(PSNUMB, psn) If thePsArray(PSNUMB, psn) < 0 then Wscript.Echo "Вы запустили лишнюю копию программы "& objLatestProcess.TargetInstance.Name _ & " - разрешенный лимит только " & thePsArray(PSMAXN, psn) objLatestProcess.TargetInstance.Terminate thePsArray(PSNUMB, psn) = thePsArray(PSNUMB, psn) + 1 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 filename" End If Запускается скрипт watcher.vbs -f filename но вот по поводу 2.2) Нет возврата счетчика в обратное состояние, если одна из копий закрывается. - это я не могу сейчас сообразить. как сделать И вообще не уверен, что это возможно :-| |
Отправлено: 18:37, 06-07-2006 | #6 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать А вообще нет, чего я... Можно просто пересчитывать количества процессов перед каждый новым запуском... Так, наверное.
Прошу прощения, если критично кому, но я завтра только смогу поковыряться... Плюс второй вариант - http://www.microsoft.com/technet/scr....mspx?mfr=true |
Отправлено: 19:06, 06-07-2006 | #7 |
Железных Дел Мастер Сообщения: 24690
|
Профиль | Сайт | Отправить PM | Цитировать |
------- Отправлено: 19:57, 06-07-2006 | #8 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать НЕЕЕЕЕ... Вы чего?
filename - это текстовый файл, в котором перечислены файлы, подлежащих "рестриктированию". Там написано за кем следить - и сколько раз можно запускать. Кстати, Вы бежите впереди паровоза :] Я как завтра хотел написать вторым вариантом решение таким образом, каким Вы сейчас предлагаете, когда на каждый файл рестрикта будет свой собственный "наблюдатель". А первым вариантом - доработать "комплексный" обработчик-рестриктизатор. |
Отправлено: 22:43, 06-07-2006 | #9 |
Пользователь Сообщения: 87
|
Профиль | Отправить PM | Цитировать Цитата:
а когда сооборазите насчет возврата счетчика?? как раз то, что мне нужно. |
|
------- Отправлено: 17:20, 07-07-2006 | #10 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
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 |
|