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

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>»
}
}




Автоматическое отключение Wi-Fi при подключении к Ethernet сети

Автоматическое отключение Wi-Fi при подключении к Ethernet сети

В Windows 10 при доступности нескольких Wi-Fi сетей система автоматически выбирает беспроводную сеть с самым сильным сигналом (не зависимо от того какова скорость этого соединения и сколько устройств его используют). Однако при подключении вашего компьютера/ноутбука к проводной Ethernet сети, Windows продолжает использовать Wi-Fi сеть, несмотря на то, что скорость подключения по Ethernet кабелю значительно выше, а само подключение стабильнее и не подвержено помехам. Чтобы переключиться на проводное Ethernet-подключение пользователю Windows приходится каждый раз вручную отключать Wi-Fi соединение. Рассмотрим, как в Windows 10 настроить автоматическое отключение Wi-Fi при подключении к Ethernet сети.

Настройка WLAN Switching в BIOS/UEFI

У многих производителей компьютерного оборудования есть собственная реализация технологии LAN/WLAN Switching (может называться по-разному). Суть технологии заключается в том, что на компьютере пользователя одновременно должен передавать данные только один сетевой адаптер. Если во время использования устройством Wi-Fi сети на компьютере появилось более приоритетное проводное Ethernet-подключение, Wi-Fi адаптер должен автоматически переходить в режим ожидания. Тем самым экономятся ресурсы батареи и уменьшается нагрузка на беспроводную Wi-Fi сеть.

LAN/WLAN Switching можно включить в настройках BIOS/UEFI или в свойствах драйвера беспроводного сетевого адаптера (все зависит от производителя оборудования).

Перезагрузите компьютер и войдите в настройки UEFI / BIOS найдите и включите опцию LAN/WLAN Switching (на устройствах HP), Wireless Radio Controll (на устройствах Dell).

LAN/WLAN Switching

Данный функционал может называться по-другому или совсем отсутствовать в BIOS/UEFI других производителей.

Опция «Отключить после установления проводного соединения» в параметрах адаптера Wi-Fi

В настройках драйвера некоторых Wi-Fi адаптеров есть опция, позволяющая автоматически отключать Wi-Fi адаптер при наличии скоростного Ethernet подключения.

В Windows 10 откройте Центр управления сетями и общим доступом и откройте свойства вашего Wi-fi адаптера. Нажмите на кнопку Настроить.

настроить wifi адаптер 802.11n

В окне свойств сетевого адаптера перейдите на вкладку Дополнительно и в списке опций Wi-Fi адаптера найдите пункт «Отключить после установления проводного соединения / Disabled Upon Wired Connect». Измените значение опции на Включено и сохраните изменения.

Отключить после установления проводного соединения

Disabled Upon Wired Connect

Благодаря этой опции драйвер беспроводной сети будет отключать адаптер от Wi-fi сети при обнаружении активного Ethernet подключения.

Данная опция поддерживается далеко не на всех моделях Wi-Fi адаптеров. Если у вас он отсутствует, можно автоматизировать автоматические переключение на Ethernet подключение с помощью скрипта PowerShell.

Автоматизируем переключение между Wi-Fi и Ethernet сетями с помощью PowerShell

Для автоматического включения и отключение WLAN адаптера можно написать собственный скрипт и привязать его к событиям появления линка на LAN интерфейсе (Event-ID: 32 — Network link is established) и (Event-ID: 27 – Network link is disconnected) с помощью триггеров событий, но есть уже готовое решение на PowerShell.

Для решения задачи автоматического отключения Wi-Fi адаптера при подключении компьютера к проводной Ethernet сети можно воспользоваться готовым PowerShell скриптом WLAN Manager (оригинальная версия доступна здесь https://gallery.technet.microsoft.com/scriptcenter/WLAN-Manager-f438a4d7). Более новая версия скрипта WLAN Manager с расширенной поддержкой Windows 10 и нормальным определением виртуальных адаптеров есть на GitHub (https://github.com/jchristens/Install-WLANManager).

Суть скрипта заключается в том, что PowerShell скрипт создаетс новое задание планировщика в системе, которое запускает PoSh скрипт при загрузке системы. Скрипт периодически выполняет проверку активных сетевых адаптеров. Если скрипт обнаруживает наличие подключение по LAN (Ethernet), то WLAN интерфейс автоматически отключается. Если сетевой кабель Ethernet отключен, скрипт сам включает беспроводной Wi-Fi адаптер.

Скрипт состоит из 2 файлов:

  • PSModule-WLANManager.psm1
  • WLANManager.ps1

Рассмотрим как установить скрипт WLAN Manager в Windows 10. Откройте командную строку PowerShell с правами администратора и разрешите выполнение скрипта:

Set-ExecutionPolicy RemoteSigned

Установим скрипт в системе с помощью команды:

.\WLANManager.ps1 -Install:System

Скрипт можно установить для запуска из под прав пользователя (Install:User) или для запуска из-под системы (Install:System).

WLANManager скрипт Powershell

Verifying WLAN Manager version information… Missing

Writing WLAN Manager version information… Done

Verify WLAN Manager Files… Missing

Installing WLAN Manager Files… Done

Verify WLAN Manager Scheduled Task… Missing

Installing WLAN Manager Scheduled Task… Done

Можно заставить скрипт оповещать пользователя о переключении между Wi-Fi и LAN сетью:

.\WLANManager.ps1 -Install:User -BalloonTip:$true

Убедитесь, что в планировщике появилось новое задание WLAN Manager.

WLAN Manager - скрипт для автоматического отключения WiFI при Ethernet подключении

Перезагрузите компьютер. После загрузки планировщик запустите скрипт «C:\Program Files\WLANManager\WLANManager.ps1», который каждую секунду проверяет сетевые подключения и, если будет обнаружено LAN подключение, все доступные Wi-Fi адаптеры будут отключены. При отключении LAN кабеля, скрипт автоматически включает беспроводные Wi-Fi адаптеры.

Скрипт WLAN Manager корректно работает как на Windows 10, так и в Windows 8.1 и 7.

Совет. Чтобы удалить скрипт, выполните команду:

.\WLANManager.ps1 Remove:System

Отключение не-доменных беспроводных сетей с помощью GPO

В групповых политиках есть отдельная настройка, которая позволяет запретить подключение к Wi-Fi сетям, когда компьютер подключен к корпоративной доменной сети через LAN. Эта политика находится в разделе Computer Configuration -> Policies ->Administrative Templates -> Network (Сеть) ->Windows Connection Manager (Диспетчер подключений Windows) и называется «Prohibit connection to non-domain networks when connected to domain authenticated network» (Запретить подключение к сетям без домена при наличии доменной сети). Эта политика появилась в Windows 8 / Windows Server 2012 и выше).

Политика запрещает компьютерам одновременно подключаться к доменной сети и к сети без домена.

Запретить подключение к сетям без домена при наличии доменной сети

Однако при включении этой политики у вас могут возникнуть проблемы с подключением к Wi-Fi сети, если у вас на компьютере есть дополнительные интерфейсы (например, loopback или созданные ПО виртуализации)




Полное тестирование Active Directory на ошибки

Полное тестирование Active Directory на ошибки

1. Первым делом нужно запустить общий тест:

netdom query fsmo 

dcdiag /e /v /q

dcdiag /n:local /e /v /f:c:\adtest.log

Ключи /q можно убрать если нужна информация не только об ошибках. 
2. Проверим здоровье DNS серверов. Выполним команду на одном из контроллеров домена:

DCDiag /Test:DNS /e /v /s:controller.contoso.com >DcdiagDNS.txt

дальше полученный отчет открываем:

notepad dcdiagdns.txt

Если всё хорошо то увидим везде слово PASS:

Если полученные ошибки ручками не получается поправить — пробуем:

DCDiag /Test:DNS /e /v /s:controller.contoso.com /fix

А также ipconfig /registerdns на контроллерах.

3. Теперь проверим здоровье репликации Active Directory. 

Запускаем общую проверку статуса репликации на контроллере:

repadmin /replsum

Получаем:

 Если значение наиб. дельты не боле часа — с репликацией всё в порядке. Количество сбоев должно быть равно 0.

Если же возникли ошибки то можно использовать следующую команду чтобы посмотреть какой контекст наименования не реплицируется:

repadmin /showreps

Получим такой вывод:

4. Диагностика службы времени.

Общая проверка синхронности часов на контроллерах:

w32tm /monitor

Получим:

Смещение не должно быть больше или меньше 0 целых на всех контроллерах. В нашем случае +2 секунды на одном из них. Как это исправить читаем тут.

5. Диагностика групповых политик.

Сначала проверим расшаренные папки SYSVOL и Netlogon. Через них распространяются групповые политики.

Проверим расшарены ли эти папки. На каждом контроллере домена:

net share 

Получаем такой результат:

Всё в порядке шАры на месте.

Теперь тест dcdiag:

dcdiag /test:netlogons

Если тест пройден увидим следующее:

В этом случае с шарами всё в порядке.

Чтобы проверить применяются ли GPO можно запустить мастер результатов групповой политики из оснастки Управление групповой политикой (GPMC). Либо выполнить следующую команду:

gpresult /user domainuser /z >gpresult.txt поправить тут

notepad gpresult.txt

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




Домены, адреса и Windows: смешивать, но не взбалтывать

https://habrahabr.ru/company/pc-administrator/blog/330944/

[Конспект админа] Домены, адреса и Windows: смешивать, но не взбалтывать

В очередном «конспекте админа» остановимся на еще одной фундаментальной вещи – механизме разрешения имен в IP-сетях. Кстати, знаете почему в доменной сети nslookup на все запросы может отвечать одним адресом? И это при том, что сайты исправно открываются. Если задумались – добро пожаловать под кат..

Для преобразования имени в IP-адрес в операционных системах Windows традиционно используются две технологии – NetBIOS и более известная DNS.

Дедушка NetBIOS

NetBIOS (Network Basic Input/Output System) – технология, пришедшая к нам в 1983 году. Она обеспечивает такие возможности как:

  • регистрация и проверка сетевых имен;
  • установление и разрыв соединений;
  • связь с гарантированной доставкой информации;
  • связь с негарантированной доставкой информации;
  • поддержка управления и мониторинга драйвера и сетевой карты.

В рамках этого материала нас интересует только первый пункт. При использовании NetBIOS имя ограниченно 16 байтами – 15 символов и спец-символ, обозначающий тип узла. Процедура преобразования имени в адрес реализована широковещательными запросами.

Небольшая памятка о сути широковещательных запросов.

Широковещательным называют такой запрос, который предназначен для получения всеми компьютерами сети. Для этого запрос посылается на специальный IP или MAC-адрес для работы на третьем или втором уровне модели OSI.

Для работы на втором уровне используется MAC-адрес FF:FF:FF:FF:FF:FF, для третьего уровня в IP-сетях адрес, являющимся последним адресом в подсети. Например, в подсети 192.168.0.0/24 этим адресом будет 192.168.0.255

Интересная особенность в том, что можно привязывать имя не к хосту, а к сервису. Например, к имени пользователя для отправки сообщений через net send.

Естественно, постоянно рассылать широковещательные запросы не эффективно, поэтому существует кэш NetBIOS – временная таблица соответствий имен и IP-адреса. Таблица находится в оперативной памяти, по умолчанию количество записей ограничено шестнадцатью, а срок жизни каждой – десять минут. Посмотреть его содержимое можно с помощью команды nbtstat -c, а очистить – nbtstat -R.

Пример работы кэша для разрешения имени узла «хр».

Что происходило при этом с точки зрения сниффера.

В крупных сетях из-за ограничения на количество записей и срока их жизни кэш уже не спасает. Да и большое количество широковещательных запросов запросто может замедлить быстродействие сети. Для того чтобы этого избежать, используется сервер WINS (Windows Internet Name Service). Адрес сервера администратор может прописать сам либо его назначит DHCP сервер. Компьютеры при включении регистрируют NetBIOS имена на сервере, к нему же обращаются и для разрешения имен.

В сетях с *nix серверами можно использовать пакет программ Samba в качестве замены WINS. Для этого достаточно добавить в конфигурационный файл строку «wins support = yes». Подробнее – в документации.

В отсутствие службы WINS можно использовать файл lmhosts, в который система будет «заглядывать» при невозможности разрешить имя другими способами. В современных системах по умолчанию он отсутствует. Есть только файл-пример-документация по адресу %systemroot%\System32\drivers\etc\lmhost.sam. Если lmhosts понадобится, его можно создать рядом с lmhosts.sam.

Сейчас технология NetBIOS не на слуху, но по умолчанию она включена. Стоит иметь это ввиду при диагностике проблем.

Стандарт наших дней – DNS

DNS (Domain Name System) – распределенная иерархическая система для получения информации о доменах. Пожалуй, самая известная из перечисленных. Механизм работы предельно простой, рассмотрим его на примере определения IP адреса хоста www.google.com:

  • если в кэше резолвера адреса нет, система запрашивает указанный в сетевых настройках интерфейса сервер DNS;
  • сервер DNS смотрит запись у себя, и если у него нет информации даже о домене google.com – отправляет запрос на вышестоящие сервера DNS, например, провайдерские. Если вышестоящих серверов нет, запрос отправляется сразу на один из 13 (не считая реплик) корневых серверов, на которых есть информация о тех, кто держит верхнюю зону. В нашем случае – com.
  • после этого наш сервер спрашивает об имени www.google.com сервер, который держит зону com;
  • затем сервер, который держит зону google.com уже выдает ответ.

Наглядная схема прохождения запроса DNS.

Разумеется, DNS не ограничивается просто соответствием «имя – адрес»: здесь поддерживаются разные виды записей, описанные стандартами RFC. Оставлю их список соответствующим статьям.

Сам сервис DNS работает на UDP порту 53, в редких случаях используя TCP.

DNS переключается на TCP с тем же 53 портом для переноса DNS-зоны и для запросов размером более 512 байт. Последнее встречается довольно редко, но на собеседованиях потенциальные работодатели любят задавать вопрос про порт DNS с хитрым прищуром.

Также как и у NetBIOS, у DNS существует кэш, чтобы не обращаться к серверу при каждом запросе, и файл, где можно вручную сопоставить адрес и имя – известный многим %Systemroot%\System32\drivers\etc\hosts.

В отличие от кэша NetBIOS в кэш DNS сразу считывается содержимое файла hosts. Помимо этого, интересное отличие заключается в том, что в кэше DNS хранятся не только соответствия доменов и адресов, но и неудачные попытки разрешения имен. Посмотреть содержимое кэша можно в командной строке с помощью команды ipconfig /displaydns, а очистить – ipconfig /flushdns. За работу кэша отвечает служба dnscache.

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

При попытке разрешения имени обычно используются сервера DNS, настроенные на сетевом адаптере. Но в ряде случаев, например, при подключении к корпоративному VPN, нужно отправлять запросы разрешения определенных имен на другие DNS. Для этого в системах Windows, начиная с 7\2008 R2, появилась таблица политик разрешения имен (Name Resolution Policy Table, NRPT). Настраивается она через реестр, в разделе HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DnsClient\DnsPolicyConfig или групповыми политиками.

Настройка политики разрешения имен через GPO.

При наличии в одной сети нескольких технологий, где еще и каждая – со своим кэшем, важен порядок их использования.

Порядок разрешения имен

Операционная система Windows пытается разрешить имена в следующем порядке:

  • проверяет, не совпадает ли имя с локальным именем хоста;
  • смотрит в кэш DNS распознавателя;
  • если в кэше соответствие не найдено, идет запрос к серверу DNS;
  • если имя хоста «плоское», например, «servername», система обращается к кэшу NetBIOS. Имена более 16 символов или составные, например «servername.domainname.ru» – NetBIOS не используется;
  • если не получилось разрешить имя на этом этапе – происходит запрос на сервер WINS;
  • если постигла неудача, то система пытается получить имя широковещательным запросом, но не более трех попыток;
  • последняя попытка – система ищет записи в локальном файле lmhosts.

Для удобства проиллюстрирую алгоритм блок-схемой:

Алгоритм разрешения имен в Windows.

То есть, при запуске команды ping server.domain.com NetBIOS и его широковещательные запросы использоваться не будут, отработает только DNS, а вот с коротким именем процедура пойдет по длинному пути. В этом легко убедиться, запустив простейший скрипт:

@echo off
echo %time%
ping hjfskhfjkshjfkshjkhfdsjk.com
echo %time%
ping xyz
echo %time%
pause

Выполнение второго пинга происходит на несколько секунд дольше, а сниффер покажет широковещательные запросы.

Сниффер показывает запросы DNS для длинного имени и широковещательные запросы NetBIOS для короткого.

Отдельного упоминания заслуживают доменные сети – в них запрос с коротким именем отработает чуть по-другому.

Active Directory и суффиксы

Active Directory тесно интегрирована с DNS и не функционирует без него. Каждому компьютеру домена создается запись в DNS, и компьютер получает полное имя (FQDN — fully qualified domain name) вида name.subdomain.domain.com.

Для того чтоб при работе не нужно было вводить FQDN, система автоматически добавляет часть имени домена к хосту при различных операциях – будь то регистрация в DNS или получение IP адреса по имени. Сначала добавляется имя домена целиком, потом следующая часть до точки.

При попытке запуска команды ping servername система проделает следующее:

  • если в кэше DNS имя не существует, система спросит у DNS сервера о хосте servername.subdomain.domain.com;
  • если ответ будет отрицательный – система запросит servername.domain.com, на случай, если мы обращаемся к хосту родительского домена.

При этом к составным именам типа www.google.com суффиксы по умолчанию не добавляются. Это поведение настраивается групповыми политиками.

Настройка добавления суффиксов DNS через групповые политики.

Настраивать DNS суффиксы можно также групповыми политиками или на вкладке DNS дополнительных свойств TCP\IP сетевого адаптера. Просмотреть текущие настройки удобно командой ipconfig /all.

Суффиксы DNS и их порядок в выводе ipconfig /all.

Однако утилита nslookup работает немного по-другому: она добавляет суффиксы в том числе и к длинным именам. Посмотреть, что именно происходит внутри nslookup можно, включив диагностический режим директивой debug или расширенный диагностический режим директивой dc2. Для примера приведу вывод команды для разрешения имени ya.ru:

nslookup -dc2 ya.ru

------------
Got answer:
    HEADER:
        opcode = QUERY, id = 1, rcode = NOERROR
        header flags:  response, want recursion, recursion avail.
        questions = 1,  answers = 1,  authority records = 0,  additional = 0

    QUESTIONS:
        4.4.8.8.in-addr.arpa, type = PTR, class = IN

    ANSWERS:
    ->  4.4.8.8.in-addr.arpa
        name = google-public-dns-b.google.com
        ttl = 86399 (23 hours 59 mins 59 secs)

------------
╤хЁтхЁ:  google-public-dns-b.google.com
Address:  8.8.4.4

------------
Got answer:

    HEADER:
        opcode = QUERY, id = 2, rcode = NOERROR
        header flags:  response, want recursion, recursion avail.
        questions = 1,  answers = 1,  authority records = 0,  additional = 0

    QUESTIONS:
        ya.ru.subdomain.domain.com, type = A, class = IN

    ANSWERS:
    ->  ya.ru.subdomain.domain.com
        internet address = 66.96.162.92
        ttl = 599 (9 mins 59 secs)

------------
Не заслуживающий доверия ответ:

------------
Got answer:

    HEADER:
        opcode = QUERY, id = 3, rcode = NOERROR
        header flags:  response, want recursion, recursion avail.
        questions = 1,  answers = 0,  authority records = 1,  additional = 0

    QUESTIONS:
        ya.ru.subdomain.domain.com, type = AAAA, class = IN

    AUTHORITY RECORDS:
    ->  domain.com
        ttl = 19 (19 secs)
        primary name server = ns-2022.awsdns-60.co.uk
        responsible mail addr = awsdns-hostmaster.amazon.com
        serial  = 1
        refresh = 7200 (2 hours)
        retry   = 900 (15 mins)
        expire  = 1209600 (14 days)
        default TTL = 86400 (1 day)

------------
╚ь :     ya.ru.subdomain.domain.com
Address:  66.96.162.92

Из-за суффиксов утилита nslookup выдала совсем не тот результат, который выдаст например пинг:

ping ya.ru -n 1
Обмен пакетами с ya.ru [87.250.250.242] с 32 байтами данных:
Ответ от 87.250.250.242: число байт=32 время=170мс TTL=52

Это поведение иногда приводит в замешательство начинающих системных администраторов.

Лично сталкивался с такой проблемой: в домене nslookup выдавал всегда один и тот же адрес в ответ на любой запрос. Как оказалось, при создании домена кто-то выбрал имя domain.com.ru, не принадлежащее организации в «большом интернете». Nslookup добавляла ко всем запросам имя домена, затем родительский суффикс – com.ru. Домен com.ru в интернете имеет wildcard запись, то есть любой запрос вида XXX.com.ru будет успешно разрешен. Поэтому nslookup и выдавал на все вопросы один ответ. Чтобы избежать подобных проблем, не рекомендуется использовать для именования не принадлежащие вам домены.

При диагностике стоит помнить, что утилита nslookup работает напрямую с сервером DNS, в отличие от обычного распознавателя имен. Если вывести компьютер из домена и расположить его в другой подсети, nslookup будет показывать, что всё в порядке, но без настройки суффиксов DNS система не сможет обращаться к серверам по коротким именам.

Отсюда частые вопросы – почему ping не работает, а nslookup работает.

В плане поиска и устранения ошибок разрешения имен могу порекомендовать не бояться использовать инструмент для анализа трафика – сниффер. С ним весь трафик как на ладони, и если добавляются лишние суффиксы, то это отразится в запросах DNS. Если запросов DNS и NetBIOS нет, некорректный ответ берется из кэша.

Если же нет возможности запустить сниффер, рекомендую сравнить вывод ping и nslookup, очистить кэши, проверить работу с другим сервером DNS.




disk defragmentation using group policy

Create a GPO and navigate to:

[Computer Configuration\Preferences\Control Panel Settings\Scheduled Tasks],

Right-click in the right-panel, choose Scheduled Task (Windows Vista and later):

1. type a name and choose SYSTEM account to run this task.
2. Switch to Triggers tab, click New, choose Weekly (or any date you prefer), click OK.
3. Switch to Action tab, click New, type «defrag.exe» in Program/script box, type «/C » in Add arguments box. Click OK. You can choose other parameters based on your need. Type defrag /? Get more information about this command.




Domain Controller starts up in Safe Mode

Domain Controller starts up in Safe Mode

KB ID: 1277
Products: Veeam Backup & Replication
Version: 7.x, 8.x, 9.x
Published: 2011-10-06
Last Modified: 2016-08-08

Challenge

After doing a full Virtual Machine restore, Instant Recovery, or testing of a Replica, you will find that the Virtual Machine boots up in what appears to be safe mode.

When the Domain Controller boots for the first time it is actually in Active Directory services restore mode.

Cause

This is normal for this to happen as we’re booting from a backup file, however it should reboot automatically.

Solution

Login with the Directory services restore mode account (typically .\administrator) and open a command prompt and run the following:

bcdedit /deletevalue safeboot
shutdown -t 01 -r
Afterwards it should reboot in normal mode.
For Windows Server 2003:
BCDEdit does not work for Windows 2003 server, so you may use BOOTCFG.exe or Edit BOOT.INI file to remove the SAFEBOOT parameter of the entry.

More Information

Please reference the Microsoft Knowledge Base Article below for further details:

http://technet.microsoft.com/en-us/library/cc816897(WS.10).aspx

For a complete guide of how to restore a Domain Controller from a Veeam Backup please see this KB:

https://www.veeam.com/kb2119




Оперативный контроль аккаунтов пользователей и компьютеров в 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 $_}