В Windows 10 есть режим ночного света, меняющий свет экрана с дневного на более теплый и обратно. Это работает вручную, по фиксированному расписанию или на закате и восходе. И я не раз видел желающих применить именно последний вариант для смены цветов ОС или плана электропитания. Поскольку встроенного решения нет, эти люди обламываются и соглашаются на фиксированное время в планировщике заданий.
Приемы работы с ним я неоднократно показывал, и в этот раз применю, но чуть более изобретательно. Я подготовил набор скриптов PowerShell, которые создают необходимые задачи в планировщике и выполняют команды.
Для примера они задают на восходе светлые цвета ОС и приложений, а на закате – темные.
Вы сможете прописать свои команды в двух скриптах PowerShell или изменить созданные задачи в графическом интерфейсе taskschd.msc, настроив для себя запуск скриптов cmd, vbs и т.д. А для тех, кто захочет существенно изменить под свои цели исходные скрипты, в рассказе есть большой теоретический раздел.
[+] Сегодня в программе
- Как это работает
- Ограничения этого подхода
- Практика
- Теория
- Получение и обработка гео-данных
- Создание и изменение запланированных заданий в PowerShell
- Изменение заданий под себя (нюансы планировщика)
- Запуск в зависимости от выполненного входа
- Запуск в контексте другого пользователя
- Запуск для нескольких пользователей
- Запуск без моргания окон PowerShell
- Диагностика
- Заключение
Как это работает
Вкратце, схема несложная:
- В планировщике создается три задания.
- Основное задание от имени системы ежедневно получает из внешнего сервиса время восхода / заката и обновляет время запуска вспомогательных заданий.
- Вспомогательные задания от имени пользователя выполняются на восходе или закате.
В скриптах предусмотрены некоторые нюансы вроде выполнения пропущенной задачи без задержек.
Ограничения этого подхода
Чтобы все работало, необходимо соблюдения двух условий.
Доступность сервиса с гео-данными
Время восхода и заката берется с сервиса https://sunrise-sunset.org/. Эта ссылка была фактически первой в Google, но есть и другие бесплатные ресурсы — например, API метеорологического института Норвегии. Изменить скрипт под другой сервис очень просто, как вы увидите ниже.
Наличие у пользователя достаточных прав на выполнение команд
Вспомогательные задачи выполняются с наивысшими правами, доступными пользователю, от имени которого они запускаются. Аккаунту из группы администраторов все по плечу, но учетная запись с обычными правами не может выполнять задачи, требующие повышения прав.
В принципе, вспомогательные команды тоже можно выполнять от имени системы, что я разберу в теоретической части статьи. Но это годится только для изменения системных параметров (смена плана электропитания), и не подходит для внесения изменений в параметры текущего пользователя (смена цветовой схемы).
Практика
Я думаю, вам будет интереснее сразу перейти к практике, убедиться в работоспособности скриптов, а потом уже разбираться с теорией.
Содержимое архива
В архиве sunrise-sunset.zip четыре скрипта PowerShell.
Скрипт | Назначение |
---|---|
set_tasks.ps1 | Создает три запланированных задания: • Sunrise-Sunset-Time (основное) • Sunrise • Sunset |
sunrise_sunset_time.ps1 | Выполняется от имени системы из основного задания: ежедневно по расписанию, при входе любого пользователя в систему и при выходе из сна/гибернации. Скрипт получает время восхода и заката, обновляет время запуска вспомогательных заданий и запускает их при необходимости.
Например, если ПК был выключен вечером после заката, а включен днем после рассвета выполняется задание Sunrise. |
sunrise.ps1 | Выполняется из задания Sunrise для запуска скрипта на рассвете. |
sunset.ps1 | Выполняется из задания Sunset для запуска скрипта на закате. |
Содержимое двух последних скриптов вы можете менять на свое усмотрение.
Создание задач в планировщике
- Скачайте архив sunrise-sunset.zip и распакуйте в папку, в которой в дальнейшем будут храниться скрипты. Если вы впоследствии поменяете путь к скриптам, придется править задачи в планировщике или пересоздавать их.
- Откройте скрипт sunrise_sunset_time.ps1 в текстовом редакторе, укажите широту и долготу своего местоположения (карты Google или Яндекс в помощь) и сохраните файл.
- В проводнике перейдите в папку со скриптами, из меню Файл выберите Запустить Windows Powershell от имени администратора и выполните команду ниже (также можно явно задать путь к папке параметром
-Path
):powershell -ExecutionPolicy Bypass '.\set_tasks.ps1'
Это все! В планировщике появятся три задачи с именами, начинающимися на Sun
. Если он был открыт во время выполнения команды, нажмите F5.
Цвета ОС и приложений могут сразу же поменяться — например, они станут темными, если команда выполнялась после заката.
Изменение задач под себя (основы)
Вам достаточно прописать свои команды PowerShell в скриптах sunrise.ps1 и sunset.ps1. Сейчас там просто изменяются два параметра реестра, например, на закате:
#Переключиться на темные цвета #Windows New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -Value 0 -Type Dword -Force #приложений New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 0 -Type Dword -Force
Если вас это чем-то смущает или не устраивает, откройте одноименные задания в планировщике и пропишите нужные команды и их аргументы на вкладке Действия. Например, в качестве команды вы можете просто указать полный путь к CMD-файлу.
Более детальный разбор заданий в теоретической части статьи.
Теория
Этот раздел для тех, кто хочет лучше понять, как все работает, а также разобраться в нюансах планирования задач с PowerShell и содержимом скриптов. Их по сути два:
- sunrise_sunset_time.ps1 – это небольшой скрипт, который получает гео-данные, обновляет время запуска задач и запускает их, если необходимо.
- set_tasks.ps1 используется однократно для создания задач планировщика. Он выглядит объемнее, но лишь из-за специфики командлетов модуля scheduledtasks и количества комментариев.
Получение и обработка гео-данных
Сервис Sunrise-Sunset отдает JSON по ссылке, принимающей параметры широты, долготы и даты.
$lat = "55.753595" $lng = "37.621031" $today = Get-Date -f "yyyy-MM-dd" $j = Invoke-RestMethod "https://api.sunrise-sunset.org/json?lat=$($lat)&lng=$($lng)&date=$($today)&formatted=0" $j.results.sunrise
В API поддерживается указание сегодняшнего дня параметром &date=today
, однако сервис завязан на UTC. Поэтому на запрос с таким параметром, например, в 00:01 по Москве, сервис ответит вчерашними данными по московскому времени.
Поэтому в скрипте дата задается явно с помощью формата командлета Get-Date, что я уже показывал в блоге. Затем командлет Invoke-RestMethod получает данные, а дальше просто выбираются сведения из нужного узла. Для наглядной работы с узлами можно отформатировать полученный JSON.
Аналогично для сервиса норвежского метеоинститута команды были бы такие:
$n = Invoke-RestMethod -uri "https://api.met.no/weatherapi/sunrise/2.0/.json?lat=$($lat)&lon=$($lng)&date=$($today)&offset=+03:00" $n.location.time.sunrise.time
Это было просто.
Создание и изменение запланированных заданий в PowerShell
Я не раз показывал в блоге работу с schtasks (вот хороший пример). С помощью ключей schtasks формируются параметры задания, а само оно создается, опрашивается, изменяется или удаляется одной командой. Без справки с ключами не разобраться, но в итоге получается команда в одну строку.
В PowerShell сделаны отдельные командлеты для работы с заданиями, в частности для:
- управления (создание, удаление, экспорт и т.д.)
- настройки, т.е. как минимум по одному командлету для каждой вкладки задания планировщика, если апеллировать к графическому интерфейсу (параметры командлетов уже определяют конкретные настройки на вкладке)
В результате для создания или изменения задачи требуется несколько строк кода. И хотя названия командлетов лучше понятны интуитивно, чем ключи schtasks, от всего этого рябит в глазах.
Создание
Давайте посмотрим на процесс создания задачи Sunrise-Sunset-Time (фрагмент скрипта set_tasks.ps1). Переменные фактически соответствуют английским названиям вкладок в интерфейсе планировщика, а код я подробно прокомментировал.
#Переменные $path = (Get-Location).path $system = "NT AUTHORITY\SYSTEM" #Создание задания $taskname = "Sunrise-Sunset-Time" #Общие: выполнять с наивысшими правами от имени системы вне зависимости от входа $principal = New-ScheduledTaskPrincipal -UserId $system -LogonType ServiceAccount #Триггеры $trigger = @( #Запускать ежедневно сразу после полуночи (не пробуждая ПК) $(New-ScheduledTaskTrigger -Daily -At 00:01), #Запускать при входе пользователя в систему $(New-ScheduledTaskTrigger -AtLogon) ) #Параметры: запускать при работе от батареи; запускать немедленно если пропущено $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -StartWhenAvailable #Команда... $execute = "powershell" #... и ее параметры командной строки $argument = "-ExecutionPolicy Bypass -WindowStyle Hidden -file $path\sunrise_sunset_time.ps1" #Действие: "команда + параметры командной строки" $action = New-ScheduledTaskAction -Execute $execute -Argument $argument #Создать задание в планировщике Register-ScheduledTask -TaskName $taskname -Action $action -Trigger $trigger -Settings $settings -Principal $principal
Читать это можно снизу вверх. Сама задача создается командлетом Register-ScheduledTask. Но сначала ее настройки формируются с помощью нескольких командлетов. При этом у New-ScheduledTaskAction, отвечающего за действие задачи, предусмотрены раздельные параметры для команды и ее ключей.
Также обратите внимание, как задается несколько триггеров одновременно. К сожалению, у командлета New-ScheduledTaskTrigger не предусмотрен параметр для триггера по событию в журнале. Поэтому триггер на событие выхода из сна / гибернации добавляется обходным путем уже после создания задачи (см. код в скрипте).
Изменение
С этим несколько проще. Задача Sunrise-Sunset-Time запускает скрипт sunrise_sunset_time.ps1, в котором есть такой фрагмент:
$j = Invoke-RestMethod "https://api.sunrise-sunset.org/json?lat=$($lat)&lng=$($lng)&date=$($today)&formatted=0" $sunrise = New-ScheduledTaskTrigger -Once -At $j.results.sunrise Set-ScheduledTask -TaskName "Sunrise" -Trigger $sunrise
Полученное из гео-сервиса время заносится в переменную, а она в свою очередь используется для формирования триггера командлетом New-ScheduledTaskTrigger. Затем этот триггер передается командлету Set-ScheduledTask, изменяющему задание.
Разобраться в модуле scheduledtasks с наскока затруднительно. Надо практиковаться, читать документацию и гуглить в тяжелых случаях.
Изменение заданий под себя (нюансы планировщика)
Есть несколько моментов, которые нужно учитывать в зависимости от ваших целей и пользователей, для которых должны отрабатывать задания. Это больше относится к планировщику, нежели к PowerShell.
Запуск в зависимости от выполненного входа
Основное задание запускается от имени SYSTEM вне зависимости от входа. Для такого случая у командлета New-ScheduledTaskPrincipal есть параметр -LogonType
, задающий служебный аккаунт.
$system = "NT AUTHORITY\SYSTEM" $principal = New-ScheduledTaskPrincipal -UserId $system -LogonType ServiceAccount
Вспомогательные задания выполняются в контексте пользователя, только когда он выполнил вход. Допустим, в некий момент времени ПК включен, но пользователь не вошел в систему. В этом случае основной скрипт отработает и обновит время запуска вспомогательных. Дальше допустим, что пользователь вошел в систему позже запланированного времени.
Если бы у основного задания был только триггер на расписание, пропущенные задания выполнялись бы спустя несколько минут после входа пользователя. Однако благодаря триггеру на вход в систему, основной скрипт снова запустится и форсирует запуск вспомогательного, если необходимо. Аналогично работает и сценарий выхода из сна/гибернации.
Если вы хотите выполнять команды от имени своей учетной записи вне зависимости от ее входа, на вкладке Общие нажмите Выполнять для всех пользователей – ОК – введите пароль своего аккаунта.
Если ваши команды изменяют параметры системы, а не пользователя (например, меняют план электропитания), вы можете перевести вспомогательные задания в системный контекст. Для этого на вкладке Общие нажмите Изменить и введите имя СИСТЕМА или SYSTEM в зависимости от языка вашей ОС.
Запуск в контексте другого пользователя
Скрипт set-tasks.ps1 создает вспомогательные задания для пользователя, который его запускает, т.е. для вашей учетной записи. Вы можете указать вместо себя другого пользователя при запуске скрипта параметром -User
в формате "Имя_компьютера\Имя_пользователя"
. Например, для пользователя на картинке выше:
powershell -ExecutionPolicy Bypass '.\set-tasks.ps1' -User "DESKTOP-EHPD2RM\Admin" -Path "C:\MyScripts"
Если задания уже созданы, на вкладке Общие нажмите Изменить и введите имя пользователя.
Запуск для нескольких пользователей
Чтобы вспомогательные скрипты работали для нескольких пользователей в их контексте, можно создавать события в журнале. Либо так:
- В планировщике экспортировать задачи Sunrise и Sunset и импортировать их с другими именами, а затем указать для клонов нужных пользователей.
- Добавить в скрипт sunrise_sunset_time.ps1 команды для обновления времени клонов и их запуска в сценарии "пропущено назначенное время выполнения задания".
Если вам это необходимо, попрактикуйтесь самостоятельно.
Запуск без моргания окон PowerShell
Несмотря на -WindowStyle Hidden
в аргументах скриптов, при их запуске из планировщика могут появляться окна PowerShell.
Этого не происходит для заданий, которые выполняются вне зависимости от входа пользователя в систему (в частности, для основного скрипта Sunrise-Sunset-Time). Но имейте в виду, что в этом случае скрипты выполняются в сеансе 0.
Отсюда следует несколько решений на выбор для вспомогательных заданий. Вы можете:
- выполнять их от имени системы, если изменяются параметры ОС, а не пользователя
- выполнять их от своего имени, сохранив учетные данные
- запускать из планировщика скрипт VBS, из которого в свою очередь вызывается скрипт PowerShell
Первые два способа я рассмотрел выше, а третий показывал в своем канале Telegram
Диагностика
Концептуально решение должно работать начиная с Windows 7 (с WMF 5.1), но я тестировал только на русской и английской Windows 10 1909. На случай, если что-то пойдет не так, я подобрал рекомендации по отладке скриптов и заданий планировщика.
В рамках диагностики:
- выполняйте все команды и скрипты от имени администратора
- после запуска заданий планировщика нажимайте F5, чтобы обновить картину
Основное задание не обновляет вспомогательные
- Выполните задание вручную и убедитесь, что изменилось время его последнего запуска, а операция завершилась успешно. Ошибки могут означать недостаток прав на выполнение команды или неверную конфигурацию действия.
- Измените время запуска вспомогательного задания и запустите основное, а затем проверьте, поменялось ли время вспомогательного.
- Если время не изменилось, возможно, не удается достучаться до гео-сервиса. Откройте ссылку ниже в браузере, и если она открывается, выполните в PowerShell:
Invoke-RestMethod 'https://api.sunrise-sunset.org/json?lat=55.751510&lng=37.618877&date=today&formatted=0'
Если данные отображаются, нужно разбираться с дальнейшей логикой скрипта sunrise_sunset_time.ps1.
Вспомогательные задания не работают
- См. п.1 выше.
- Выполняйте скрипты sunrise.ps1 и sunset.ps1 или их команды в PowerShell и смотрите, что происходит. Если не работает, дело не в планировщике.
- Пробуйте прописать в скриптах что-нибудь простое, например, запись текущей даты в текстовый файл:
Get-Date | Out-File -FilePath C:\scripts\test.txt -Force
- Если это работает, выполняйте одноименные задания в планировщике.
Помощь
Если вам необходима помощь, предоставьте в комментариях:
- Экспортированные задания планировщика плюс скрипты sunrise.ps1 и sunset.ps1 (если меняли). Все должно быть упаковано в ZIP и залито на Яндекс.Диск / OneDrive / Google Drive.
- Команды и ошибки при их выполнении в текстовом виде на https://pastebin.com/, в скриншотах – на хостинге картинок.
- Подробное описание проблемы и отчет по мотивам диагностики выше.
Заключение
Если бы в планировщике уже было некое задание с триггерами на восходе и закате, можно было бы цепляться к нему или клонировать путем экспорта/импорта, но я такого не нашел. Наверное, ночной свет использует API встроенной в систему службы местоположения, что было бы логично.
Скрипт создания задач планировщика выглядит сложновато для неподготовленного человека. Но лезть в него необязательно, поскольку параметры созданных задач можно изменять в графическом интерфейсе taskschd.msc. Все остальное укладывается в дюжину строк кода PowerShell.
При этом мой подход несложно адаптировать под другие задачи, выполняющиеся на основе различных гео-данных, прогноза погоды и вообще любых сведений, подтягиваемых из интернета.
Из JSON очень легко извлекать необходимые сведения, а в более сложных случаях можно обрабатывать вывод Invoke-WebRequest.
В комментариях расскажите, какую последнюю задачу вы решали скриптом PowerShell и/или планировщиком заданий!
Михаил Прохоров
Почти два года назад задавал вопрос на форуме http://forum.oszone.net/thread-335719.html :)
Vadim Sterkin
Обещанного три года ждут, так что всё с опережением графика:)
Lecron
Коллега примерно так и делал. Значения координат читал из, а восхода-заката писал в переменные окружения, а вместо выполнения конкретных действий, eventcreate генерировал события восхода-заката.
Не знаю, сложнее в целом получилось или проще, но связность точно меньше и пользовательская часть полностью вынесена в отдельный блок.
Vadim Sterkin
Из чего?
Писать событие в журнал — мысль была, а время в переменные среды — нет. Но я сразу фокусировался на готовом решении — запустил один скрипт, занес свои команды в два других и все работает. В PowerShell, создавать триггер по событию сложно.
Работа под другими учетными записями неудобно масштабируется, это да, но я счел это некритичным для задачи и ЦА. Но в остальном пользовательская часть от системной отделена и управляется легко.
Lecron
читал из, …писал в переменные окружения.
А зачем создавать триггер по готовому событию из PS? Это привычная задача планировщика. Создается ручками в интерфейсе, однократно.
Vadim Sterkin
Я так и не понял, из чего он читал координаты, но ладно.
Да, это так. Но не все осилят это…
Мне не очень понятна его логика обработки событий, а продумывать ее лень, потому что я отбросил этот вариант. Но с тем же успехом можно ручками создать событие в нужной учетной записи и дописать пару строк в скрипт.
Lecron
Из переменных окружения, конечно же.
Наоборот. Код максимальнно отвязан от данных и нет нужды разбираться в скриптовании. Если уж пользователь не сможет создать задачу в планировщике, то закодировать её же в скрипте и подавно.
Это фактически законченное решение, для которого можно сделать инсталятор.
Впрочем, о достоинствах и недостатках можно спорить долго и бессмысленно.
Я сам не настолько в теме, но как понял:
1. install.ext копирует необходимое в нужные папки и создает задачу updateSunPeriod
2. задача updateSunPeriod запускает скрипты
2.1 getSunPeriod.ext читает координаты из переменных окружения, получает данные и пишет их в переменные окружения.
2.2 setSunPeriod.ext -sunrise создает/модифицирует задачу инициирующую событие sunrise
2.3 setSunPeriod.ext -sunset аналогично для события sunset
3. Пользователь создает любые задачи с привязкой к готовым событиям. Получая то, о чем вы сожалели: «Если бы в планировщике уже было некое задание с триггерами на восходе и закате».
Vadim Sterkin
Спасибо за объяснение. Это вообще не проблема. Как я объяснил, задания можно запускать вне зависимости от входа пользователя. Если надо событие, можно дописать по строчке Write-EventLog во вспомогательные скрипты и будут два события с разными номерами. Остальные пользователи могут к ним привязываться.
Lecron
В таком варианте — то что надо. Только не скрипты дополню, а изменю создание задачи в set_tasks. Вспомогательные же скрипты буду запускать по событию, а не по времени. Конечно получится 5 задач планировщика — 3 служебных и 2 пользовательских, но мне так понятнее.
Спасибо.
Игорь-И
Пользуюсь планировщиком с того времени как узнал о нём Вашем блоге.
Применял Ваши скрипты по созданию точки восстановления и по обслуживанию
ССД диска в определённый час и день месяца.
По пятницам превентивно запускается DISM.exe с аргументами /Online /Cleanup-image /RestoreHealth
так как начитался множества советов о том, что решает многие проблемы
запуск DISM.exe /Online /Cleanup-image /RestoreHealth.
В определённые дни каждого месяца запускается Internet Explorer с аргументом в виде адреса сайта
для напоминания о некоторых платежах.
Задержка автозагрузки нескольких программ на определённое время после
входа в систему.
Так как некоторые из этих программ(переводчик, почта, RSS) требовали интернета, стал применять условие
(Запускать только при подключении к любой сети) потому-что сети разные.
После этого проявилась проблема: при кратковременном
пропадании сети или интернета программы, запущенные с таким условием закрывались, и
после восстановления сети не запускались, их приходилось запускать вручную.
Эту задачу решил с помощью события в журнале WLAN-AutoConfig/Operational
и там-же можно установить задержку по времени.
При таком способе запуска появился для меня и ещё один положительный эффект:
автоматический перезапуск этих программ требующих интернета после пропадании сети
сна, гибернации.
Большое спасибо Вам за просветительскую деятельность.
Создано с учётом мини-руководства по стилю технических инструкций.
Vadim Sterkin
Он решает конкретные проблемы, и превентивно запускать это не надо. Проблемы решать надо по факту их возникновения.
В остальном, вы хорошо поставили планировщик себе на службу!
Herz Mein
Интересно было бы посмотреть расчет времени восхода-заката для определенных широты и долготы. Оффлайн всегда надежней.
Lecron
SO говорит что для Python существуют как минимум две библиотеки astral и suntime.
Для Lua на гитхабе модуль lustrous. Там кстати вполне понятная математика.
Vadim Sterkin
Ничто не мешает вам получить эти данные хоть на год вперед (в примере — 5 дней)
См. также примеры работы с Get-Date в Как массово задать дату изменения или создания файлов в PowerShell.
Lecron
Предложенный запрос также показывает необходимость уменьшения связности (и возможности использовать код на других языках). Задача sunrise_sunset_time не учитывает включение при отсутствии интернета. Что на ноуте вещь не сказать чтобы редкая. Значит нужно или добавлять условие на наличие сети и форсировать выполнение после ее появления (что думаю очень и очень геморрой), или хранить большой кеш префетча с поиском по нему (не намного легче), или действительно считать локально.
Хотя может я и преувеличиваю проблему. Достаточно переключить однократный на ежедневный запуск и пусть на следующий день события сработают с небольшой погрешностью, но это лучше чем их отсутствие. Даже за пару дней, в самый пик изменения длительности суток, ошибка не превысит 10 минут, что с учетом направленности окон и окружающего ландшафта, не бог весть какая погрешность. Впрочем, в коде все равно нужно будет реализовать сохранение даты последнего успешного запроса и вывести сообщение, если он был давно. Так может все-таки лучше обеспечить возможность локального запроса? И пусть пользователи делают что хотят.
Herz Mein
Вопрос не в получении данных из онлайн-сервиса, а в их расчете локально. Исходя из долготы, широты и даты. Но это не к вам лично, а вообще. В интернете есть уравнения, но что-то не въезжаю.
Vadim Sterkin
Что-то я здесь много не понял :) О каких языках речь? Если о языке интерфейса / форматах даты, то роли это не играет. Get-Date корректно работает вне зависимости от языка, просто вывод пользователь видит в своем формате.
Если же речь о выводе кода выше, т.е. то что отдает сервис, то в PowerShell 5.1 там UTC
2020-04-10T02:34:23+00:00
2020-04-11T02:31:51+00:00
2020-04-12T02:29:19+00:00
В PS 7.0 вывод в другом формате https://i.imgur.com/JZimzLN.png, но я не вникал, почему это происходит (скрипт запускает 5.1).
Вообще, интернет должен подключаться быстрее, чем вы войдете в систему. Но если проблема существует, я вижу два пути решения.
1. Не добавлять триггеры при входе и по событию пробуждения, т.е. убрать их из скрипта или из GUI планировщика после отработки set_tasks.ps1. Тогда просто будет выполняться триггер по расписанию, а если задание пропущено — при первой возможности. Там как раз задержка около 5 минут, что достаточно для инициализации сети.
Это я разбирал в разделе статьи Запуск в зависимости от выполненного входа.
2. Явно задать задержку триггерам входа и пробуждения. Проще всего это сделать в GUI планировщика. Но если хочется сразу создавать такие задания…
У New-ScheduledTaskTrigger есть несколько странный параметр
-RandomDelay
. То есть если задана 1 минута, он случайным образом выбирает значение от 1 до 60 секунд.Параметра для фиксированной задержки нет, но можно указывать свойство триггера так:
Аналогично для триггера по событию пробуждения просто добавляется
PT1M
— 1 минута. Решение не вполне очевидно, но это стандартный формат схемы планировщика, что я разбирал в рамках статьи об автоматическом обслуживании.А код создания триггера по событию пробуждения изначально демонстрирует, как работают свойства. Да, это сложно, но это был реально единственный аспект, который я гуглил в рамках подготовки материала.
Мое решение работает без всяких записей в переменные или файловую систему. И я не вижу необходимости добавлять эту мороку в подавляющем большинстве случаев.
Если вам надо кастомное что-то под свои условия, пилите какой угодно код :) Чем могу, помогу.
Lecron
Вообще, интернета может не быть вообще. Если с устройством работают в дороге (не дом или родной офис). Задержками этот вопрос не решить. И это не такой уж редкий случай.
Если к sunset-у скорее всего получит данные и взведет затвор, то проворонить sunrise элементарно. Думаю этот случай, как минимум надо описать в примечаниях основной статьи.
Я без претензий. Ваше решение отличный прототип, минимально рабочее решение, демонстрирующее возможности PS. Которые подчас знать важнее, чем детали синтаксиса команд. Много раз сам сталкивался с «а разве так можно было»)))
Vadim Sterkin
В принципе, это первый пункт раздела «Ограничения этого подхода» — доступность сервиса подразумевает наличие подключения к интернету :)
Я думал над тем, чтобы расписать на этот и текущий день, но это усложняло скрипт, добавляло условий… Решил оставить допиливание желающим — хорошая практика, да.
Навскидку, в таком сценарии можно в конце вспомогательного скрипта sunset обновлять задания с завтрашней датой, т.е. это даст следующий день. Если совсем в лоб, то добавить переменную $tomorrow и еще раз прогнать с ней блок получения данных и обновления времени запуска вспомогательных заданий уже с ней.
Если пытаться чуть элегантнее, то пример получения нескольких дней с DO-WHILE я показал в комментариях, равно как AddDays.
Mikhail Lyalin
А можно примеры/ссылки на эти скрипты?
Vadim Sterkin
SSD обслуживать не надо, а то можно дообслуживаться. Точки восстановления конечно же тут: Автоматизация включения защиты, ее настройки и создания точек
Herz Mein
В общем универсальней самому менять цветовую тему, когда захочешь. Во-первых не всегда может быть интернет, во-вторых не всегда геолокация соответствует исходным данным. Небольшая переключалка. При каждом вводе меняется цветовая схема:
Vadim Sterkin
В статье смена цветов для примера. А так, вместо переключалки можно просто задания запускать
Алексей Каманин
Я решил немного развлечься и нацарапал кривенький скриптец, который берёт с Bing ежедневную картинку и ставит её фоном рабочего стола.
Vadim Sterkin
Зачет! В принципе, для этого есть Dynamic Theme https://www.microsoft.com/en-us/p/dynamic-theme/9nblggh1zbkw Но скриптом ок.
Кстати, а зачем
Import-Module BitsTransfer
? Разве этого недостаточно?Ну или Set-Content, как я показывал в связанной статье.
Алексей Каманин
Ну это больше как демонстрация возможностей PowerShell.
Да и про Dynamic Theme не знал.
BitsTransfer просто круче ;)
Herz Mein
Ну вообще-то есть System.Net.Webclient. Пример скрипта для загрузки файлов с прогрессом:
Вызывать:
Файл сохраняется в текущей директории.
Vadim Sterkin
Теперь и Bing Wallpaper https://www.microsoft.com/bing/bing-wallpaper
Андрей Кузнецов
Здравствуйте, Вадим! Большое спасибо за ваш блог. Сам подумываю писать о чем-то подобном. Являюсь поклонником автоматизации и оптимизации рутинных процессов, поэтому ваша тема мне очень близка.
А теперь ближе к делу. Скажите, вы когда-нибудь задумывались о том, чтобы реализовать такой функционал: отключать монитор в Windows после отключения его кнопкой. Винда почему-то по-прежнему видит отключенный монитор, пока из ноутбука не выдернешь кабель, то есть мышь по прежнему двигается за пределы рабочего стола так, словно монитор активен. А вот в MacOS тот же моник переставал видеться именно после выключения кнопкой.
При этом, ЖК телевизор в винде отключается как надо — нажимаешь кнопку и всё, больше нельзя «залезть» мышью за край рабочего стола.
Гуглил на эту тему, но ничего не нашел.
P.S. А как книгу по ускорению Windows получить? Уже подписался, но книга не дошла.
Vadim Sterkin
Андрей, спасибо, что читаете мой блог. Книга дошла — прочтите приветственное письмо. Если этого недостаточно, пишите в личку — Telegram или почту.
С монитором я не понял — то ли хотелка, то ли проблема. Если первое, пишите в чат @winsiders, если второе — см. там же приветственное сообщение.
Андрей Кузнецов
Спасибо. Книгу правда не разглядел, теперь нашел. Еще раз благодарю.
Владимир
Здравствуйте Вадим!
ПОМОГИТЕ ПОЖАЛУЙСТА!
У меня Windows 10. Выполнил Ваши рекомендации по установке sunrise — sunset. Скрипты сработали. Хотел посмотреть задания в планировщике – планировщик не открывается. Проверил целостность системы и получил, что какие-то файлы повреждены, и система не может устранить ошибку самостоятельно. Возможно что причина вовсе не из-за выполнения скриптов. Я ведь до их выполнения планировщик не открывал.
Vadim Sterkin
Владимир, проблема никак не связана со скриптами. Пишите в http://forum.oszone.net