У нас есть возможность в 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 к SQL серверу
Проигрывание аудио по событию в системе в 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.
...
Подписывайтесь на наш Telegram канал
Теги: #powershell