Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Серверные продукты Microsoft » Microsoft Windows NT/2000/2003 » [решено] Как ограничить количество запущенных копий приложения на терминальном сервере?

Ответить
Настройки темы
[решено] Как ограничить количество запущенных копий приложения на терминальном сервере?

Аватара для SkyF

Vladimir


Сообщения: 1070
Благодарности: 17

Профиль | Отправить PM | Цитировать


Изменения
Автор: ShaddyR
Дата: 10-07-2006
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
Запуск
Код: Выделить весь код
watcher -f config.txt
Пример config.txt
Код: Выделить весь код
notepad.exe 2
calc.exe 3


После запуска сценария - он запускается резидентно и выполняет перехват событий запуска процесса, сравнивает название процесса с заранее заданными и в случае совпадения - передает управление счетчику. Если лимит будет исчерпан - для нового процесса будет вызван метод завершения.
Процесс может быть запущен из любой терминальной сессии, а сценарий должен запускаться от имени системы (те при запуске ОС)

Любые изменения приветствуются!

ЗЫ полезные ссылки:
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
Благодарности: 0

Профиль | Отправить PM | Цитировать


Нужно ограничить количество одновременно запускаемых программ для пользователей терминального доступа на w2k3.
Подскажите как это можно сделать?

-------
Генератор вопросов.


Отправлено: 13:31, 05-06-2006 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Старожил


Сообщения: 208
Благодарности: 9

Профиль | Отправить 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



Administrator


Сообщения: 25152
Благодарности: 3798

Профиль | Сайт | Отправить PM | Цитировать


http://www.oszone.net/3644/#18

-------
FAQ по Windows 10 .::. Настройка Центра обновления в Windows 10 .::. Чистая установка Windows 10 – пошаговая инструкция


Отправлено: 16:50, 06-06-2006 | #4


Аватара для ShaddyR

Железных Дел Мастер


Moderator


Сообщения: 24514
Благодарности: 4495

Профиль | Сайт | Отправить PM | Цитировать


проверил я предложенные варианты... вопрос не решен. Озвучу промежуточные результаты:
1) указанное foss: не то. Кто дружит с английским, поймет описание предложенного параметра:
Цитата:
Determines how many shortcuts the system can display in the Documents menu on the Start menu.

The Documents menu contains shortcuts to the nonprogram files the user has most recently opened. By default, the system displays shortcuts to the 10 most recently opened documents.
2) вариант скрипта vbs: более реально, но
2.1) Прежде всего, суммируются все инстанции названных процессов. То есть, если я запущу два калькулятора, то два нотепада я запустить уже не смогу
2.2) Нет возврата счетчика в обратное состояние, если одна из копий закрывается.

Ессно, я понимаю, что скрипт набросан на скорую руку. В содержимом разобрался, но с визуал бейсиком не дружен, посему:
1) можно ли создать массив из связок имя_процесса-кол-во_копий
2) можно ли добавлять в этот массив компоненты динамически, а не прописывать в скрипте
3) можно ли отслеживать завершение работы копии и делать соответствующие изменения в счетчике (с удалением единицы массива при закрытии последней из копий данного процесса)

-------
[FAQ] Как определить аппаратную конфигурацию компьютера и правильно задать вопрос
-------
В благодарность за помощь нажимаем ссылочку "Полезное сообщение" внизу этого самого сообщения (подробнее). Помните: админ конфеты НЕ ПЬЁТ ;)
-------
Говори, что думаешь и думай, что говоришь! (c) || МОЙ ShaddyR.at.UA/blog - Как поменять термопасту за 100+ баксов


Отправлено: 13:36, 06-07-2006 | #5


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить 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
Формат файла такой
Код: Выделить весь код
имяпрограммы1.exe n1
имяпрограммы2.exe n2
имяпрограммы3.exe n3
Запускается скрипт watcher.vbs -f filename

но вот по поводу 2.2) Нет возврата счетчика в обратное состояние, если одна из копий закрывается. - это я не могу сейчас сообразить. как сделать


И вообще не уверен, что это возможно :-|

Отправлено: 18:37, 06-07-2006 | #6


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


А вообще нет, чего я... Можно просто пересчитывать количества процессов перед каждый новым запуском... Так, наверное.
Прошу прощения, если критично кому, но я завтра только смогу поковыряться...

Плюс второй вариант - http://www.microsoft.com/technet/scr....mspx?mfr=true

Отправлено: 19:06, 06-07-2006 | #7


Аватара для ShaddyR

Железных Дел Мастер


Moderator


Сообщения: 24514
Благодарности: 4495

Профиль | Сайт | Отправить PM | Цитировать


Изображения
Тип файла: jpg vbs_error.JPG
(11.1 Kb, 6 просмотров)

hasherfrog: я понял)
Резалты теста (назвал скрипт Processrestrict.vbs):
1)
Код: Выделить весь код
Processrestrict.vbs -f calc.exe
возвращает "File exists not."
2) Processrestrict.vbs -f "C:\WINDOWS\system32\calc.exe"
возвращает ошибку в аттаче)

-------
[FAQ] Как определить аппаратную конфигурацию компьютера и правильно задать вопрос
-------
В благодарность за помощь нажимаем ссылочку "Полезное сообщение" внизу этого самого сообщения (подробнее). Помните: админ конфеты НЕ ПЬЁТ ;)
-------
Говори, что думаешь и думай, что говоришь! (c) || МОЙ ShaddyR.at.UA/blog - Как поменять термопасту за 100+ баксов


Отправлено: 19:57, 06-07-2006 | #8


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


НЕЕЕЕЕ... Вы чего?
filename - это текстовый файл, в котором перечислены файлы, подлежащих "рестриктированию".
Там написано за кем следить - и сколько раз можно запускать.

Кстати, Вы бежите впереди паровоза :] Я как завтра хотел написать вторым вариантом решение таким образом, каким Вы сейчас предлагаете, когда на каждый файл рестрикта будет свой собственный "наблюдатель". А первым вариантом - доработать "комплексный" обработчик-рестриктизатор.
Это сообщение посчитали полезным следующие участники:

Отправлено: 22:43, 06-07-2006 | #9


Пользователь


Сообщения: 87
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата:
2.2) Нет возврата счетчика в обратное состояние, если одна из копий закрывается
hasherfrog

а когда сооборазите насчет возврата счетчика?? как раз то, что мне нужно.

-------
OSZONE.NET


Отправлено: 17:20, 07-07-2006 | #10



Компьютерный форум OSzone.net » Серверные продукты Microsoft » Microsoft Windows NT/2000/2003 » [решено] Как ограничить количество запущенных копий приложения на терминальном сервере?

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
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




 
Переход