переадресациия при блокировке рабочего стола
номера IPPhone сотрудника и мобилы берутся из ActiveDirectory - актуально только для для компьютеров под Vista, WIndows7, 2008, 2008R2/
при блокировке рабочего стола выполняется скрип на PowerShell который пишет в базу данных MSSQL , а на каком-нибудь сервере каждую минуту выполняется скрипт который берет статусы переадресации из базы MSSQL обращается по телнету к астеру через интерфейс AMI и добавляет запись
типа /CF/XXX : YYYYYYYYYY (XXX номер сотрудника YYY номер мобилы)
В конце будут параметры БД MSSQL (одна таблица три столбца)
выполнение всех скриптов осуществляется через планировщик заданий - задание можно через ГПО распространить на все компы (Computer configuration / preferences / control panel settings / scheduled task) параметры запуска в самом низу поста
также через ГПО нужно в политике компьютера включить выполнение скриптов Powerahell с любых источников (computer configuration / policies / administrative templates / windows componets / windows PowerShell - alow all scripts)
и так
Клиентский скрипт
#параметр можно задать значение после пути к скрипту (\\блабла\блаблабла\Скрипт.ps1 0) задали параметр 0 - по умолчанию 1
param(
#Присвоение параметру значения по умолчанию
[INT]$statredirect = '1'
)
#функции выполнения команды на запись и обновление значений в БД MSSQL
function sql{
param($sql)
#адрес вашего SQL сервера
$sqlservername = "QAZWSX\mssqlGGGG"
$sqlConnection = new-object System.Data.SqlClient.SqlConnection
# имя базы данных на сервере Database=asterisk
$sqlConnection.ConnectionString = "Server=$sqlservername;Database=asterisk;Integrated Security=SSPI"
$sqlConnection.Open()
$sqlCommand = new-object System.Data.SqlClient.SqlCommand
$sqlCommand.CommandTimeout = 120
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandText= $sql
$result = $sqlCommand.ExecuteNonQuery()
$sqlConnection.Close()
}
#Функция получения данных с SQL сервера
function getsql{
param($sql1)
$SQLSrv = 'addssec\mssqladdssec'
$SQLCon = New-Object System.Data.SQLClient.SQLConnection
$SQLCon.ConnectionString ="Data Source=$SQLSrv;Database=asterisk;Integrated Security=SSPI"
$SQLCon.Open()
$Query = $sql1
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLCon)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet) | Out-Null;
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$DataTable.DefaultView
$SQLCon.Close()
}
#Присвоение переменной логина пользователя запустившего процесс explorer.exe
$gpro = Get-WmiObject win32_process -Filter "name='explorer.exe'"
$username = $gpro.GetOwner().user
$statusexistence = "0"
$statusexistence1 = "1"
#получение информации о наличии пользователя в БД
$statusexistence = getsql "select username from userredirectcall Where username = '$username'"
$statusexistence1 = $statusexistence | select -ExpandProperty username
#Цикл который в зависимости от существования пользователя в БД создает или обновляет значение статуса переадресации
if ($statusexistence1 -gt 0)
{
$functionstrting2 = "Update userredirectcall set statusredirect = '$statredirect' , datelastmod = GETDATE() Where username = '$username';"
$TDTSS2 = sql $functionstrting2
}
else
{
$functionstrting1 = "insert into userredirectcall values('$username',0,GETDATE());"
$TDTSS = sql $functionstrting1
}
param(
#Присвоение параметру значения по умолчанию
[INT]$statredirect = '1'
)
#функции выполнения команды на запись и обновление значений в БД MSSQL
function sql{
param($sql)
#адрес вашего SQL сервера
$sqlservername = "QAZWSX\mssqlGGGG"
$sqlConnection = new-object System.Data.SqlClient.SqlConnection
# имя базы данных на сервере Database=asterisk
$sqlConnection.ConnectionString = "Server=$sqlservername;Database=asterisk;Integrated Security=SSPI"
$sqlConnection.Open()
$sqlCommand = new-object System.Data.SqlClient.SqlCommand
$sqlCommand.CommandTimeout = 120
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandText= $sql
$result = $sqlCommand.ExecuteNonQuery()
$sqlConnection.Close()
}
#Функция получения данных с SQL сервера
function getsql{
param($sql1)
$SQLSrv = 'addssec\mssqladdssec'
$SQLCon = New-Object System.Data.SQLClient.SQLConnection
$SQLCon.ConnectionString ="Data Source=$SQLSrv;Database=asterisk;Integrated Security=SSPI"
$SQLCon.Open()
$Query = $sql1
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLCon)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet) | Out-Null;
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$DataTable.DefaultView
$SQLCon.Close()
}
#Присвоение переменной логина пользователя запустившего процесс explorer.exe
$gpro = Get-WmiObject win32_process -Filter "name='explorer.exe'"
$username = $gpro.GetOwner().user
$statusexistence = "0"
$statusexistence1 = "1"
#получение информации о наличии пользователя в БД
$statusexistence = getsql "select username from userredirectcall Where username = '$username'"
$statusexistence1 = $statusexistence | select -ExpandProperty username
#Цикл который в зависимости от существования пользователя в БД создает или обновляет значение статуса переадресации
if ($statusexistence1 -gt 0)
{
$functionstrting2 = "Update userredirectcall set statusredirect = '$statredirect' , datelastmod = GETDATE() Where username = '$username';"
$TDTSS2 = sql $functionstrting2
}
else
{
$functionstrting1 = "insert into userredirectcall values('$username',0,GETDATE());"
$TDTSS = sql $functionstrting1
}
Скрипт на сервере - Сервер должен быть контроллером домена
#Импорт командлетов для activedirectory
Import-Module activedirectory
#Функция получения данных с SQL сервера
function getsql{
param($sql1)
$SQLSrv = 'addssec\mssqladdssec'
$SQLCon = New-Object System.Data.SQLClient.SQLConnection
$SQLCon.ConnectionString ="Data Source=$SQLSrv;Database=asterisk;Integrated Security=SSPI"
$SQLCon.Open()
$Query = $sql1
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLCon)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet) | Out-Null;
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$DataTable.DefaultView
$SQLCon.Close()
}
#Функция старта обращения к Asterisk по AMI
Function Start-TcpClient([String]$remote_ip, [Int]$remote_port)
{
if (!$remote_ip -or !$remote_port)
{
throw "Remote IP and Remote Port are mandatory!"
}
$private:tcpcli = New-Object System.Net.Sockets.TcpClient($remote_ip,$remote_port)
if ($tcpcli)
{
$tcpcli.ReceiveTimeout = 10000;
}
return $tcpcli
}
#Функция завершения обращения к Asterisk по AMI
Function Stop-TcpClient([System.Net.Sockets.TcpClient]$tcpcli)
{
if (!$tcpcli)
{
throw "Nothing to close!"
}
$tcpcli.Close()
}
#Функция Записи в Asterisk по AMI
Function Write-TcpClient([System.Net.Sockets.TcpClient]$tcpcli, [String]$str="", [Bool]$eol=$true)
{
if (!$tcpcli)
{
throw "Can't write to NULL!"
}
if ($eol) { $str+="`r`n" }
$private:enc = New-Object System.Text.AsciiEncoding
$private:strm = $tcpcli.GetStream()
$private:buff = $enc.GetBytes($str)
$strm.Write($buff,0,$buff.Length)
}
#Функция Чтения из Asterisk по AMI
Function Read-TcpClient([System.Net.Sockets.TcpClient]$tcpcli, [Bool]$trim=$true)
{
if (!$tcpcli)
{
throw "Can't read from NULL!"
}
$private:enc = New-Object System.Text.AsciiEncoding
$private:strm = $tcpcli.GetStream()
$private:buff = New-Object System.Byte[] 1024
$private:cnt = $strm.Read($buff,0,1024)
if ($cnt)
{
$private:str = $enc.GetString($buff,0,$cnt)
if ($trim) { $str = $str.Trim() }
return $str
}
return ""
}
#Функция добавления переадресации
function add-redirect($addipphone, $addmobilephone)
{
if (($addipphone -gt 0) -and ($addmobilephone -gt 0))
{
$addphoneaction = "Action: dbput`r`nFamily: CF`r`nKey: $addipphone`r`nVal: $addmobilephone`r`n"
#адрес и порт интерфейса AMI
$sock = Start-TcpClient "192.168.128.22" 5038
if ($sock)
{
$response = Read-TcpClient $sock
#XXXXX это логин AMI YYYYY пароль
Write-TcpClient $sock "Action: login`r`nUsername: XXXXX`r`nSecret: YYYYY`r`nEvents: off`r`n"
$response = Read-TcpClient $sock
if ($sock)
{
Write-TcpClient $sock $addphoneaction
$response = Read-TcpClient $sock
}
if ($sock)
{
Write-TcpClient $sock "Action: logoff`r`n"
$response = Read-TcpClient $sock
}
if ($sock)
{
Stop-TcpClient $sock
}
}
}
}
#Функция Удаления переадресации
function del-redirect($delipphone)
{
if ($delipphone -gt 0)
{
$delphoneaction = "Action: dbdel`r`nFamily: CF`r`nKey: $delipphone`r`n"
#адрес и порт интерфейса AMI
$sock = Start-TcpClient "192.168.128.22" 5038
if ($sock)
{
$response = Read-TcpClient $sock
Write-TcpClient $sock "Action: login`r`nUsername: Forward`r`nSecret: TfyenczJFcafkmn`r`nEvents: off`r`n"
$response = Read-TcpClient $sock
if ($sock)
{
Write-TcpClient $sock $delphoneaction
$response = Read-TcpClient $sock
}
if ($sock)
{
Write-TcpClient $sock "Action: logoff`r`n"
$response = Read-TcpClient $sock
}
if ($sock)
{
Stop-TcpClient $sock
}
}
}
}
#Массив пользователей для включения переадресации
$arradd = getsql "select username from userredirectcall Where statusredirect = '1';"
#Массив пользователей для отключения переадресации
$arrdel = getsql "select username from userredirectcall Where statusredirect = '0';"
#текущая дата
$date = get-date
#текущая дата минус две минуты
$dateMin2 = $date.AddMinutes(-2)
#Цикл перебора пользователей на включение переадресации
foreach ($arad in $arradd | % {$_.username})
{
#проверка на существование пользователя
if ($arad -gt 0)
{
$aradt = $arad.Trim()
#выборка даты изменения статуса пользователя
$usrdate = getsql "select datelastmod from userredirectcall Where username = '$aradt';"
$tt1 = $ipphone
$tt2 = $mobilephone
#Выборка из БД внутреннего номера и мобилы
$ipphone = Get-ADUser -Identity $aradt -Properties ipphone | select -Property ipphone | select -ExpandProperty ipphone
$mobilephone = Get-ADUser -Identity $aradt -Properties mobilephone | select -Property mobilephone | select -ExpandProperty mobilephone
#цикл проверки наличия мобилы и внутреннего номера у пользователя и обнуления значений если нет одного из них
if (($tt1 -eq $ipphone) -or ($tt2 -eq $mobilephone))
{
$ipphone = 0
$mobilephone = 0
}
#Цикл сравнения даты изменения записи в MSSQL базе от текущего времени в случае если оно больше чем текущее минус две минуты
if (($usrdate | % {$_.datelastmod}) -gt $datemin2)
{
add-redirect $ipphone $mobilephone
$ipphone
$mobilephone
}
}
}
#Цикл перебора пользователей на выключение переадресации
foreach ($ardl in $arrdel | % {$_.username})
{
#$aradl = $ardl.Trim()
if ($ardl -gt 0)
{
$aradl = $ardl.Trim()
$usrdate1 = getsql "select datelastmod from userredirectcall Where username = '$aradl';"
$tt3 = $dlipphone
$dlipphone = Get-ADUser -Identity $aradl -Properties ipphone | select -Property ipphone | select -ExpandProperty ipphone
if ($tt3 -eq $dlipphone)
{
$dlipphone = 0
}
if ( ($usrdate1 | % {$_.datelastmod}) -gt $datemin2)
{
del-redirect $dlipphone
$dlipphone
}
}
}
пример диалплана на переадресацию с учетом времени дней недели
[office-sip]
exten => _7XX,1,Set(CALLERID(all)=${CALLERID(num)})
exten => _7XX,n,Set(cff=${DB(CF/${EXTEN})})
exten => _7XX,n,GotoIf( $[ "${cff}" = ""} ]?nosett:sett)
exten => _7XX,n(sett),GotoIfTime(18:00-8:00,*,*,*?office-sip,${EXTEN},force)
exten => _7XX,n,GotoIfTime(*,sat-sun,*,*?office-sip,${EXTEN},noring)
exten => _7XX,n,Dial(SIP/${EXTEN},10)
exten => _7XX,n,Goto(out783,${cff},1)
exten => _7XX,n(force),GotoIfTime(*,sat-sun,*,*?office-sip,${EXTEN},noring)
exten => _7XX,n,Dial(SIP/${EXTEN},5)
exten => _7XX,n(noring),Goto(out783,${cff},1)
exten => _7XX,n(nosett),NoOP(${CALLERID(all)})
exten => _7XX,n,Dial(SIP/${EXTEN})
Параметры задания планировщика задания
выбрать тип Scheduled Task windows vista and leter
запуск от админа домена - Run whether user is logged on or not
галку Run with Highest privileges
Configure for windows 7 или vista в зависимости от клиентской ОС
тригеры - ноукоментс
action start-program
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe
####-ваш путь к скрипту и параметр или без праметра в зависимости от включения или выключения переадресации
–NonInteractive –command \\Server\Scripts\sql.ps1 0
%systemroot%\System32\WindowsPowerShell\v1.0
База на MSSQL
название Asterisk админа домена в дбо овнеры
таблица userredirectcall
толбцы параметры
первый столбец - параметры для него - Primary Key имя username тип Char20
второй statusredirect тип int
третий datelastmod тип datetime
Включение AMI
добавить в /etc/asterisk/manager.conf
XXXX логин
YYYY пароль
и можно указать с каких хостов запрещено с каких разрешено заходить
тут указан IP сервера на котором выполняется PowerShell скрипт
[XXXX]
secret=YYYY
deny=0.0.0.0/0.0.0.0
permit=192.168.1.4/255.255.255.255
read=system,call,log,verbose,command,agent,user
write=system,call,log,verbose,command,agent,user
также прикладываю пару скриптов которые в независмости от даты изменения записи в БД MSSQL добавляют или удаляют всем записи на сервере.
Последний раз редактировалось: morgoved (Ср Мар 30, 2011 08:18)
Только стоит ли ТАК ухищряться? Может просто сделать вызов с длительностью 10 сек и в случае неответа либо гнать на другой либо на голосовую почту.
_________________
P4 3.0 + 1Gb CentOS 5.8 Aster 1.8.16
Не люблю gui-сборки: натуральный продукт вкуснее.
И еще: я ПРОФИ так как НЕ ЛЕНЮСЬ читать литературу.