Удаленное выключение компьютеров на ночь

Проблема


Требуется обеспечить принудительное выключение определенных клиентских компьютеров в ночное время. Все компьютеры являются членами домена Active Directory.

Теория


Как удаленно выключить компьютер?

Вариантов удаленного выключения существует довольно много:

  • через графическую консоль Управление компьютером (Computer Manager), подключенную к удаленному компьютеру;
  • через штатную утилиту shutdown.exe;
  • с помощью сценария PowerShell;
  • и т.п.

На мой взгляд, для автоматизации задачи массового принудительного удаленного выключения компьютеров лучше всего подходит утилита PsShutdown.exe, являющаяся частью пакета PsTools.

Вариант команды PsShutdown может быть таким:

C:\>PsShutdown \\XP01 -s -f -t 300 –c –n 10 -e p:0:0 –m "Night shutdown. Please contact Servicedesk if you have any questions. Servicedesk phone: 123-45-67."

Описание используемых ключей:

\\XP01 – имя удаленного компьютера, можно заменить файлом со списком компьютеров (например, @C:\Scripts\Computers.txt)

-s – выключение компьютера (если все компьютеры поддерживают режим гибернации, можно заменить ключом –h);

-f – принудительное закрытие всех открытых приложений;

-t 300 – указание времени в секундах, в течение которого выводится окно уведомления о выключении компьютера;

-c – опция, позволяющая пользователю удаленного компьютера отменить выключение (пользователю будет выводиться кнопка Cancel);

-n 10 – максимальное время в секундах, отводимое на подключение к удаленному компьютеру;

-e p0:0 – указание, что выключение является плановым;

-m “Night shutdown. Please contact Service Desk if you have any questions. Service Desk phone: 123-45-67.” – текст уведомления; замените на свой собственный.

image

Как сделать выборку компьютеров?

Можно, конечно, вручную создать текстовый файл, в котором перечислить все компьютеры, которые следует выключать. А можно автоматизировать создание актуальной выборки на основе данных из Active Directory.

Проще всего сделать выборку с помощью утилиты dsquery.exe, присутствующей на серверах или в составе пакета RSAT.

Ниже приведен вариант выборки, создающей список всех компьютеров из контейнера Desktops в домене corp.gorbunov.pro:

C:>DSQUERY *  "OU=Desktops,DC=corp,DC=gorbunov,DC=pro" -filter (objectCategory=computer) -attr name -l > C:\Scripts\Computers.txt

Результат выборки – файл C:\Scripts\Computers.txt со списком имен компьютеров.

Финальное решение


Шаг 1

Создаем на сервере папку C:\Scripts, в которую копируем утилиту PsShutdown.exe.

Шаг 2

В папке C:\Scripts создаем пакетный файл под названием RemoteShutdown.bat.

Файл создает выборку C:\Scripts\Computers.txt и затем запускает массовое выключение компьютеров из выборки.

Для контроля работы файла RemoteShutdown.bat создается файл журнала RemoteShutdownLog.txt.

Листинг файла RemoteShutdown.bat:

@ECHO OFF

DSQUERY * "OU=Desktops,DC=corp,DC=gorbunov,DC=pro" -filter (objectCategory=computer) -attr name -l > C:\Scripts\Computers.txt

C:\Scripts\PsShutdown -s -f -t 300 -c -n 10 -e p:0:0 -m "Night shutdown. Please contact Servicedesk if you have any questions. Servicedesk phone: 123-45-67." @C:\Scripts\Computers.txt > C:\Scripts\RemoteShutdownLog.txt

Для своей сети замените OU=Desktops,DC=corp,DC=gorbunov,DC=pro на путь к своему домену и контейнеру с компьютерами. Фильтр objectCategory=computer можно заменить на свой LDAP-запрос.

Шаг 3

В папке C:\Scripts создаем пакетный файл под названием CancelShutdown.bat.

Этот файл будет полезным для экстренной отмены выключения.

Листинг файла CancelShutdown.bat:

C:\Scripts\PsShutdown -a -n 10 @C:\Scripts\Computers.txt

 

Шаг 4

Добавляем на сервере файл RemoteShutdown.bat в Планировщик заданий для запуска, например, ежедневно в 22:00.

 

Подробнее об утилите DSQUERY:
http://technet.microsoft.com/en-us/library/cc754232.aspx 

Подробнее об утилите PsShutdown:
http://technet.microsoft.com/ru-ru/sysinternals/bb897541.aspx

28 комментариев:

  1. скажите, а на заблокированных компьютерах это будет срабатывать?

    ОтветитьУдалить
  2. Да, заблокированный компьютер выключается с принудительным закрытием сессии пользователя. Главное, чтобы PsShutdown смогла к удаленному компьютеру подключиться (используется подключение к административной папке Admin$).

    ОтветитьУдалить
  3. Алексей, подскажите пожалуйста, какие службы должны быть включены для правильной работы PsShutdown? или какие нибудь дополнительные права пользователя? А то при попытке послать команду на удаленный компьютер, выдает "Доступ запрещен".

    «Couldn’t access ip: Access Denied
    If (ip adress) is already performing a shutdown operation you must abort it before issuing a different command.»

    Это при обращении по IP, при обращении по имени компьютера-тоже самое. Пробовал полностью отключать фаерволы-не помогло.

    ОтветитьУдалить
  4. Вот описание системных требований для PsShutdown (http://www.windowsitpro.com/article/administration-tools2/psshutdown).

    Проверьте, все ли настроено в соответствии с требованиями; если не заработает, пишите, будем лечить :-)

    PsShutdown shares its remote-access capabilities with several other members of the PsTools suite, including PsExec. PsShutdown extracts a Windows service executable to the system that it will control through that system's Admin$ share, starts the service, then sends the service a command that reflects the options you've specified. The service uninstalls after it completes the command. Therefore, you must enable file sharing on any remote computers on which you want to use PsShutdown, and the Admin$ share (which is defined by default) must be defined and accessible through the Common Internet File System (CIFS)/Server Message Block (SMB) and Remote Procedure Call (RPC) TCP/IP ports. The account from which you run PsShutdown must have Administrative group membership on all target systems, or you must use the tool's -u switch to specify an account that has the necessary permissions.

    ОтветитьУдалить
  5. "...and accessible through the Common Internet File System (CIFS)/Server Message Block (SMB) and Remote Procedure Call (RPC) TCP/IP ports..." А где эти "звери" живут и как проверить, включены ли они?

    ОтветитьУдалить
  6. Ну, вот... Отключил полностью UAC на обоих компьютерах и все заработало. Но оставлять отключенным его что-то не хочется, наверное нужно создать где-то правило (не в брендмауэре Windows 7, они у меня отключены, т.к. использую другой)для psshutdown.exe?

    ОтветитьУдалить
  7. Только вот сообщения все равно не проходят (не появляются).

    ОтветитьУдалить
  8. Александр, синтаксис помотрите к утилите повнимательней. тма есть нужный ключик

    ОтветитьУдалить
  9. Собственно, приведенный пример с PsShutdown тоже работает одной строкой. Пакетный файл нужен, чтобы автоматически создавать выборку из Active Directory, а не поддерживать список компьютеров в актуальном состоянии вручную.

    ОтветитьУдалить
  10. psshutdown.exe \\HPdv6700 -u den -p 123 -d вот такая команда работает только при отключенном антивирусе на удаленном компьютере. Что нужно добавить в правилах антивируса чтобы оно работало

    ОтветитьУдалить
  11. Часто есть компьютеры, которые нужно оставить включенными, при этом проще не раскидывать эти машины по разным OU, а сделать политику для группу (например "Evening Shutdown")
    Выборка при этом, будет выглядеть примерно так:
    dsget group "CN=Evening Shutdown,OU=Desktops,DC=corp,DC=gorbunov,DC=pro" -members -filter (objectCategory=computer) -attr name -l > C:\Scripts\Computers.txt

    ОтветитьУдалить
    Ответы
    1. Тоже красивый вариант. Минус лишь, что управлять группой нужно вручную, добавлять/удалять компьютеры. В каких-то ситуациях можно, наверное, даже скомбиноровать выборки из DSQUERY и DSGET GROUP. Короче, поле для фантазии широкое открывается :-)

      Удалить
  12. Этот комментарий был удален автором.

    ОтветитьУдалить
  13. FOR /F %G IN ('net view ^| find "\\" ^| findstr /V /G:UOC.TXT') DO shutdown /s /f /t 60 %G

    в самом конце перед %G добавить /m

    ОтветитьУдалить
  14. Проверен основной рассматриваемый вариант.
    Резюме: проверяет доступность всех компьютеров, в итоге список из 230 записей в AD прогонял полчаса, в принципе это не так много для ночи, но в итоге почему-то не закрылся пакетный файл и соответственно лог не записался.
    Вариант m.naumenko более приемлемый т.к. он делает выборку из включенных на данный момент станций, как правило это 1-2 и то не каждый день

    ОтветитьУдалить
  15. Как написать уведомление на русском языке (кирилицей)?

    ОтветитьУдалить
  16. При попытке выключить удаленные компьютеры при помощи назначенного задания, выдает сообщение:
    "If WS027 is already performing a shutdown operation you must abort it before issuing a different command."
    Правда некоторые компьютеры уже были выключены, но на включенных выдавал такое же сообщение. В чем может быть проблема?

    ОтветитьУдалить
  17. как можно реализовать повторное открытие всех закрытых при выключении программ?

    ОтветитьУдалить
  18. А как быть в случае с Windows 7? Появляется интерактивное сообщение: "Программа, запущенная на этом компьютере, пытается отобразить сообщение..."

    ОтветитьУдалить
    Ответы
    1. Вариант скрипта ниже:

      Set WSHShell = WScript.CreateObject("WScript.Shell")
      Set oFS = CreateObject("Scripting.FileSystemObject")

      strWarning = "Due to network maintenance, this computer must be restarted. You have 5 minutes to save your work from the start of this countdown. Sorry for any inconvenience caused. "
      strDelay = 300 'Delay given in seconds; change this value to your preference, or set it to 0 to give no delay at all

      'Open a text file of computer names
      'with one computer name per line
      Set oTS = oFS.OpenTextFile("C:\computers.txt")

      'go through the text file
      Do Until oTS.AtEndOfStream
      'get the next computer name
      'store it in variable strCompname
      strCompname = oTS.ReadLine
      WshShell.Run "C:\Windows\System32\shutdown.exe -m \\" & strCompname & " -r -c " & Chr(34) & strWarning & Chr(34) & " -t " & strDelay 'Replace the "-r" switch with "-s" to make the computers shutdown instead
      Loop
      'close the text file
      oTS.Close


      Взято отсюда: http://www.edugeek.net/forums/windows-7/102750-psshutdown-windows-7-a.html

      Удалить
  19. Вот вариант cmd скрипта без psshutdown и промежуточного файла.

    @echo off

    for /f "tokens=*" %%i in (
    'dsquery * "CN=Computers,DC=domain,DC=ru" -filter "(&(objectCategory=computer)(name=*YOUR_NAME*))" -attr name -l ^| sort'
    ) do start /B shutdown /s /m \\%%i /t 30 /d p:0:0 /c "Nightly Shutdown"

    ОтветитьУдалить
    Ответы
    1. Промежуточный файл был запрошен заказчиком для контроля процесса.

      Удалить
  20. Не работает. Задание отрабатывает. Список пополняется. К компам коннектится и пишет что они уже выполняют шутдаун. Причем не зависимо от того включен этот комп или нет.

    ОтветитьУдалить
    Ответы
    1. Возможно, старые утилиты уже не подходят для Windows 7 с последними обновлениями. Давно все разрабатывалось.

      Удалить
  21. Сделал свой скрипт с группой через dsget с другой фильтрацией, кстати скрипт с группой выше тут, не рабочий изначально нет такого метода -filter, тут выше вообще ни одного толком рабочего скрипта нет А Я ВСЕ ПОПРОБОВАЛ РЕАЛЬНО. Все сырое. Автор блога ты бы хоть причесывал его. Свой выкладывать тут не буду. Кому надо стучите отпишу в личку.

    ОтветитьУдалить
    Ответы
    1. 1. Мы незнакомы, поэтому никак не "ты".
      2. Все скрипты оттестированы и работали на момент написания статьи четыре года назад. Учимся копи-пастить из веб сайта в командную строку без вставки спецсимволов.
      3. Внимательно читаем документацию по утилите dsquery и узнаем, как пользоваться ключом -filter: http://technet.microsoft.com/ru-ru/library/cc754232(v=ws.10).aspx

      Удалить
  22. сделал все тоже самое, при выполнения задания зависает psshutdown, может подскажите что нито?

    ОтветитьУдалить