ОглавлениеВведение....................................................................................................................................................2
1. Меняем пароль локального администратора.....................................................................................2
2. Перезагрузка или остановка сервера...................................................................................................4
3. Перезагрузка службы............................................................................................................................7
4. Остановка процесса.............................................................................................................................11
5. Создаем отчет об использовании дисков..........................................................................................12
6. Получаем 10 последних ошибок журнала событий..........................................................................19
7. Сброс контроля доступа к папке.........................................................................................................23
8. Получение информации о времени работы сервера (uptime).........................................................26
9. Получение информации о service pack..............................................................................................30
Введение
Порою с помощью PowerShell управлять Windows Server 2008 можно гораздо быстрее, чем с помощью привычных GUI-инструментов. В этой статье вы найдет 9 наиболее распространенных задач, которые могут быть реализованы с помощью PowerShell.
В руководстве будут рассмотрены следующие задачи:
1. Изменение пароля локального администратора с помощью PowerShell
2. Перезагрузка или выключение сервера
3. Перезапуск службы
4. Остановка процесса
5. Создание отчета об использовании диска
6. Получаем 10 последних ошибок журнала событий
7. Сбрасываем контроль доступа к папке
8. Получаем server’s uptime
9. Получаем информацию о Service Pack
1. Меняемпароль локального администратора
Предположим Вы залогинились как доменный администратор на компьютере под
Windows 7, который входит в Ваш домен. Теперь, предположим, Вы хотите сменить
пароль локального администратора на удаленном сервере CHI-WIN7-22 в Чикаго.
После использования пароля в течение определенного периода времени, его
желательно сменить; процедуру необходимо повторять периодически.
Первое, что администратор делает для смены пароль администратора — создает ADSI
объект для локального администратора на этом компьютере. Это делается в PowerShell
следующим образом:
[ADSI]$Admin=”WinNT://CHI-WIN7-22/Administrator”
Произойдет извлечение учетной записи администратора на сервере CHI-WIN7-22 и
присвоение ее ADSI объекту $Admin. Имя WinNT в этой строке чувствительно к регистру,
примите это во внимание. Если Вы захотите подключиться к другому компьютеру,
просто замените CHI-WIN7-22 на имя того компьютера, к которому Вы хотели бы
подключиться.
Однако для начала необходимо узнать, как долго пароль используется, чтобы
определить, пришло ли время менять его или нет. Информация из $Admin может быть
получена следующим образом:
$Admin.PasswordAge
Выведется время, прошедшее с последней смены пароля. Результат показывается в
секундах, переведем ее в дни (осуществим деление на 86400 (количество секунд в
сутках)):
$Admin.PasswordAge.Value/86400
Обратите внимание, что было использовано свойство Value. Это было сделано потому,
что PasswordAge хранится как коллекция, и поэтому нам необходимо сначала
присвоить значение этой коллеции, чтобы вернуть ее в число, к которому можно
применить операцию деления.
В итоге Вы можете изменить пароль, вызвав SetPassword метод и затем использовав
новый пароль в качестве аргумента.
$Admin.SetPassword(“S3cre+WOrd”)
Внимание: По нажатию Enter, не ждите получения письмо подтверждения. Такового не
будет! Изменения будет применены немедленно. То, что я здесь продемонстрировал,
является методом, а не командлетом. Помимо прочего это значит, что в отличие от
командлетов, SetPassword не поддерживает -whatif или -confirm.
Это все. Позвольте мне продемонстрировать все это PowerShell-картинках.
2. Перезагрузка или остановка сервера
Двигаемся дальше. Перед нами стоит задача перезагрузить или остановить сервер с
помощью PowerShell. Как и в первом случае, предположим, что вы залогинены как
доменный администратор на машине под Windows 7, которая входит в ваш домен.
Мы будем использовать два WMI-командлета – Restart-Computer и Stop-Computer. И
хотя мы не будем их здесь показывать, стоит упомянуть, что эти командлеты
принимают альтернативные учетные данные (alternate credentials). Альтернативные
учетные данные позволяют Вам уточнить учетную запись пользователя (отличную от
той, под которой вы залогинились), так что вы можете осуществлять действия, на
которые эта (альтернативная) учетная запись имеет права.
Также среди приятного об этих командлетах – вы сможете использовать -whatif и -
confirm. Это значит, если вы захотите перезапустить или выключить сервер,
необходимо сначала убедиться, что вы делаете это на предназначенном для этого
компьютере. Это удобно, когда вы осуществляете подобные операции с множеством
компьютеров.
Для перезагрузки компьютера синтаксис такой:
Restart-Computer -ComputerName <string[ ]>
где -ComputerName <string[ ]> это массив строк, который может состоять как из
имени одного, так и нескольких компьютеров. Stop-Computer используется
практически тот же самый синтаксис. Например, если Вы хотите перезагрузить два
компьютера CHI-DC02 и CHI-FP01, используйте следующую команду:
Restart-Computer “CHI-DC02”, “CHI-FP01”
Ниже приведен фактически скриншот PowerShell, в котором мы использовали аргумент
–whatif. Используйте его, если вы просто хотите посмотреть, что случиться, если вы
выполните команду.
Все достаточно просто. Давайте теперь усложним задачу. Предположим, что у вас есть
список компьютеров в файлеservers.txt. Используем командлет Get-Content, чтобы
извлечь их имена из файла.
Итак, у вас есть ряд компьютеров, которые вы бы хотели периодически перезагружать,
и вы храните их имена в текстовом файле. Каждый раз, когда вам нужно перезагрузить
их, вы просто используйте командлет Get-Content. Ниже представлен пример работы
Get-Content и Restart-Computer.
Сначала мы получаем содержимое файла, используя Get-Content. Для начала
пропингуем этим компьютеры. В этом выражении, мы запустим test-connection, что
фактически эквивалентно ping на каждом компьютере. -quiet возвращает значения
true или false, а -count 2 означает, что каждый компьютер будет “пропингован” лишь
дважды. Те компьютеры, которые будут успешно пропингованы, будут дальше
запущены в работу.
Затем мы используем foreach. Цель этого такова: для каждого имени, которое
проходит пинг-тест, выводится сообщение зеленым текстом, указывающее на
перезагрузку компьютера. “$_” означает текущий объект в конвейере. Затем
используем командлет Restart-Computer для перезагрузки тех компьютеров, которые
пингуются. Мы также используем параметр –force, чтобы сбросить всех, кто залогинен
на данном компьютере
Параметр –whatif используется для того, чтобы посмотреть, что произойдет, без
реальной перезагрузки компьютеров.
3. Перезагрузка службы
Restart-Service, как следует из название, это командлет, который перезапускает
службу. Хотя у него и отсутствует возможность подключаться к удаленному серверу,
может быть активирован PowerShell Remoting, так что Вы можете выполнять ее
локально на удаленном компьютере. Это бывает полезно, когда Вы хотите
перезапустить службу на группе компьютеров.
Для локальной перезагрузки службы просто напишите Restart-Service “service”, где
“service” – имя той службы, которую вы хотите перезагрузить. С другой стороны, если
вы хотите перезагрузить службы на одной или нескольких удаленных машинах,
используйте командлет Invoke-Command и PowerShell Remoting.
На скриншоте ниже показаны два примера работы командлеты Restart-Service для
перезагрузки службы wuauserv (Windows Update). В первом примере Restart-Service
выполняется локально. Во втором, она выполняется на удаленном сервере БД CHI-DB01с
помощью командлета Invoke-Command.
По умолчанию Restart-Service не выводит никаких объектов, если вы не используете
параметр -passthru. Дополнительная информация (Status, Name и другое) – результат
его использования. Если служба запущена на нескольких компьютеров и вы хотите
перезапустить их также, перечислите их через запятые.
То же самое можно сделать с использование WMI. Создадим WMI объект:
gwmi – это сокращенно для Get-WmiObject.
Давайте посмотрим на методы объекта. Введем Get-Member (сокращенно gm).
Как вы могли заметить, здесь отсутствует метод для перезапуска службы. А это значит,
что сначала придется остановить службы через метод StopService и запустить снова с
помощью StartService.
Вот как остановить службу, используя метод StopService объекта. Круглая скобка
указывает на наличие метода. Если получили ReturnValue равным 0, значит служба
успешно остановлена. В противном случае, обратитесь к документации MSDN для
класса службы Win32.
Запускаем службу — метод StartService.
Проверяем: запустим команду get-service на этом компьютере. Get-service позволяет
получить информацию о службе на удаленном компьютере. Пример запроса для
удаленного компьютера CHI-DB01.
4. Остановка процесса
Еще одной частой задачей является остановка процесса. Используем для этого
командлет Stop-Process. Он может быть выполнен как локально, так и на удаленной
машине (см. пункт 3).
Существует два способа остановки процесса с помощью командлета Stop-Process.
Первый – простой. Запускаете Stop-Process и передаете ему имя или соответствующий
ID процесса. Обратите внимание, что мы останавливаем “Calc” (Калькулятор Windows). В
данном примере процесс запущен локально.
Второй способ связан с использованием командлета Get-Process для получения одного
или нескольких процессов или передачи их в Stop-Process. Для примера взят процесс
Notepad. Kill является сокращением для Stop-Process. Notepad запущен локально.
Двигаемся дальше. Перейдем к процессам, запущенным на удаленной машине. Для
начала запустим, например, notepad на удаленном компьютере chi-fp01.
Затем, проверим, запущен ли процесс. Для этих целей используем ps, являющимся
сокращением для Get-Process.
5. Создаем отчет об использовании дисков
Администраторы должны отслеживать свободное место, оставшееся на серверах. Это
можно сделать, использовав WMI и класс Win32_LogicalDisk, которые дают нам
информацию такую как ID устройства, размер диска, свободное места и прочую
информацию.
Через WMI мы можем обращаться к локальным и удаленным компьютерам. Мы также
можем выполнять эти запросы как одной, так и нескольких машинах. Также мы можем:
экспортировать данные в .csv или базу данных, создавать текстовый или HTML-отчет
или просто вывести результаты на экран.
Пример команды, выполняемой на локальном компьютере.
Get-WmiObject win32_logicaldisk -filter “drivetype=3” | Out-File c:\Reports\Disks.txt
Мы используем командлет GetWmiObject для возвращения информации из класса
Win32_LogicalDisk. Затем мы применяем -filter чтобы возвратить только информацию,
для которой справедливо утверждение drivetype=3, которое означает фиксированные
логические диски, типа C:. Это значит, что информация относительно о USB и сетевых
дисках не будет включена. Полученная информация будет записана в файл Disks.txt.
Пример в PS.
Хотя вроде бы все нормально, лучше внести парочку улучшений. Например, добавить
отображение свободного места в гигабайтах, а не байтах. Этим мы и займемся.
Чтобы это сделать создадим функцию Get-DiskUtil. Хотя в предыдущем примере мы
все делали интерактивно, в этом случае давайте запишем функцию в файл, загрузим в
ваш профиль к другим скриптам, которые можно использовать позже.
А вот и сама функция:
Давайте ее разберем.
Функция берет имя компьютера как параметр и задает его как имя локального
компьютера по умолчанию.
Затем мы используем фрагмент скрипта Process, где свойство “имя компьютера”
передается в функцию. “$_” указывает, что имя компьютера задается как переменная.
В противном случае имя компьютера как будет воспринято как параметр.
Далее следует выражение GetWmiObject.
Вывод этого выражения передается в командлет Select-Object (сокращенно Select).
Мы используем хеш-таблицы, чтобы создать пользовательское свойство под названием
Computername. Фактически будет осуществлено переименованиеSystemName
текущего объекта ($_) в Computername. DeviceID остается неизменным.
Сделаем еще парочку хеш-таблиц. Первая берет свойство Size и делит его на 1GB,
вывод будет с двумя знаками после запятой и переименовывает свойство в SizeGB.
Вторая производит то же самое со свойством Freespace.
Затем создаем свойство UsedGB, которого нет в WMI. Вычисляется разница между
свойствами Size и FreeSpace и делится на 1GB.
В конце создаем еще одно свойство PerFree – свободно в процентах. Оно завершает
функцию.
Ниже приведена работа функции для компьютера CHI-FP01, выведенная в таблице
(Format-Table (или ft)) с авто форматированием (параметр –auto).
Все и так хорошо, но от этой функции мы можем получить больше. Поэтому
предположим, что вам нужно еженедельно получать отчет об использовании дисков на
всех серверах в вашей компании. Посмотрим, как этого можно достичь.
Для начала сохраним результаты нашего выражения в переменную $data, чтобы
каждый раз не набирать эту команду. Затем, передадим результаты в объект where,
пропингуем сервера (дважды) и передадим имя компьютера в созданную нами функцию
Get-DiskUtil.
Данные будут храниться в переменной $data. Вы можете вытащить информацию из
$data и отсортировать поcomputername, применив –auto. Информация также может
быть направлена на печать (Out-Printer) или в файл (Out-File).
Конвертируем в csv:
Потом Вы можете импортировать этот csv файл для получения снимка статуса
использования дисков на момент запуска команды:
Пример:
И напоследок: я покажу, как создать HTML отчет, доступ к которому можно получить из
любого места.
Берем $data и передаем ее в Sort Computername. Результат передается в командлет
ConvertTo-HTML. Вы можете присвоить заголовок и путь CSS. CSS необходим, так как
ConverToHTML не обладает возможностями форматирования. Поэтому если вы хотите,
чтобы отчет выглядит прилично, понадобится CSS файл. На последнем этапе пишем
результат в файл.
Теперь файл готов, его можно посмотреть с помощью команды start.
Пример HTML отчета.
Помните, что информацию необходимо держать информацию актуальной.
6. 10 Получаем последних ошибокжурнала событий
Каждое утро, вы возможно просматриваете журналы событий в поисках 10 последних
ошибок в системном журнале событий на одном или нескольких компьютерах.
Упростить эту задачу можно с помощью командлета Get-EventLog.
Нужно уточнить имя журнала событий и тип записи. Типичная команда для конкретной
задачи выглядит так:
В нашем случае взят журнал событий ‘system’ и тип записи ‘Error”. Если мы не уточняем
имя компьютера, информация собирается с локальной машины.
Обратите внимание на сообщения (Колонка Message), которые выведены не полностью.
Давайте немного изменим команду, что бы мы могли их видеть полностью.
Мы просто передали выход предыдущей команды в ft, сокращение для Format-Table и
задали отображения для таблицы следующих свойств: Timewritten, Source, EventID и
Message. Мы также добавили -wrap и -auto для более красивого отображения. -wrap
активирует обтекание текстов, а -auto – автоматическое форматирование.
Как это выглядит:
Создадим еще один вариант данной команды. Она сортирует свойства по Source и
затем осуществляет их группировку. Вывод передается в more для отображения только
того, что помещается на экран.
Пример:
Обратите внимание, что элементы сгруппированы по источнику. Сначала идет
EventLog, затем Microsoft-Windows-GroupPolicy. — More – указывает на завершения
отображения, необходимо нажать любую клавишу для того, чтобы посмотреть
дополнительную информацию.
Все эти Get-EventLog команды, которые были продемонстрировали, запущены на
локальном компьютере. Теперь покажем, как это сделать на удаленной машине.
Например, мне необходимо посмотреть 5 последний ошибок на контроллерах домена в
офисе в Чикаго (имена компьютеров chi-dc01 и chi-dc02). Предположим, что мне
необходимо отсортировать и сгруппировать результаты по Machine Name. Я также
хотел бы отобразить следующие свойства Timewritten, Source, EventID и Message. И
снова добавляю -wrap, -autoи more “для красоты”.
Получаем на выходе.
Рассматривая задачу №5 (получение информации по свободному месту на дисках), мы
рассматривали как можно сделать HTML отчет и выложить его на Интернет сервер; то
же можно сделать и с данной задаче.
7. Сброс контроля доступа к папке
Примеров, когда NTFS права на папку настроены не так, как надо, множество. Если это
случается, вы, возможно, захотите, спросить контроль доступа к этой папке. Это
реализуется с помощью командлета Set-Acl (Set-ACL).
Самый просто подход – использовать Get-Acl для извлечения ACL (Access Control List) из
“хорошей” папки и копировать его в проблематичную папку. Произведется замена
имеющегося ACL. Хотя и можно создать ACL объект с нуля, первый метод (копирование)
желателен, и сейчас я продемонстрирую почему.
Предположим, что имеется на компьютере CHI-FP01 папка sales и у этой папки есть
“хорошая” копия ACL. Копируем ACL и сохраняем в переменную $acl.
Давайте взглянем на информацию в ACL:
Видите свойство Access справа? Фактически это другой объект. Чтобы посмотреть его
содержимое, выполним команду:
Что внутри:
Как Вы видите, это записи контроля доступа. Если Вы хотите видеть только ссылки
(identity references), чьи имена совпадают с “Sales”, то выполните следующую команду:
Теперь если мы используем ту же команду, чтобы посмотреть содержимое свойства
Access, принадлежащего созданной папке chicagosales, мы ничего не получим.
Обратите внимание на использование сокращений:
Одной из возможных причин, почему значения не выводятся, может быть некорректная
выдача NTFS прав.
Очевидно, что решение этой проблемы – копировать “хороший” ACL в “плохой”. Но для
начала нужно получить текущие NTFS права папки chicagosales и сохранить в XML файл.
Это необходимо для восстановления ACL, если вдруг что-то пойдет не так (импортируем
XML файл).
После того, как это сделано, запускаем команду Set-Acl для chicagosales, используя
$acl, скопированную из хорошей папки.
Проверим, успешно ли осуществлена процедура: Используем ту же команду, которую
мы использовали ранее для отображения ссылок на тех, чьи имена совпадают с “Sales”.
Теперь chicagosales NTFS разрешения те же, что и для папки sales. Таким образом, у вас
есть простой способ управления разрешениями, позволяющий оперативно разрешить
проблемы контроля доступа.
8. Получение информации о времени работы сервера(uptime)
Вашем руководству возможно будет интересно регулярно получать информацию о
времени работы сервера. Используем для этого WMI класс Win32_OperatingSystem. Он
выведет время работы. Возможен локальный и удаленный запуск команды. Свойство,
которое нас интересует, LastBootUpTime. Но так как оно отображается в WMI формате,
нам нужно будет конвертировать в более приемлемый формат.
Начнем с примера запуска локально под Windows 7.
Сначала сохраним результаты GetWmiObject в переменную $wmi.
В $wmi присутствует несколько свойств, с которыми мы будем работать, а именно
CSName (имя компьютера) иLastBootUpTime.
LastBootUpTime отображается WMI формате, поэтому его нужно отконвертировать.
Сохраним отконвертированное значение в переменную $boot.
Мы используем метод ConverToDateTime, который включен во все WMI объекты,
которые вы получаете, когда запускаете GetWmiObject. Параметр, который вы
передаете в этот метод — свойство LastBootUpTime WMI объекта $wmi.
Запросив информацию о $boot, вы получите следующее, что гораздо нагляднее
предыдущего варианта LastBootUpTime:
Для определения времени работы машины, вычитываем $boot из текущих
даты/времени, которые могут быть получены с помощью Get-Date.
Результат выводится как TimeSpan объект. Отконвертируем его в строку для более
наглядного представления с помощьюToString().
Мы видим, что машина была запущена 2 дня 5 часов 46 минут и т.д.
А теперь все, что мы рассмотрели, запишем в виде функции под названием get-boot.
Сначала посмотрим на нее полностью.
У функции есть параметр, который берет имя компьютера и делает его именем
локального компьютера по умолчанию.
Затем мы используем фрагмент скрипта Process, где свойство “имя компьютера”
передается в функцию. “$_” указывает, что имя компьютера задается как переменная.
В противном случае имя компьютера как будет воспринято как параметр.
Включенное в фрагмент скрипта Process выражение GetWmiObject уточняет имя
удаленного компьютера.
Здесь также будет несколько хеш-таблиц. Свойство CSName поменяем на
Computername, так мы сможем получить более наглядное отображение. Свойство
LastBoot представляет собой значение LastBootUpTime, отконвертированное с
использование метода ConvertToDateTime(). И еще есть свойство Uptime, которое
представляет собой TimeSpan объект, показывающий, как долго машина была
запущена.
Если мы запускаем скрипт локально (например, нам не нужно уточнять имя
компьютера), функция по умолчанию берет имя локального компьютера. Вот что
получится на выходе:
Как в случае с задачей 2 предыдущего поста (“Перезагрузка или выключение сервера”),
Вы можете сохранить имена серверов в текстовый файл, обрабатывать те, которые
пингуются и передавать их имена в функцию get-boot.
9. service packПолучение информации о
Получать информацию о service pack важно по ряду причин. Во-первых, вы можете быть
в процессе установки обновления и вам важно нужно найти компьютеры с
определённым SP. Во-вторых, вы можете осуществлять инвентаризацию или аудит
ваших компьютеров, поэтому информация о SP вам будет нужна.
Для этого мы снова будет использовать WMI и класс Win32_Operating System. Обратите
внимание на некоторые свойства: the ServicePackMajorVersion – целое число (1, 2 или
0); ServicePackMinorVersion и CSDVersion, которое выводит информацию в строку,
например, “Service Pack 1”.
При работе нас интересуют в первую очередь свойства CSName (имя компьютера),
Caption (ОС), CSDversion иServicePackMajorVersion.
Типичное выражение выглядит следующим образом:
Как мы видим эта машина под Windows 7 не использует ни один SP, поэтому
ServicePackMajorVersion равно 0, а CSDVersion пусто.
Создадим функцию Get-SP. В качестве параметра возьмем имя компьютера, по
умолчанию совпадающее с именем локального компьютера.
И снова мы используем блок скрипта Process. Так что если имя компьютера
передается, переменная $computername будет установлена в качестве передаваемого
объекта. Основная часть функции – выражение класса
Get-Wmiobject/Win32_operatingsystem.
Как и прежде, создадим пару хеш-таблиц. CSName переведем в ComputerName.
Вместо свойства Caption используемOperating System. А вместо CSDVersion —
SPName. Наконец, вместо ServicePackMajorVersion используем простоVersion.
Вот пример функции, запущенной локально:
Теперь можно взять компьютеры из текстового файла, пропинговать их и передать их
имена в созданную функцию get-sp. Результат:
Можно видеть, что у CHI-DC02 отсутствует Service Pack 1, который только недавно был
выпущен для Server 2008 R2. А это дает основания задуматься об обновлении Service
Pack на этом компьютере.