Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МУ_ЛР_БОС.doc
Скачиваний:
112
Добавлен:
08.05.2019
Размер:
1.15 Mб
Скачать

Практика

Типовая задача, которую можно встретить почти везде, состоит в периодическом перезапуске сервисов. Желательно с отчетом о результате выполнения и пр.

Собственно данная логика легко реализуется с помощью следующего скрипта.

# функция перезапуска сервиса

function restart-service {

# парамет вызова – имя сервиса

param ($srvName)

# Останавливаем сервис

Stop-Service $srvName

$service = get-service $srvName

# читаем его состояние

if ($service.status -ne "Stopped") {

# если не удалось остановить сервис то отправляем сообщение

send-email($srvName + " has failed to stop, please manually stop and restart.")

Write-Host ($srvName + " has failed to stop, please manually start.")

}

# Запускаем сервис

start-Service $srvname

$service = get-service $srvName

if($service.status -ne "Running") {

# если не удалось запустить сервис то отправляем сообщение

send-email ($srvName + " has failed to start, please manually start.")

Write-Host ($srvName + " has failed to start, please manually start.")

} else {

Write-Host ($srvName + " has started.")

}

}

# функция отправки сообщения

function send-email {

param ($body)

# от кого

$From = report@example.com

# кому

$To = admin@example.com

# тема сообщения

$Subject = "Service problem on server – SRV01"

# указываем имя SMTP сервера

$SMTPServer = "SMTP_HOST_NAME"

$SMTPMessage = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body

$SMTPClient = New-Object System.Net.Mail.SMTPClient $SMTPServer

$SMTPClient.Send($SMTPMessage)

}

# перестартовываем сервис BITS

restart-service Bits

Настройка сервисов

Не буду вдаваться во все нюансы настройки и приведу только основные примеры.

Смотрим каковы имена и типы запуска сервисов

# вывести список сервисов и их режимом запуска

Get-WmiObject -Class Win32_Service | format-table Name, StartMode –autosize

# вывести только отключенные сервисы

Get-WmiObject -Class Win32_Service | Where-Object {$_.StartMode -eq ‘Disabled’}

Настройка типа запуска сервиса «вручную», «автоматически», «отключено» производится следующими командами.

Set-Service service_name -StartupType Manual

Set-Service service_name -StartupType Automatic

Set-Service service_name -StartupType Disabled

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

Get-Service -name Schedule -computername SRV1, SRV2 | Set-Service -Status paused

Управление процессами

За получение списка процессов в PowerShell отвечает команда Get-Process. Можно запрашивать процесс или список процессов по имени или по маске:

# Запрашиваем процесс по имени

Get-Process cmd

# или запрашиваем процесс по маске. Будут найдены процессы по маске "c*"

Get-Process c*

# Запрашиваем несколько процессов по маскам "cm*" и "po*"

Get-Process cm*, po*

Полученный результат подлежит форматированию.

# В виде таблицы т.е. его задавать не надо т.к. отображается по умолчанию.

Get-Process p* | Format-Table

# В виде списка

Get-Process p* | Format-List

# В "растянутом" виде

Get-Process p* | Format-Wide

Так же результат можно вывести в файл.

Get-Process p* | Format-List | Out-File D:\Script\Result.txt

На выходе команды Get-Process всегда получается объект имеющий набор стандартных свойств. Для получения их списка вводим команду.

Get-Process | Get-Member

TypeName: System.Diagnostics.Process

Name MemberType Definition

()

Handles AliasProperty Handles = Handlecount

Name AliasProperty Name = ProcessName

()

Записываем нужные нам для работы свойства. Например Name, Handles, ID, Company и прочие.

Теперь мы совершенно легко можем найти процессы у которых handlecount больше чем 500.

Get-Process | where {$_.handlecount -gt 500}

Или найти все процессы от отпеределенного производителя.

Get-Process | Where {$_.company -eq "Oracle Corporation"}

Работа с процессами на удаленном компьютере почти не отличается от работы с локальными процессами, вам необходимо только указать параметр -comp или -ComputerName.

Запрос процессов на удаленном компьютере выглядит так.

# Запрашиваем список процессов по маске "svchost*"

Get-Process -comp remote-host | where {$_.name -like "svchost*"}

# Запрашиваем список процессов по маске "svchost*" или "wmiprvse*"

Get-Process -comp remote-host | where {$_.name -like "svchost*" -or $_.name -like "wmiprvse*"}

# Можно упростить ввод и воспользоваться командой

Get-Process svchost*, wmiprvse* -comp remote-host

# Или искать сразу на нескольких хостах

Get-Process svchost*, wmiprvse* -comp remote-host1, remote-host2

Второй метод запроса процессов заключается в использовании WMI класса Win32_Process.

Get-WMIObject -Class Win32_Process -ComputerName "REMOTE-HOST" | Select ProcessName, ProcessId

Команда Start-Process запускает процессы.

# Запуск экземпляра cmd.exe

Start-Process cmd.exe

# Запуск экземпляра cmd.exe от имени другого пользователя

Start-Process cmd.exe -Credential (Get-Credential)

Команда Stop-Process останавливает процесс. Для примера можно привести закрытие всех запущенных сеансов cmd.exe.

# Остановка всех найденных экземпляров cmd.exe

Get-Process cmd | Stop-Process

# то же самое что и первое

Stop-Process –Name cmd

# Остановка процесса по его ID

Stop-ProcessId 2268

Примечание: Для надежности используйте ключи -WhatIf и -Confirm для получения списка предпринимаемых действий (тестирование того что будет сделано) и запроса подтверждения действия команды.

Get-Process cmd | Stop-Process –WhatIf

Get-Process cmd | Stop-Process –Confirm

Главное не пробовать сделать так:

Get-Process | Stop-Process

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

Командлеты Get-Process, Start-Process, Stop-Process для своей работы используют .NET класс [System.Diagnostics.Process]. Он имеет несколько статичных методов которые можно посмотреть с помощью команды.

[System.Diagnostics.Process] | Get-Member -Static -MemberType method

Вызов методов из полученного списка производится по имени следующим образом.

[System.Diagnostics.Process]::StaticMethodName(<args>)

Для демонстрации можно привести следующий пример

$computer="SERVER-01"

$process = [System.Diagnostics.Process]

# запрашиваем список процессов

$process::GetProcesses($computer)

Посмотрев список полученных процессов идем дальше.

Для получения списка доступных методов вводим.

$process::GetProcessById(2008,$computer) | Get-Member -Member method

Первое что бросается в глаза это

Kill Method System.Void Kill()

Им мы и воспользуемся для завершения процесса по его ID.

$process::GetProcessById(2008,$server).Kill()

Примечание: Переменная $computer должна указывать на локальный сервер т.к. метод kill не поддерживается для работы с удаленными ПК.

Для завершения процессов на удаленных хостах поддерживается и вполне работоспособен вот такой вызов метода Terminate().

(Get-WMIObject Win32_Process -Filter "Name=’cmd.exe’" -ComputerName "REMOTEHOST").Terminate()

__GENUS : 2

__CLASS : __PARAMETERS

__SUPERCLASS :

__DYNASTY : __PARAMETERS

__RELPATH :

__PROPERTY_COUNT : 1

__DERIVATION : {}

__SERVER :

__NAMESPACE :

__PATH :

ReturnValue : 0

Результаты его работы можно оценить по полученному коду завершения операции.

  • 0 – Successful Completion. Процесс прибит успешно

  • 2 – Access Denied. Отказано в доступе

  • 3 – Insufficient Privilege. Не хватило прав

  • 8 – Unknown Failure. Непонятный отбой

  • 9 – Path Not Found. Нет такого процесса

  • 21 – Invalid Parameter. Неверно задан параметр