[решено] Событие и код перехода на питание от батареи
Здравствуйте! Есть одна задумка. Хочу создать определённые задания в планировщике задач, которые бы запускались при переходе на питание от батареи. Не могу определить тригер для этого. То есть запуск задачи при событии, а вот журнал, источник и код события не могу найти. Бродил на TechNet, но ничего подходящего не смог найти. Может быть есть какой-то альтернативный вариант, то есть запуск задания по какому-то другому условию, которое в свою очередь всегда выполняется системой при переходе на питание от батареи?
|
Говорят, что Windows не пишет в журнал событие подключения/отключения питания, предлагают писать его при помощи PS:
Код:
New-EventLog -Source BatteryStatusMonitor -LogName Application
Function OnBatteryStatusChange ($NewStatus) {
If ($NewStatus -eq 1) {
$EventID = 5001
$Message = "The computer was unplugged."
} ElseIf ($NewStatus -eq 2) {
$EventID = 5002
$Message = "The computer was plugged in."
} Else {
$EventID = 5000
$Message = "Battery status changed to $NewStatus"
}
Write-EventLog -LogName Application -Source BatteryStatusMonitor -EventID $EventID -Message $Message
}
$Query = "select * from __instancemodificationevent within 3 where targetinstance isa 'win32_battery' and targetinstance.batterystatus <> previousinstance.batterystatus"
Register-WmiEvent -Query $Query -Action {OnBatteryStatusChange $Event.SourceEventArgs.NewEvent.TargetInstance.BatteryStatus} -SourceIdentifier "BatteryStatusChange"
For (;;) {}
Если получится записывать в журнал состояние отключения питания от сети, сможете и триггер по событию из журнала настроить, в данном примере по событию с кодом 5001.
Источник: http://superuser.com/a/389853
|
а как с помощью этого скрипта добавить журналирование?
|
n_i_x, сохранить его как .ps1 и запустить, полагаю. Для ежедневного использования поместить в автозапуск или лучше в планировщик. Потом смотрите события в журнале Приложение - найдите событие с кодом 5001 и источником BatteryStatusMonitor - по правой кнопке мыши на нем - Привязать задачу к событию...
На GitHub есть другой скрипт, который основан на этом: Get and Log Battery and Power Levels using Powershell
Правда он развесистый и мониторит не только подключение/отключение, при желании можете его отредактировать под себя, благо он с комментариями.
Попробуйте, расскажите как и что :)
Код:
#Battery Monitor Script 0.2
# based on http://www.rivnet.ro/2010/05/log-battery-and-power-levels-using-powershell.html
#-------------------------------
# You can modify the following settings to fit your needs
# Check interval to detect power changes
$checkInterval = 1
# Log interval in seconds when on battery power.
$batteryLogInterval = 60
# Log interval in seconds when on AC power.
$acLogInterval = 3600
# Log warning instead of info if battery power below given percentage
$batteryLogWarn = 15
#-------------------------------
#create custom event-log if it doesn't exist already
$condition = ((get-wmiobject -class "Win32_NTEventlogFile" | where {$_.LogFileName -like 'BatteryMonitor'} | measure-object ).count -eq '0')
if($condition) {
'create event log'
New-EventLog -Source BattMon -LogName BatteryMonitor
}
#signal script execution start
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 0 -Message 'Starting new Execution of BatteryCharge Monitor Script' -EntryType Information -ComputerName $env:computername -ErrorAction:SilentlyContinue
$prevBatteryStatus = 2
$prevLogTime = 0
do {
#clear any previous values
$PowstatMsg = $null
$ChargeRemMsg = $null
$ChargeRem = $null
$RemTimeMsg = $null
#create a Message object that we can add values to
$Message = ''
$Message = $Message | select-object *,PowStatMsg,ChargeRemMsg,RemTimeMsg
$batt = Get-WmiObject -Class Win32_Battery
#1 means on battery, 2 on ac power
If ($batt.BatteryStatus -like '1') {
$Message.PowstatMsg = 'On_Battery'
'PowerStatus: On_Battery' }
elseif ($batt.BatteryStatus -like '2') {
$Message.PowstatMsg = 'AC_Power'
'PowerStatus: AC_Power' }
#If charge is larger than 100, it means it is full/on ac power
if ($batt.EstimatedChargeRemaining -lt '100') {
'EstimatedChargeRemaining: ' + $batt.EstimatedChargeRemaining + '%'
$Message.ChargeRemMsg = "{0:P0}" -f ($batt.EstimatedChargeRemaining/100)
$ChargeRem = $batt.EstimatedChargeRemaining
} else {
'EstimatedChargeRemaining: 100%'
$Message.ChargeRemMsg = "{0:P0}" -f 1
$ChargeRem = 100
}
#If estimated minutes is an absurdly high value, it means we are on AC power
if ($batt.EstimatedRUntime -lt '9999') {
'EstimatedRunTime: ' + $batt.EstimatedRunTime + 'min'
$Message.RemTimeMsg = $batt.EstimatedRunTime }
else {
$Message.RemTimeMsg = 'N/A' }
If ($batt.BatteryStatus -ne $prevBatteryStatus) {
if ($prevBatteryStatus -like '2') {
$EventMsg = "Switched to Battery Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
} else {
$EventMsg = "Switched back to AC Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
}
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 10 -Message $EventMsg -EntryType Warning -ComputerName $env:computername -ErrorAction:SilentlyContinue
$prevLogTime = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
}
$prevBatteryStatus = $batt.BatteryStatus
$currLogTime = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
$diff = $currLogTime.TotalSeconds - $prevLogTime.TotalSeconds
if ($prevBatteryStatus -like '2') {
#AC Power
if ($diff -ge $acLogInterval) {
$EventMsg = "$($Message.PowStatMsg), $($Message.ChargeRemMsg), $($Message.RemTimeMsg)"
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 100 -Message $EventMsg -EntryType Information -ComputerName $env:computername -ErrorAction:SilentlyContinue
$prevLogTime = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
}
} elseif ($prevBatteryStatus -like '1') {
# Battery power
if ($diff -ge $batteryLogInterval) {
$EventMsg = "$($Message.PowStatMsg), $($Message.ChargeRemMsg), $($Message.RemTimeMsg)"
if ($ChargeRem -le $batteryLogWarn) {
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 200 -Message $EventMsg -EntryType Warning -ComputerName $env:computername -ErrorAction:SilentlyContinue
} else {
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 200 -Message $EventMsg -EntryType Information -ComputerName $env:computername -ErrorAction:SilentlyContinue
}
$prevLogTime = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
}
}
Sleep $checkInterval
}
while (1)
|
первый скрипт запустился, и работал нормально до перезагрузки, после не работает, так как не может зарегистрировать себя в журнале, ругается на то, что такое уже существует. второй работает, но слегка чудит с логами)
если выдернуть шнур то кидает сообщение, о том что переключено питание на батарею, если воткнуть шнур обратно, то выдаёт что переключен на питание от батареи или на питание от сети, всегда по разному, но номер события один и тот же 10))
|
Цитата:
Цитата Blast
Если получится записывать в журнал состояние отключения питания от сети, сможете и триггер по событию из журнала настроить, »
|
Тут, наверное, и писать в журнал не обязательно, а можно сразу в том же скрипте:
Цитата:
Цитата n_i_x
определённые задания … которые бы запускались при переходе на питание от батареи. »
|
|
Цитата:
Цитата n_i_x
работал нормально до перезагрузки, после не работает, так как не может зарегистрировать себя в журнале, ругается на то, что такое уже существует »
|
Он не ругается, а сообщает :) Но продолжает отслеживать и помещать события в журнал. Если хотите, можете просто удалить первую строку из скрипта. Вы же запуск правильно делаете?
Код:
powershell -file <путь к файлу>\имя_файла.ps1
Если путь с кириллицей или пробелами, то в кавычки.
Цитата:
Цитата n_i_x
второй работает, но слегка чудит »
|
Ну да, там же каждую секунду отслеживается куча всего, что вам не нужно, надо править под себя, но... оно вам не надо.
Цитата:
Цитата Iska
Тут, наверное, и писать в журнал не обязательно »
|
Здраво, так наверное проще даже.
|
да запускаю именно так.
а во втором 2 одинаковых кода на разные события
Код:
If ($batt.BatteryStatus -ne $prevBatteryStatus) {
if ($prevBatteryStatus -like '2') {
$EventMsg = "Switched to Battery Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
} else {
$EventMsg = "Switched back to AC Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
}
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 10 -Message $EventMsg -EntryType Warning -ComputerName $env:computername -ErrorAction:SilentlyContinue
стоит ли удалять второе сообщение?
|
Добавьте проверку по примеру второго
Код:
$condition = ((get-wmiobject -class "Win32_NTEventlogFile" | where {$_.LogFileName -like 'Application'} | measure-object ).count -eq '0')
if($condition) {
'create event log'
New-EventLog -Source BatteryStatusMonitor -LogName Application
}
Function OnBatteryStatusChange ($NewStatus) {
If ($NewStatus -eq 1) {
$EventID = 5001
$Message = "The computer was unplugged."
} ElseIf ($NewStatus -eq 2) {
$EventID = 5002
$Message = "The computer was plugged in."
} Else {
$EventID = 5000
$Message = "Battery status changed to $NewStatus"
}
Write-EventLog -LogName Application -Source BatteryStatusMonitor -EventID $EventID -Message $Message
}
$Query = "select * from __instancemodificationevent within 3 where targetinstance isa 'win32_battery' and targetinstance.batterystatus <> previousinstance.batterystatus"
Register-WmiEvent -Query $Query -Action {OnBatteryStatusChange $Event.SourceEventArgs.NewEvent.TargetInstance.BatteryStatus} -SourceIdentifier "BatteryStatusChange"
For (;;) {}
.
Цитата:
Цитата n_i_x
а во втором 2 одинаковых кода на разные события »
|
А второй мне лень смотреть :) коды - да, события - нет.
Первый я проверял, все нормально работает, в том числе и через планировщик скрывая окно PS. События регистрируются, поставленная вами задача выполняется, что еще надо? :)
|
1 вариант простой и более подходящий, но когда этот скрипт активен, то нагрузка на систему возрастает сильно, аж вентилятор сильней крутится начинает)
остановился на 2 варианте, пытаюсь в нём разобраться сейчас, как разделить сообщение с одинаковыми кодами, но разными событиями
|
Цитата:
Цитата n_i_x
как разделить сообщение с одинаковыми кодами, но разными событиями »
|
Зачем? Сделайте разные коды (та часть, которую вы приводили выше):
Код:
If ($batt.BatteryStatus -ne $prevBatteryStatus) {
if ($prevBatteryStatus -like '2') {
$EventID = 10
$EventMsg = "Switched to Battery Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
} else {
$EventID = 11
$EventMsg = "Switched back to AC Power! $($Message.ChargeRemMsg), Minutes: $($Message.RemTimeMsg)"
}
Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID $EventID -Message $EventMsg -EntryType Warning -ComputerName $env:computername -ErrorAction:SilentlyContinue
|
Вложений: 2
А в принципе, по первоначальной постановке вопроса я понял, что вам вам не нужно ежесекундный отчет в консоли, запись в журнал событий о запуске скрипта, о низком заряде батареи и т.д. Вам ведь нужно только, чтобы в журнал записывалось событие при отключении от сети и переход на питание от батареи? Если так, то скрипт можно существенно сократить - batterylog_0.zip
А если целью был просто запуск приложения при переходе на питание от батареи, то берите batterylog_1.zip и поправьте в нем путь к запуску программы в строке 12. Если программу нужно запускать с параметрами, то параметры указывайте за кавычками. Вместо C:\Program Files\ можете использовать переменную $env:ProgramFiles
Скрипт спокойно запускается из планировщика и при соответствующей настройке задачи не показывает свое окно.
|
Блин! Огромное человеческое спасибо!!!!!
Изначально у меня была задумка, что бы при переходе на питание от батареи, автоматически менялась тема оформления с заставки на чёрный фон, закрытие определённых приложений и тому подобное, а при переходе на питание от электросети возвращалось всё обратно. Всё подготовил для этого, но вот с событиями батареи запнулся)
|
В таком случае можно опять же обойтись без записей в журналы событий (незачем их загаживать чем попало).
Примерно так (требуется проверка, спешил, мог напортачить):
Код:
$checkInterval = 1
$prevBatteryStatus = 2
$prevLogTime = 0
do {
$batt = Get-WmiObject -Class Win32_Battery
If ($batt.BatteryStatus -ne $prevBatteryStatus) {
if ($prevBatteryStatus -like '2') {
& "<путь к батнику, который меняет настройки при работе от батареи>"
} else {
& "<путь к батнику, который меняет настройки при работе от сети>"
}
}
$prevBatteryStatus = $batt.BatteryStatus
$currLogTime = New-TimeSpan "01 January 1970 00:00:00" $(Get-Date)
$diff = $currLogTime.TotalSeconds - $prevLogTime.TotalSeconds
Sleep $checkInterval
}
while (1)
|
bonderlogin |
05-12-2015 12:40 2581658 |
Здравствуйте. Последний скрипт хорош, и мне подходит для одной из задач. Но я так понял, что он не просто проверяет состояние питания, а сравнивает его с предыдущим, работая циклически? А для второй моей задачи нужно просто единоразово запустить подобный скрипт, чтобы он, в свою очередь, выполнил действия в зависимости от типа питания (как и в предыдущем примере) и завершился. Как его отредактировать для этих целей?
|
Время: 05:37.
© OSzone.net 2001-