Как через Powershell проиграть аудио по событию в системе


17 августа 2019


Как через Powershell проиграть аудио по событию в системе

У нас есть возможность в Powershell проиграть аудио и при этом привязать его к какому-то событию в системе. Мы можем проиграть wav и mp3, но для каждого формата будет разный подход.

В первом варианте, через SoundPlayer, будет проигрываться только WAV формат и определенного метода кодирования. Проигрывание будет идти до завершения трека либо закрытию окна, либо выполнения команды $obj.Stop():

#путь до файла
$path = "C:\sound.wav"
#проигрывание трека
$obj = New-Object Media.SoundPlayer $path
$obj.Play()
$obj.Stop()

Так же отмечу, что не все wav форматы подходят. Один из треков, который я изначально скачал в формате WAV выдал ошибку:

Исключение при вызове "Play" с "0" аргументами: "Файл в папке C:\alarm.wav не является волновым файлом."

Особо не разбираясь я нашел mp3 трек и сконвертировал в wav, что исправило ошибку.

Второй вариант немного посложнее, через Media.MediaPlayer, но с ним можно проигрывать mp3:

#Путь до mp3 файла
$path = "C:\sound.mp3"
Add-Type -AssemblyName presentationCore
 $filepath = [uri] $path
 $winplayer = New-Object System.Windows.Media.MediaPlayer
 $winplayer.Open($filepath)
# Время нужное для загрузки файла, без этого может не сработать
 Start-Sleep 2 
 $duration = $winplayer.NaturalDuration.TimeSpan.TotalSeconds
 $winplayer.Play()
 Start-Sleep $duration
 $winplayer.Stop()
 $winplayer.Close()

На Windows Sever 2019 с этим скриптом была ошибка, которую я устранил первым запуском Media Player с рекомендуемыми настройками.

 

Проигрывание аудио по событию в системе в Powershell

Теперь, когда мы разобрались в проигрывании файлов можно определить само событие. Я планирую мониторить любую ошибку в журналах System и, если она произойдет, должен будет проиграться файл. Сам скрипт будет запускаться в планировщике задач, но можно использовать и цикл со Start-Sleep, например, в 30 секунд.

Сами события, которые являются отчетом об ошибке, можно получить так:

Get-WinEvent -FilterHashtable @{ LogName='Security'; Level=2;}

Так как в планировщике скрипт будет запускаться каждые 30 минут у меня нет необходимости получать логи за все время. Для того что бы получать данные только за последние пол часа я объявляю переменную с этим временем и передаю ее в hashtable:

$date = (Get-Date).AddMinutes(-30)
Get-WinEvent -FilterHashtable @{ LogName='System'; StartTime=$date; Level=2;}

Если нет ни одного события, то у нас будет появляться ошибка. Мы можем поставить ключ -ErrorAction SilentlyContinue для избежания каких-то уведомлений об ошибках, но сама ошибка не мешает процессу. Саму возможность проигрывания аудио файла я объявил в функцию Make-Audio:


function Play-Audio {
	$path = "C:\sound.mp3"
	Add-Type -AssemblyName presentationCore
	 $filepath = [uri] $path
	 $winplayer = New-Object System.Windows.Media.MediaPlayer
	 $winplayer.Open($filepath)
	 Start-Sleep 2 
	 $duration = $winplayer.NaturalDuration.TimeSpan.TotalSeconds
	 $winplayer.Play()
	 Start-Sleep $duration
	 $winplayer.Stop()
	 $winplayer.Close()}

$date = (Get-Date).AddMinutes(-30)
$result = Get-WinEvent -FilterHashtable @{ LogName='System'; StartTime=$date; Level=2;}
if ($result) {Play-Audio}

Конечно можно сделать и лучше, приведен только пример реализации. Кстати у Get-WinEvent есть возможность получения событий удаленно с помощью ключа -ComputerName.

...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.