По мере того, как компании становятся все более и более зависимыми от компьютерной инфраструктуры, планирование переноса серверов и минимизация последствий от неожиданных отказов превращается в важную административную задачу. Чтобы помочь вам упростить решение этой задачи, мною написаны четыре сценария, которыми вы можете воспользоваться для сбора параметров о подключенных пользователях и получить информацию о файлах, к которым обращаются приложения. Эти сценарии представляют вам различные возможности по созданию отчетов, которые вы затем можете анализировать для получения точной картины использования ресурсов серверов пользователями и приложениями. Имея в руках собранную информацию о пользователях и пути к используемым файлам, вы сможете лучше информировать пользователей об изменениях в серверной среде и сможете улучшить доступность ресурсов во время миграции и перемещении серверов. Давайте рассмотрим эти сценарии, и то, как они могут помочь вам в решении поставленных перед вами задач.

Для знакомства

Основной целью каждого из приведенных сценариев было идентифицировать пользователей сети и приложения, которые используют подключения с интересующим нас сервером, т.е. сервером, который вы хотите перенести, либо вывести из работы. Наиболее полезной из известных мне утилит, выполняющих поиск и перечисление пользовательских соединений, является утилита PsLoggedOn компании Sysinternals, входящая в набор утилит PsTools. Вы можете использовать PsLoggedOn для отображения локальных и удаленных подключений к локальной или удаленной системе. Три из приведенных сценариев используют следующий синтаксис

psloggedon.exe computername

где computername - имя удаленной системы.

Поскольку вы пытаетесь определить сетевые пользовательские подключения вам необходимо отфильтровать локальные соединения. Если при просмотре сотен и тысяч пользовательских соединений оставить локальные соединения в отчетах, возможно, это не сильно испортит вашу статистику. Однако удаление подобных соединений обеспечит для вас более ясную и точную картину учетных записей для служб домена, указывающих на зависимости в работе приложений. К сожалению, PsLoggedOn не имеет ключей, обеспечивающих подобную фильтрацию. По этой причине сценарий использует следующую цепочку команд, исключающих из результатов любое соединение, которое не содержит прямых слэшей или имени компьютера

psloggedon.exe computername | find "/"  | find /I /V "computername"

Такое поведение необходимо для исключения соединений, не имеющих метки даты и времени, поскольку соединение сделано учетной записью службы на локальной системе. Если вам необходимо увидеть соединения пользователей и локальных служб, просто удалите вторую команду Find :

psloggedon.exe computername | find "/"

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

Четыре сценария

Сценарий GetSessionMetrics.bat, представленный в листинге 1, использует основной синтаксис команды PsLoggedOn и сообщает только количество подключенных пользователей без регистрации идентификаторов пользователей. Команда Set в блоке A увеличивает значение счетчика, содержащего общее количество строк, возвращаемых командой PsLoggedOn, при этом игнорируется идентификатор пользователя. Этот счетчик предоставляет информацию о количестве подключенных пользователей в данный момент времени.

Я предполагаю, что для сбора информации используется планировщик задач Task Scheduler, запускающий сценарий несколько раз в течение рабочего дня, поскольку в разное время и разные дни подключается различное количество пользователей. Это предоставит вам более полную статистику подключений. Постарайтесь использовать характерные часы и дни для вашего предприятия при составления вашего расписания. Например, вы собираете данные о бухгалтерии и знаете, что рабочий цикл бухгалтерии смещен на последние дни каждого месяца. Убедитесь, что вы включили эти дни в ваше расписание. Ваши результаты не отразят использование общих папок серверов, но уведомят вас о подключениях к дискам и открытым папкам и файлам.

Если вы хотите запускать сценарий несколько раз в течение дня, убедитесь, что вы протестировали каждый из сценариев и выяснили примерное время работы каждого из них. В зависимости от этого установите интервалы повторения запуска. Установите интервал запуска, больший, чем наблюдаемое вами время. Если время работы сценария превысит принятый вами интервал, то время следующего запуска сценария пересечется с работой предыдущего экземпляра сценария. Например, если сценарию требуется для выполнения работы один час, а вы в планировщике задач установите запуск сценария каждые 30 минут, планировщик попытается запустить сценарий, что приведет к ошибке, поскольку первый экземпляр сценария еще выполняется. Планировщик задач никогда не запустит второй экземпляр задачи, если первая не завершилась.

Такое безопасное поведение планировщика является его хорошей особенностью, поскольку запуск двух экземпляров сценария такого как GetSessionMetrics.bat, производящего запись в один входной файл, может повредить ваши результаты. Такое поведение планировщика задач защитит выходной файл от повреждения. Еще раз напомню, что для получения достоверных результатов и их корректной записи интервалы между запусками сценария должны быть больше, чем время выполнения сценария.

Следующий сценарий GetUniqueSessionUserIDs.bat определяет не только количество пользовательских соединений, но и то, какое из соединений в данный момент активно.

GetUniqueSessionUserIDs.bat представлен в листинге 2. Он позволяет собирать идентификаторы (ID) пользователей, которые игнорировались при работе GetSessionMetrics.bat, и посылает эти ID в электронную таблицу отчета. Я также предполагаю, что вы будете запускать этот сценарий несколько раз в день для получения хорошей достоверности результатов. Хотя для получения статистики, повторный запуск сценария желателен, это может вызвать ряд проблем. Поскольку каждый запуск сценария процедуры добавляет данные в таблицу отчета, вы вскоре получите длинный отчет с множеством повторяющихся имен. Вы можете запустить сценарий в нужное время и затем удалить повторяющиеся идентификаторы пользователей, открыв отчет Microsoft Excel и выполнив ручную сортировку, используя фильтры. Вместо этого я включил код (блок A на листинге 2), который автоматически производит сортировку и фильтрацию каждый раз при запуске сценария. В результате отчет содержит список уникальных пользовательских ID в алфавитном порядке. При каждом последующем запуске сценария в отчет будут добавляться только новые уникальные ID.

Сценарий GetUniqueSessionsIDsWithNames.bat, представленный в листинге 3 собирает более детальную пользовательскую информацию, наряду с идентификаторами пользователей. Много раз я заставлял себя написать сложный сценарий для сбора членства в группах и других идентификаторов пользователей только лишь для того, чтобы предоставить руководству результаты, в которых имена пользователей представлены в дружественном виде. Например, fredsmith, sallylee. Если в вашей организации схема присвоения имен пользователям домена допускает использование дружественных имен, в этом случае запросы значительно упрощаются. Однако во многих средах, пользовательские идентификаторы часто зашифрованы табельными номерами департамента по работе с персоналом или еще каким-нибудь кодом, не имеющим ничего общего с реальным идентификатором пользователя. В случае подобного окружения код блока B в листинге 3 использует утилиту GetUniqueSessionUserIDs.bat компании JoeWare Get User, позволяющую получить отображаемое имя, имея либо полное имя либо информацию из описания для заданного идентификатора пользователя, перечисленного в отчете с ID пользователей, который создается GetUniqueSessionUserIDs.bat. Имея подобную детальную информацию о пользователях, задача контактов с пользователями и их оповещением сильно упрощается.

Последний сценарий рассматриваемого набора для сбора информации о подключениях пользователей - GetOpenFiles.bat. В листинге 4 представлена часть этого сценария. Сценарий позволит вам определить то, какие ресурсы используются в данный момент и какие из пользователей будут отключены во время миграции или смены сервера. Знание путей, используемых клиентами для доступа к ресурсам, становится все более важным. Эта информация поможет вам более точно идентифицировать то, какие из файлов внутри общей папки открыты клиентами и какой из общих ресурсов используется. Пытаться определить это путем просмотра последней даты доступа в Windows несколько неточно, поскольку только факт выбора файла или папки может переключить дату изменения. Регистрация реальной даты доступа к файлу даст вам намного более точную картину того, какие из совместных ресурсов действительно активны.

Сбор информации о доступе к папкам, о путях к файлам и пользовательских идентификаторах учетных записей, под которыми происходит обращение к этим файлам, ведется GetOpenFiles.bat с использованием утилиты PsFile компании Sysinternals, также входящей в набор утилит PsTools и некоторой цепочки команд Find:

psfile.exe computername | find /V "Locks:"  | find /V "Access:"

Вывод команды PsFile имеет одну неприятную особенность: он отображает путь к файлу и пользователя на разных строках отчета. Поэтому, вам придется воспользоваться отдельными командами For для сбора информации о пути и пользователе, а затем получить эту информацию снова, объединив ее предшествующей записью в журнале. Код блока B на листинге 4 выполняет эту операцию.

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

Одной из трудностей сортировки и манипуляции текстовыми строками в сценариях командной строки - это встречающиеся зарезервированные символы. Если строка пути к файлу содержит какие- либо зарезервированные символы, такие как амперсанд или открывающиеся и закрывающиеся скобки, то сценарий интерпретирует зарезервированные символы как часть кода сценария. Это может вызвать непредвиденную ошибку. Наилучшим путем решения этой проблемы будет использование двойных кавычек, выделяющих эту строку. Таким образом, вы предотвратите неправильную интерпретацию зарезервированных символов. Код в блоке A на листинге 4 выполняет операции сортировки и фильтрации подобно операциям удаления дубликатов имен в сценариях GetUniqueSessionUserIDs.bat и GetUniqueSessionsIDsWithNames.bat, решает проблемы с символами и сохраняет кавычки вокруг любой строки, содержащей путь к файлу при сортировке и выводе.

Как работать с этими сценариями

Я тестировал эти сценарии на Windows Server 2003, Windows XP Professional Service Pack 1 (SP1), Windows 2000 Server SP4 и Windows 2000 Pro, чтобы начать использовать их, выполните следующие шаги :

  1. Загрузите PsLoggedOn и PsFile с сайта http://www.sysinternals.com; загрузите GetUserInfo по адресу http://www.joeware.net/win/free/tools/getuserinfo.htm, некоторые из этих утилит чувствительны к пробелам в пути к файлу. Разместите их в папке, которая не содержит пробелов в пути. Для упрощения доступа вы можете разместить их на общедоступном сервере.
  2. Скопируйте все сценарии в одну папку на сервере или на компьютере, с которых вы будете выполнять запросы. Учтите, что ширина колонки в печатной публикации меньше, чем длина строк кода в напечатанном листинге. Это может вызвать проблемы с правильностью работы кода, если набрать некоторые команды не в одну строку. Кроме того, некоторые из сценариев содержат пробелы, табуляцию и другие детали, которые не являются необходимыми для работы кода. После загрузки кода приведите его в соответствие с изложенными инструкциями. Операторы должны быть набраны в одну строку.
  3. Отредактируйте первую, либо вторую строку каждого из сценариев, (например, код в блоке A на листинге 3, указывающий на путь к утилитам PsTools и JoeWare).
  4. Местоположение сценариев произвольное. Они просматривают файл servers.txt в той же папке, где расположены сценарии. Этот файл должен содерать список ваших целевых серверов с одним именем сервера в каждой строке.
  5. Каждый сценарий автоматически создает папку журналов Logs при первом запуске и размещает журналы внутри этой папки. Формат файла журнала .tsv - (значения разделены символом табуляции) и имеет имя, соответствующее имени целевого сервера.
  6. После того, как вы протестируете сценарии и решите, какой из сценариев наиболее подходит вам и дает наиболее полную информацию о вашей среде, воспользуйтесь планировщиком задач Task Scheduler для запуска его на регулярной основе. Я запускаю их каждые два часа в течение рабочего дня.

Представленные четыре сценария призваны сделать миграцию сервера и общих ресурсов более осознанной и облегчить использование и обслуживание этих общедоступных ресурсов. Попробуйте сценарии сначала в тестовой среде и подберите сценарий, представляющий наиболее нужную вам информацию.


Листинг 1. GetSessionMetrics.bat
Set PSUtilLoc=server5PsTools
For /F "tokens=1,2,*" %%i in ('Dir %0 ^| Find "Directory"')
 Do Set dirloc=%%k
If Not Exist "%dirloc%Logs" Mkdir "%dirloc%Logs"
For /F "tokens=1,*" %%i in ("%date%") Do Set daterev=%%j
For /F "tokens=1,2,3 delims=: " %%i in ("%time%")
 Do Set timerev=%%i:%%j
For /F "tokens=1,2,3 usebackq" %%i in ("%dirloc%Servers.txt")
 Do (Set server=%%i) & (Call :Testem)
Echo Run complete
Goto :EOF
 
:Testem
If Exist "%dirloc%Logs\%server%-Sessionlog.tsv" Goto :Next
Echo Date        Time        Sessions
 >>"%dirloc%Logs\%server%-Sessionlog.tsv"
 
:Next
Set Sessions=0
:: НАЧАЛО БЛОКА A
For /F "tokens=*" %%i in ('%PSUtilLoc%psloggedon.exe
 \%server% ^| Find "/" ^| Find /I /V "%server%"')
 Do Set /A Sessions+=1
:: КОНЕЦ БЛОКА A
 
Echo %daterev%        %timerev%        %Sessions%
 >>"%dirloc%Logs\%server%-Sessionlog.tsv"
Goto :EOF
 
Листинг 2. GetUniqueSessionsIDs.bat
Set PSUtilLoc=server5PsTools
For /F "tokens=1,2,*" %%i in ('Dir %0 ^| Find "Directory"')
 Do Set dirloc=%%k
If Not Exist "%dirloc%Logs" Mkdir "%dirloc%Logs"
For /F "tokens=1,*" %%i in ("%date%") Do Set daterev=%%j
For /F "tokens=1,2,3 delims=: " %%i in ("%time%")
 Do Set timerev=%%i:%%j
For /F "tokens=1,2,3 usebackq" %%i in ("%dirloc%Servers.txt")
 Do (Set server=%%i) & (Call :Testem)
Echo Run complete
Goto :EOF
 
:Testem
If Exist "%dirloc%Logs\%server%-Userlog.tsv" Goto :Next
Echo _User DomainIDs_>>"%dirloc%Logs\%server%-Userlog.tsv"
 
:Next
For /F "tokens=1,2,3,*" %%i in ('%PSUtilLoc%psloggedon.exe
 \%server% ^| Find "/" ^| Find /I /V "%server%"')
 Do Echo %%l>>"%dirloc%Logs\%server%-Userlog.tsv"
Move "%dirloc%Logs\%server%-Userlog.tsv"
  "%dirloc%Logs\%server%-UserlogTemp.tsv"
Sort "%dirloc%Logs\%server%-UserlogTemp.tsv"
 > "%dirloc%Logs\%server%-UserlogTempSorted.tsv"
For /F "tokens=* usebackq" %%i in
 ("%dirloc%Logs\%server%-UserlogTempSorted.tsv")
 Do (Set line=%%i) & (Call :Filter)
If Exist "%dirloc%Logs\%server%-UserlogTemp.tsv"
 Del "%dirloc%Logs\%server%-UserlogTemp.tsv"
If Exist "%dirloc%Logs\%server%-UserlogTempSorted.tsv"
 Del "%dirloc%Logs\%server%-UserlogTempSorted.tsv"
Goto :EOF
 
:: НАЧАЛО БЛОКА A
:Filter
If /I "%line%"=="%prevline%" Goto :Skip
Echo %line%>>"%dirloc%Logs\%server%-Userlog.tsv"
Set prevline=%line%
 
:Skip
Goto :EOF
:: КОНЕЦ БЛОКА A
Листинг 3. GetUniqueSessionsIDsWithNames.bat
:: НАЧАЛО БЛОКА A
Set PSUtilLoc=server5PsTools
Set JWUtilLoc=server5JoeWareTools
:: КОНЕЦ БЛОКА A
For /F "tokens=1,2,*" %%i in ('Dir %0 ^| Find "Directory"')
 Do Set dirloc=%%k
If Not Exist "%dirloc%Logs" Mkdir "%dirloc%Logs"
For /F "tokens=1,*" %%i in ("%date%") Do Set daterev=%%j
For /F "tokens=1,2,3 delims=: " %%i in ("%time%")
 Do Set timerev=%%i:%%j
For /F "tokens=1,2,3 usebackq" %%i in ("%dirloc%Servers.txt")
 Do (Set server=%%i) & (Call :Testem)
Echo Run complete
Goto :EOF
 
:Testem
If Exist "%dirloc%Logs\%server%-UserlogWName.tsv" Goto :Next
Echo _User DomainIDs_        Full Name        Description
 >>"%dirloc%Logs\%server%-UserlogWName.tsv"
 
:Next
For /F "tokens=1,2,3,*" %%i in ('%PSUtilLoc%psloggedon.exe
 \%server% ^| Find "/" ^| Find /I /V "%server%"')
 Do (Set User=%%l) & (Call :GetInfo)
Move "%dirloc%Logs\%server%-UserlogWName.tsv"
 "%dirloc%Logs\%server%-UserlogWNameTemp.tsv"
Sort "%dirloc%Logs\%server%-UserlogWNameTemp.tsv"
 > "%dirloc%Logs\%server%-UserlogWNameTempSorted.tsv"
For /F "tokens=* usebackq" %%i in
 ("%dirloc%Logs\%server%-UserlogWNameTempSorted.tsv")
 Do (Set line=%%i) & (Call :Filter)
If Exist "%dirloc%Logs\%server%-UserlogWNameTemp.tsv"
 Del "%dirloc%Logs\%server%-UserlogWNameTemp.tsv"
If Exist "%dirloc%Logs\%server%-UserlogWNameTempSorted.tsv"
 Del "%dirloc%Logs\%server%-UserlogWNameTempSorted.tsv"
Goto :EOF
 
:Filter
If /I "%line%"=="%prevline%" Goto :Skip
Echo %line%>>"%dirloc%Logs\%server%-UserlogWName.tsv"
Set prevline=%line%
 
:Skip
Goto :EOF
 
:GetInfo
Set FullName=N/A
Set Desc=N/A
:: НАЧАЛО БЛОКА B
For /F "tokens=1,2,*" %%i in ('%JWUtilLoc%GetUserInfo.exe
 "%User%" ^| Findstr /I /C:"Full Name"') Do Set FullName=%%k
For /F "tokens=1,*" %%i in ('%JWUtilLoc%GetUserInfo.exe
 "%User%" ^| Findstr /I /C:"Description"') Do Set Desc=%%j
:: КОНЕЦ БЛОКА B
Echo %User%        %FullName%        %Desc%
 >>"%dirloc%Logs\%server%-UserlogWName.tsv"
Goto :EOF
Листинг 4. Фрагмент GetOpenFiles.bat
:: НАЧАЛО БЛОКА A
:Filter
Echo prevline: %prevline%
Set line1=%line:"=%
Set line2=%line1: =X%
If /I "%line2%"=="%prevline%" Goto :Skip
Echo %line:""=NA%>>"%dirloc%logs\%server%-FileAccesslog.tsv"
Set prevline=%line2%
 
:Skip
Goto :EOF
:: КОНЕЦ БЛОКА A
 
:: НАЧАЛО БЛОКА B
:Filterit
For /F "tokens=1,*" %%i in ('Echo "%var2%" ^| Findstr /V "User:"')
 Do (Set pathline=%%j)
For /F "tokens=1,*" %%i in ('Echo "%var2%" ^| Findstr "User:"')
 Do (Set UserID=%%j)
If Defined UserID if defined pathline Echo "%UserID%        "%pathline%
 >>"%dirloc%logs\%server%-FileAccesslog.tsv" &
 (Set UserID=) & (Set UserID=)
Goto :EOF
:: КОНЕЦ БЛОКА B