Скрипт об истечении пароля.

Import-Module ActiveDirectory

#System globalization
#$ci = New-Object System.Globalization.CultureInfo(«ru-RU»)

#SMTP server name
$smtpServer = «mail.crt-service.local»

#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
#Creating a Mail object for report
$msgr = new-object Net.Mail.MailMessage

#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)

#E-mail structure
Function EmailStructure($to,$expiryDate,$upn)
{
$msg.IsBodyHtml = $true
$msg.From = «it@maykor.com»
$msg.To.Clear()
$msg.To.Add($to)
$msg.Subject = «Срок дейстия пароля заканчивается»
$msg.Body =»<html><body><font face=’Arial’>Это автоматическое уведомление от ИТ департамента.<br><br><b>Пароль на вашу учетную запись <i><u>crt-service\$upn</u></i> истекает $expiryDate.</b><br><br>Пожайлуйста, измените свой пароль, или после указанной даты Ваш доступ к информационным системам компании будет ограничен.</font></body></html>»
}

Function EmailStructureReport($to)
{
$msgr.IsBodyHtml = $true
$msgr.From = «it@maykor.com»
$msgr.To.Add($to)
$msgr.Subject = «Отчет о блокирумых учетных записях»
$msgr.Body = «<html><body><font face=’Arial’><b>Отчет о блокирумых учетных записях<br><br>Скрипт успешно отработал.<br>$NotificationCounter пользователя получили уведомления:<br><br>$ListOfAccounts<br><br>$NotificationCounterExp пользователя просрочено:<br><br>$ListOfAccountsExp<br><br></b></font></body></html>»
}

#Set the target OU that will be searched for user accounts!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$OU = «OU=TestPass,OU=!Maykor,OU=Office,DC=crt-service,DC=local»

$ADAccounts = Get-ADUser -LDAPFilter «(objectClass=user)» -searchbase $OU -server srv-dc06 -properties PasswordExpired, PasswordNeverExpires, PasswordLastSet, EmailAddress, Enabled | Where-object {$_.Enabled -eq $true -and $_.PasswordNeverExpires -eq $false}
$NotificationCounter = 0
$NotificationCounterExp = 0
$ListOfAccounts = «»
$ListOfAccountsExp = «»
Foreach ($ADAccount in $ADAccounts)
{
$accountFGPP = Get-ADUserResultantPasswordPolicy $ADAccount -server srv-dc06
if ($accountFGPP -ne $null)
{
$maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge
}
else
{
$maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}

#Fill in the user variables
$samAccountName = $ADAccount.samAccountName
$userEmailAddress = $ADAccount.EmailAddress
$userPrincipalName = $ADAccount.UserPrincipalName

if ($ADAccount.PasswordExpired)
{
#write-host «Expired if»
#Write-host «The password for account $samAccountName has expired!»
$ExpiryDate = $ADAccount.PasswordLastSet + $maxPasswordAgeTimeSpan
$TodaysDate = Get-Date
$DaysToExpire = $TodaysDate — $ExpiryDate
#Calculating DaysToExpireDD to DD format (w/o fractional part and dot)
$DaysToExpireDD = $DaysToExpire.ToString() -Split («\S{17}$»)
Write-host «The password for account $samAccountName expired on: $ExpiryDate. Days past: $DaysToExpireDD.»
if (($DaysToExpire.Days -gt 0))
{
$expiryDate = $expiryDate.ToString(«d»,$ci)
#Generate e-mail structure and send message
if ($userEmailAddress)
{
#EmailStructure $userEmailAddress $expiryDate $samAccountName
#$smtp.Send($msg)
#Write-Host «NOTIFICATION — $samAccountName :: Cheked»
$NotificationCounterExp = $NotificationCounterExp + 1
$ListOfAccountsExp = $ListOfAccountsExp + $samAccountName + » — $DaysToExpireDD days past.<br>»
}
}
}
else
{
write-host «Expired else»
$ExpiryDate = $ADAccount.PasswordLastSet + $maxPasswordAgeTimeSpan
$TodaysDate = Get-Date
$DaysToExpire = $ExpiryDate — $TodaysDate
#Calculating DaysToExpireDD to DD format (w/o fractional part and dot)
$DaysToExpireDD = $DaysToExpire.ToString() -Split («\S{17}$»)
Write-host «The password for account $samAccountName expires on: $ExpiryDate. Days left: $DaysToExpireDD. «
if (($DaysToExpire.Days -eq ‘-2031’) -or ($DaysToExpire.Days -eq 15) -or ($DaysToExpire.Days -eq 7) -or ($DaysToExpire.Days -le 3))
{
#write-host «Daystoexire if»
$expiryDate = $expiryDate.ToString(«d»,$ci)
#Generate e-mail structure and send message
if ($userEmailAddress)
{
#write-host «EmailAddress if»
EmailStructure $userEmailAddress $expiryDate $samAccountName
$smtp.Send($msg)
#Write-Host «NOTIFICATION — $samAccountName :: e-mail was sent to $userEmailAddress»
$NotificationCounter = $NotificationCounter + 1
$ListOfAccounts = $ListOfAccounts + $samAccountName + » — $DaysToExpireDD days left. Sent to $userEmailAddress<br>»
}
}
}
}
Write-Host «SENDING REPORT TO IT DEPARTMENT»
EmailStructureReport(«it@maykor.com»)
$smtp.Send($msgr)




проверка истечения жизни учетки в AD

Import-Module ActiveDirectory
#Set the target OU that will be searched for user accounts
$OU = «DC=axapta,DC=local»

$ADAccounts = Get-ADUser -LDAPFilter «(objectClass=user)» -searchbase $OU -properties accountExpires, AccountExpirationDate | Where-object {$_.Enabled -eq $true}

Write-Host «=-=-=-=-=-=-=-=-=-=-=-=-=-=»
Foreach ($ADAccount in $ADAccounts)
{
$samAccountName = $ADAccount.samAccountName
$userEmailAddress = $ADAccount.Mail
$userName = $ADAccount.Name
$userEnabled = $ADAccount.Enabled
$userexp = $ADAccount.accountExpires
if (($userexp -lt 9223372036854775807) -and ($userexp -gt 0))
{
$Exp = $ADAccount.AccountExpirationDate
$TodaysDate = Get-Date
$DaysToExpire = $Exp — $TodaysDate
#Calculating DaysToExpireDD to DD format (w/o fractional part and dot)
$DaysToExpireDD = $DaysToExpire.ToString() -Split («\S{17}$»)
### Write-host «Account $samAccountName expires on: $Exp. Days left: $DaysToExpireDD»
if (($DaysToExpire.Days -lt 15) -and ($DaysToExpire.Days -gt 0))
{
Write-Host «Account: $samAccountName; $userEmailAddress; $userName истекает «$Exp.ToString(‘dd-MMM-yyyy’)»Осталось $DaysToExpireDD дней»
}

$ListOfAccounts = $ListOfAccounts + $samAccountName ### + » — $DaysToExpireDD days left. Sent to $userEmailAddress<br>»
}
}




Оперативный контроль аккаунтов пользователей и компьютеров в Active Directory

Обновлено 20.03.2013. Внесен ряд исправлений
В скриптах, связанных с удалением компьютерных учетных записей не выводилось имя компьютера
Кроме того, как оказалось, при массовых операциях, например вводах в группу или удалении из группы, приходит только одно уведомление, что само по себе не очень правильно. В связи с этим скрипты несколько переделаны — вместо последнего, отбираются все такие события за последние 120 секунд

Недавно я публиковал заметку Автоматическое уведомление о заблокированных аккаунтах. Там было вполне рабочее решение, но у него был один недостаток – информация приходила в несколько “корявом” виде. В песочнице хабры я нашел нашел статью, в которой аналогичные вещи сделаны гораздо удобнее.

На ее основании я сделал  десяток скриптов, которые будут информировать вас о:

— блокировании и разблокировании (lock/unlock) учетных записей пользователей
— добавлении или удалении кого-либо в/из группы
— включение или выключение (enable/disable) пользовательского аккаунта

— добавление или удаление компьютера в/из домена
— добавление или удаление пользователя в/из домена

Все нижеприведенные скрипты сохраняются в файлы, по одному в каждый из файлов, файлы кладутся на контроллер домена, там же запускается Task Scheduler и в нем создается задача с триггером на соответствующий EventID в Security Log, например 4740, и действием, содержащим запуск C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe с параметром в виде пути к скрипту и его именем, например, C:\cmd\event-notification-4740-account_lockout.ps1

В результате, вы оперативно получаете информацию по важным изменениям в AD и можете на нее оперативно реагировать

#Отправка уведомлений по наступлению события 4740 — блокирование учетной записи пользователя
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################
$Subject = “Заблокирован аккаунт»
$Theme = “Только что был заблокирован аккаунт”
$Server = “smtp.domain.ua
$From = “noreplay@domain.ua
$To = “it@domain.ua
$encoding = [System.Text.Encoding]::UTF8

#Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4740;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Аккаунт”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”} |%{$_.’#text’}}},@{n=”Имя компьютера”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetDomainName”}| %{$_.’#text’}}}
$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время события» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4767 — разблокирование учетной записи пользователя
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Разблокирован аккаунт”
$Theme = “Только что был разблокирован аккаунт”
$Server = “smtp.domain.ua
$From = “noreplay@domain.ua
$To = “it@domain.ua
$encoding = [System.Text.Encoding]::UTF8

#Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4767;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Аккаунт”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”} |%{$_.’#text’}}},@{n=”Имя компьютера”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetDomainName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время события» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4728 — Добавление учетной записи в группу
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Добавление учетной записи в группу”
$Theme = “Учетная запись добавлена в группу”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “it@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4728;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя группы”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}, @{n=”Имя пользователя”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “MemberName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4729 — Удаление учетной записи из группы
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Удаление учетной записи из группы”
$Theme = “Учетная запись удалена из группы”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “it@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4729;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя группы”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}, @{n=”Имя пользователя”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “MemberName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4722 — включение учетной записи пользователя
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################
$Subject = “Аккаунт включен»
$Theme = “Только что был включен аккаунт”
$Server = “smtp.domain.ua
$From = “noreplay@domain.ua
$To = “it@domain.ua
$encoding = [System.Text.Encoding]::UTF8

#Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4722;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Аккаунт”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}
$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время события» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4725 — отключение учетной записи пользователя
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################
$Subject = “Аккаунт выключен»
$Theme = “Только что был выключен аккаунт”
$Server = “smtp.domain.ua
$From = “noreplay@domain.ua
$To = “it@domain.ua
$encoding = [System.Text.Encoding]::UTF8

#Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4725;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Аккаунт”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}
$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время события» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4741 — Создание учетной записи компьютера в домене
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Создание учетной записи компьютера в домене”
$Theme = “Добавлен новый компьютер в домен”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “it@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4741;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя компьютера”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4743 — Удаление учетной записи компьютера в домене
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Удаление учетной записи компьютера в домене”
$Theme = “Компьютер удален из домена”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “john@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4743;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя компьютера”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4720 — Создание учетной записи пользователя в домене
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Создание учетной записи пользователя в домене”
$Theme = “Добавлен новый пользователь в домен”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “it@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4720;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя пользователя”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SamAccountName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


#Отправка уведомлений по наступлению события 4726 — Удаление учетной записи пользователя из домена
#Автор оригинального скрипта:
http://habrahabr.ru/post/147750/
#Изменения (itpadla.wordpress.com)
#Дата создания 22.08.2012
#Дата изменения: 20.03.2013
#Описание: скрипт отправляет уведомление о определенном событии в Security Log в письме в человекочитаемом виде
#####################################################################################

$Subject = “Удаление учетной записи пользователя из домена”
$Theme = “Удален пользователь из домена”
$Server = “smtp.domain.ua” # SMTP Сервер
$From = “noreplay@domain.ua” # Адрес отправителя
$To = “it@domain.ua” # Получатель

$encoding = [System.Text.Encoding]::UTF8

#Собственно сам запрос поиска события. Выбирается последнее произошедшее событие с таким ID.

$Body=Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4726;StartTime=(Get-Date)..AddSeconds(-120)} | Select TimeCreated,@{n=”Оператор”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “SubjectUserName”} |%{$_.’#text’}}},@{n=”Имя пользователя”;e={([xml]$_.ToXml()).Event.EventData.Data | ? {$_.Name -eq “TargetUserName”}| %{$_.’#text’}}}

$body = $body -replace «@{» -replace «}» -replace «=», «: » -replace «;»,»`n» -replace «TimeCreated»,»Время» -replace «^»,»`n»
$BodyM = $Body

Send-MailMessage -From $From -To $To -SmtpServer $server -Body “$Theme `n$BodyM” -Subject $Subject -Encoding $encoding


Если у вас Windows Server 2003, то так красиво сделать не получился, т.к. ее Task Scheduler существенно хуже того, что есть сейчас. Но можно сделать по другому — сделать задачу, запускающую скрипт раз в 5 минут, а выборку в скриптах модифицировать следующим образом: отбирать события за последних 6 минут. Получится:

Get-WinEvent -FilterHashtable @{LogName=”Security”;ID=4740;StartTime=(Get-Date).AddMinutes(-6)}

Остальное — аналогично




Поиск пользователя в AD powershell

#######################################################################################
# 
# Скрипт автоматического выключения учётных записей, удаления всех групп в которых
# состоит учётная запись, переноса в OU для отключенных учётных записей и скрытия 
# учётной записи из общей адресной книги MS Exchange
# 
#######################################################################################

cls

#Импортируем модуль для работы с AD удалённо
Import-Module ActiveDirectory

#Импортируем командлеты Exchange 
$exch = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange/powershell
Import-PSSession $exch -CommandName Get-Mailbox,Set-Mailbox -AllowClobber

$programmName = "RemoveUsers"
#Импортируем информацию о пользователях из файла в переменную
$users = Import-Csv "D:\scripts\ps\users.csv" -Delimiter ";"
#Преобразуем дату в нужный формат
$date = Get-Date -Format "yyyy-MM-dd"
#Путь OU для выключенных аккаунтов
$pathOU = "OU=Disable Users,DC=domain,DC=ru"
#Директория куда пишется логи
$logFile = "D:\scripts\ps\" + $date + "_" + $programmName + ".log"

#Функция записи логов в файл
function writeLog ($type, $msg) {
    #Преобразуем дату и время в нужный формат
    $date = Get-Date -Format "dd.MM.yyyy HH:mm:ss"
    $msg = $date + "`t" + $type + "`t" + $msg
    #Записываем сообщение в файл
    Out-File -FilePath $logFile -InputObject $msg -Append -encoding unicode
}

#Функция получения логина пользователя
function getLogin ($userName, $jobTitle) {
    try {
        #Если пользователь с указанным именем и должность есть в AD, записываем его логин в переменную и возвращаем её
        $login = (Get-ADUser -Filter {DisplayName -eq $userName -and Title -eq $jobTitle}).SamAccountName
        if ($login -ne $null) {
            $type = "OK `t getLogin `t"
            $msg = "Логин $userName - $login"
            writeLog $type $msg
            return $login
        }
        else {
            $type = "Info `t getLogin `t"
            #$msg = "Пользователь $userName в должности $jobTitle не найден"
            $msg = "$_"
            writeLog $type $msg
        }
    }
    catch {
        $type = "Error `t getLogin `t"
        #$msg = "Пользователь $userName в должности $jobTitle не найден"
        $msg = "$_"
        writeLog $type $msg
        break
    }
}

#Функция получения объекта ADUser
function getAccount ($userName, $jobTitle) {
    try {
        #Если пользователь с указанным именем и должность есть в AD, записываем его в переменную и возвращаем её
        $account = Get-ADUser -Filter {DisplayName -eq $userName -and Title -eq $jobTitle}
        return $account
    }
    catch {
        $type = "Error `t getAccount `t"
        $msg = "$_"
        writeLog $type $msg
        break
    }
}

#Функция выключения учётной записи
function disableUser ($login) {
    try {        
        Set-ADUser $login -Enabled $false         
        $type = "OK `t disableUser `t"
        $msg = "Учётная запись пользователя $login отключена"
        writeLog $type $msg
    }
    catch {
        $type = "Error `t disableUser `t"
        $msg = "$_"
        writeLog $type $msg
        break
    }
}

#Функция удаления пользователя их всех групп в которых он состоит
function removeGroupsOfMember ($login) {
    try {
        $groupsOfMember = Get-ADUser -Filter {SamAccountName -eq $login} -Properties MemberOf
        #Если переменная существует
        if ($groupsOfMember) {
            foreach ($group in $groupsOfMember.memberof) {
                #Удаляем группы
                Remove-ADGroupMember -Identity $group -Members $groupsOfMember -Confirm:$false
                $type = "OK `t removeGroupsOfMember"
                $msg = "Учётная запись пользователя $login удалена из групп(ы): $group"
                writeLog $type $msg
            }
        }
        else {
            $type = "Info `t removeGroupsOfMember"
            #$msg = "Групп не найдено"
            $msg = "$_"
            writeLog $type $msg
        }
    }
    catch {
        $msg = "$_"
        $type = "Error `t removeGroupsOfMember"
        writeLog $type $msg
        break
    }
}

#Функция переноса учётной записи
function moveToOU($user, $pathOU) {
    try {
        #Переносим учётную запись пользователя в OU указанный в pathOU
        Move-ADObject $user -TargetPath $pathOU
        $msg = "Учётная запись $login перенесена в $pathOU"
        $type = "OK `t moveToOU `t"
        writeLog $type $msg
    }
    catch {
        $msg = "$_"
        #$msg = "Учётная запись $login не перенесена"
        $type = "Error `t moveToOU `t"
        writeLog $type $msg
        break
    }
}

#Функция скрывает e-mail адрес пользователя из общей адресной книги
function hiddenAddressList ($login) {
    try {
        #Скрываем e-mail адрес из общей адресной книги
        Set-Mailbox -HiddenFromAddressListsEnabled $true -Identity $login
        $type = "OK `t hiddenAddressList"
        $msg = "Почтовый ящик пользователя $login удалён из адресной книги"
        writeLog $type $msg
    }
    catch {
        $type = "Error `t hiddenAddressList"
        #$msg = "Почтовый ящик пользователя $login не удалён из адресной книги"
        $msg = "$_"
        writeLog $type $msg
        break
    }
}

#Главная функция
function main {
    try {
        foreach($user in $users) {
            $login = getLogin $user.Name $user.JobTitle
            $account = getAccount $user.Name $user.JobTitle
            disableUser $login
            removeGroupsOfMember $login
            moveToOU $account $pathOU
            hiddenAddressList $login
        }
        $type = "OK `t main `t`t"
        $msg = "$_"
        #$msg = "Скрипт выполнился успешно"
        writeLog $type $msg
        #закрываем сессию с exchange
        Remove-PSSession $exch
    }
    catch {
        $type = "Error `t main `t`t"
        $msg = "$_"
        writeLog $type $msg
        break
    }
}

main



Копируем членов одной группы в другую

Задача: скопировать членов одной группы AD в другую. С ходу 2 решения:

  • Используем квестовские командлеты для работы с AD:
Get-QADGroupMember Group1 | % {Add-QADGroupMember Group2 -Member $_}
  • Используем Powershell 2.0 и модуль ActiveDirectory:
Import-Module ActiveDirectory
Get-ADGroupMember Group1 | % {Add-ADGroupMember Group2 -Members $_}



Управление правилами почтового ящика в Exchange Server 2010

Командлет, используемый для получения списка называется Get-InboxRule:

Get-InboxRule –Mailbox <MailboxUser>

Если вы хотите увидеть какое то определенное правило, используйте команду

Get-InboxRule –Mailbox <MailboxUser> -Identity “<Rule-Name>”

Для более удобного просмотра правил, используйте следующую конструкцию:

Get-InboxRule –Mailbox <MailboxUser> | Select Name, Description | fl

Теперь посмотрим на правило более детально с помощью командлета:

Get-InboxRule –Mailbox Anderson -Identity “Subject contains ‘Payroll’”

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

Set-InboxRule -Mailbox Anderson -Identity "Subject contains ‘Payroll’" -ApplyCategory {Red Category} -MarkImportance 2

Отключение или удаление правил

У нас также есть возможность отключать или удалять правила.  Предположим что наш руководитель опять изменил свое мнение (бывает у них такое, что поделать) и теперь он не хочет что с сообщениями содержащими слово Payroll просходили какие-либо изменения. Мы можем выполнить это просто отключив правило с помощью следующего командлета:

Disable-InboxRule -Mailbox Anderson -Identity "Subject contains ‘Payroll’"

Если вы хотите полностью удалить правило, процесс очень похож, отличает лишь командлет. Используйте:

Remove-Inboxrule –Mailbox <MailboxName> -Identity “<Inbox Rule name>”



Exchange 2010 Импорт/Экспорт почтовых ящиков

Импорт/экспорт почтовых ящиков в Exchange 2010 SP1

 

Экспорт почты в PST файл
New-MailboxExportRequest –Mailbox “sotrudnik@office.local” –Filepath “\\mail\F$\archive_pst\sotrudnik.pst”

Статус запроса
Get-MailboxExportRequest –Mailbox “sotrudnik@office.local"

Импорт PST файла
New-MailboxImportRequest -Mailbox sotrudnik -FilePath “\\mail\F$\archive_pst\sotrudnik.pst”

Статус запроса
Get-MailboxImportRequest -Mailbox sotrudnik

В некоторых случаях вы можете решить импортировать PST в подпапку почтового ящика. Для этого необходимо использовать параметр -TargetRootFolder.
New-MailboxImportRequest -FilePath “\\mail\F$\archive_pst\sotrudnik.pst” -Mailbox othersotrudnik -TargetRootFolder "Mailbox - SOTRUDNIK"

Вы можете посмотреть статус запроса импортирования с помощью командлета Get-MailboxImportRequest.

Перенаправив результат командлета Get-MailboxImportRequest в командлет Get-MailboxImportRequestStatistics вы можете просматривать прогресс выполнения запроса.
Get-MailboxImportRequest | Get-MailboxImportRequestStatistics

Когда запрос на импорт завершает работу он по прежнему остается на сервере до тех пор, пока администратор не удалит его с помощью командлета Remove-MailboxImportRequest.

Для просмотра всех завершенных запросов выполните следующую команду:
Get-MailboxImportRequest | where {$_.status -eq "Completed"}

Удалить все завершенные запросы можно следующей командой:
Get-MailboxImportRequest | where {$_.status -eq "Completed"} | Remove-MailboxImportRequest




FAQ по Microsoft Exchange Server » Как удалить сообщения по определенным критериям в нескольких почтовых ящиках в Exchange Server 2010?

Как удалить сообщения по определенным критериям в нескольких почтовых ящиках в Exchange Server 2010?

В Exchange Server 2007 эту операцию можно было выполнить двумя командами. Например, пользователю pnagaev нужно удалить в почтовом ящике пользователя Elena сообщение, содержащее слова «Odnoklassniki.ru»:

1
2
Add-MailboxPermission -Identity Elena -User pnagaev -AccessRights FullAccess
Get-Mailbox -Identity Elena | Export-Mailbox -SubjectKeywords "Odnoklassniki.ru" -DeleteContent

После выполнения нужно не забыть забрать права у пользователя pnagaev.

В общем-то это не очень хороший способ, т.к. к содержимому ящиков получает доступ третье лицо — администратор, что всегда осуждалось в среде специалистов по Exchange Server. Делай что хочешь, но в почтовый ящик пользователя залезать нельзя ни под каким предлогом.

В Exchange Server 2010 SP1  механизм доступа был пересмотрен, вышеприведенная команда Export-Mailbox не поддерживается.
Команда New-MailboxExportRequest не поддерживает параметр «-DeleteContents»
Для того, чтобы найти и удалить сообщения в Exchange Server 2010 SP1, необходимо назначить  пользователю следующие роли.

1
2
New-ManagementRoleAssignment  -Role "Support Diagnostics"   –User pnagaev
New-ManagementRoleAssignment  -Role "Mailbox Import Export" -User pnagaev

Вышеприведенные команды предоставят пользователю только необходимые права для удаления сообщений, но доступа к содержимому почтового ящика у пользователя не будет.

Для поиска и удаления сообщений служит следующая команда

1
Search-Mailbox -Identity Elena -SearchQuery 'subject:"Odnoklassniki.ru"' –DeleteContent

Эта команда может быть запущена для всех почтовых ящиков

1
Get-Mailbox –Server “*имя сервера*” –ResultSize unlimited | Search-Mailbox -SearchQuery 'subject:"Odnoklassniki.ru"' –DeleteContent

Как мы видим запрос для поиска состоит из специальных слов, например «subject:», «from:». Остальные слова можно посмотреть по ссылке Advanced Query Syntax

FAQ по Microsoft Exchange Server » Как удалить сообщения по определенным критериям в нескольких почтовых ящиках в Exchange Server 2010?.




Enable POP3 and IMAP4 Users to Use Default Protocol Settings

http://technet.microsoft.com/en-us/library/bb124540.aspx

 

You can enable POP3 and IMAP4 users to use the default protocol settings on the Microsoft Exchange Server 2010 Client Access server that has the IMAP4 service or POP3 service enabled.

Using the Exchange Management Shell to Enable POP3 and IMAP4 Users to Use the Default Protocol Settings


In addition to using the Set-PopSettings or Set-ImapSettings cmdlets to manage POP3 and IMAP4 settings for all your users, you can also use the Set-CASMailbox cmdlet to specify individual POP3 and IMAP4 settings for your users. You can also use the Set-CASMailbox cmdlet to enable a user to use the default protocol settings for a server when you use the Set-PopSettings or Set-ImapSettings cmdlets.

The following table shows the parameters to use to configure a POP3 or IMAP4 user to use the protocol default settings as specified on the Client Access server.

POP3 and IMAP4 parameters for the Set-CASMailbox cmdlet

Parameter Value Description
PoPopUseProtocolDefaults
  • $true
  • $false
This parameter lets you use the default protocol settings as specified by the Set-PopSettings cmdlet.
ImImapUseProtocolDefaults
  • $true
  • $false
This parameter lets you use the default protocol settings as specified by the Set-ImapSettings cmdlet.

For more information about the Set-CASMailbox cmdlet, see Set-CASMailbox.

Looking for other management tasks related to setting up POP 3 and IMAP4? Check out Managing POP3 and IMAP4.

Use the Shell to enable a POP3 user to use the default protocol settings


You need to be assigned permissions before you can perform this procedure. To see what permissions you need, see the «POP3 and IMAP4» entry in the Client Access Permissions topic.

This example enables a POP3 user to use the default protocol settings for the server CAS01:

Set-CASMailbox -Identity CAS01 -PopProtocolDefaults $true

This example disables the default protocol settings for a POP3 user on the server CAS01:

Set-CASMailbox -Identity CAS01 -PopProtocolDefaults $false
Use the Shell to configure an IMAP4 user to use the default protocol settings


You need to be assigned permissions before you can perform this procedure. To see what permissions you need, see the «POP3 and IMAP4» entry in the Client Access Permissions topic.

This example enables an IMAP4 user to use the default protocol settings for the server CAS01.

Set-CASMailbox -Identity CAS01 -ImapProtocolDefaults $true

This example disables the default protocol settings for an IMAP4 user on the server CAS01.

Set-CASMailbox -Identity CAS01 -ImapProtocolDefaults $false

For more information about syntax and parameters, see Set-CASMailbox.




Получение алиасов электронной почты по заданным критериям

http://www.sourica.ru/page/poluchenie-aliasov-elektronnoj-pochty-po-zadannym-kriterijam

Продолжаем писать полезные и не очень скрипты для получения данных с AD. Сейчас задача следующая.

  • Есть домен child1.example.com c почтовыми адресами на Exchange вида: @child1.com
  • Есть домен child2.example.com c почтовыми адресами на Exchange вида: @child2.com
  • У некоторых пользователей домена child2.example.com в качестве дополнительного адреса электронной почты присутствуют адреса @child1.com
  • Для определенных целей необходимо получить данные адреса.

Приступим к реализации. Как и раньше будем использовать ActiveRoles Management Shell от Quest Software. Для начала разберемся в терминах:

  • Primarysmtpaddress – адрес, используемый по умолчанию для отправки сообщений через Exchange. Он может быть только один.
  • ProxyAddresses – дополнительные адреса электронной почты, которых может быть МНОГО.

Наша задача получить список ProxyAddresses адресов @child1.com у пользователей домена child2.

Для этого используем такую конструкцию:

Gt-QADUser -SearchRoot 'dc=child2,dc=example,dc=com' -SizeLimit 0 -IncludedProperties ProxyAddresses | where {$_.ProxyAddresses -match 'child1.com'} | Select-Object @{n='CHILD1';e={$_.ProxyAddresses -match 'child1.com'}}

Разберем немного подробнее:

Get-QADUser -SearchRoot ‘dc=child2,dc=example,dc=com’ -SizeLimit 0 -IncludedProperties ProxyAddresses

  • Get-QADUser – получаем список пользователей
  • -SearchRoot ‘dc=child2,dc=example,dc=com’  — указываем нужный нам домен в качестве корня поиска пользователей
  • -SizeLimit 0  — ЕМПНИМ ограничение вывода 1000 пользователей. Убираем данный лимит если у нас очень много пользователей.
  • -IncludedProperties ProxyAddresses   —  по умолчанию в результирующий набор получаемых данных включаются не все доступные атрибуты пользователя. В частности ProxyAddresses  необходимо включать явным образом.
where {$_.ProxyAddresses -match 'child1.com'}

Получает в конвейере список пользователей. Фильтрует из них только тех, у кого в ProxyAddresses  присутствует нужный почтовый домен.

Select-Object @{n='CHILD1';e={$_.ProxyAddresses -match 'child1.com'}}

Также в конвейере получает отфильтрованный список пользователей и выводит только нужное по условиям задачи поле.

На выходе получаем список адресов электронной почты, который нас и интересует.