Для контроля хода репликации объектов AD можно использовать средства PowerShell из модуля Active Directory.
Для начала, импортируем модуль:
Import-Module ActiveDirectory
Для выведения полного списка командлетов, связанных с работой по репликации AD можно выполнить:
get-command -module activedirectory -name *ADReplicat*
В случае, если нужно вывести список ошибок репликации на контроллере(или контроллерах) домена, можно воспользоваться командлетом
Get-ADReplicationFailure -Target DC1,DC2
, где DC1,DC2 – имена домен-контроллеров.
Также можно запросить статус репликации для всех контроллеров домена в составе сайта:
Get-ADReplicationFailure -scope site -target {SITE} | FT Server, LastError, Partner-AutoТоже самое, но для отдельного домена:
Get-ADReplicationFailure -Target "domen.com" -Scope Domain
Предположим, выявили проблемы с репликацией конкретного объекта AD. В этом случае можно попробовать принудительно инициировать его репликацию с помощью командлета Sync-ADObject.
Get-ADDomainController -filter * | foreach {Sync-ADObject -Object "cn=Vasya Pupkin ,cn=Users,dc=domen,dc=com" -source DC1 -Destination $_.hostname}Еще несколько полезных командлетов.
Get-ADReplicationPartnerMetadata позволяет получить информацию о метаданных репликации между DC и его партнерами, в частности время последней попытки выполнить репликацию и время последней успешной репликации( для этого нужно выбрать данные, которые мы хотим получить (Select-Object Server, LastReplicationAttempt, LastReplicationSuccess, Partner)
С помощью командлета Get-ADReplicationQueueOperation можно получить список операций ожидающих репликации на сервере.
Командлет Get-ADReplicationConnection позволяет вывести информацию о партнерах репликации для текущего контролера домена. Например, если мы хотим узнать эту информацию для конкретного домен-контроллера, можно выполнить:
Get-ADReplicationConnection -Filter {ReplicateToDirectoryServer -eq "DC1"}Командлет Get-ADReplicationUpToDatenessVectorTable выдает список USN для партнеров по репликации:
Get-ADReplicationUpToDatenessVectorTable * | ft Partner,Server,UsnFilter
С помощью PowerShell вы можете определить точный размер определенного каталога в Windows (с учетом всех вложенных директорий). Это позволит узнать размер каталог без использования сторонних утилит, таких как TreeSize или WinDirStat. Кроме того, PowerShell позволяет более гибко отфильтровать файлы по типам или размерам, которые нужно учитывать при расчете размера папки.
Для получения размеров файлов в каталогах используются следующие командлеты PowerShell:
- Get-ChildItem (алиас
gci
) — позволяет получить список файлов в директории (включая вложенные объекты) - Measure-Object (алиас
measure
) – складывает размеры всех файлов для получения суммарного размера директории
Например, чтобы получить полный размер директории F:\ISO в Гб, выполните команду:
Рассмотрим используемые параметры:
-
-Force
— учитывать скрытые и системные файлы -
-Recure
— получать список файлов во вложенных директориях -
-ErrorAction SilentlyContinue
– игонрировать объекты, к которым у текущего пользователя нет доступа -
-measure Length -sum
– сложить размеры всех файлов (свойство Length) -
.sum/ 1Gb
– вывести только суммарный размер в Гб
В данном примере размер директории около 37 Гб (без учета NTFS сжатия). Чтобы округлить результаты до двух символов после запятой, выполните команду:

С помощью PowerShell можно получить суммарный размер всех файлов определенного типа в директории. Например, чтобы узнать сколько места занято ISO файлами, добавьте параметр
*.iso
:

Можно использовать другие фильтры для выбора файлов, которые учитываются при расчете размера директории. Например, вы можете получить размер файлов, созданных за 2023 год
Указанная выше PowerShell команда при подсчете размера файлов в каталоге будет выводить неверные данные, если в директории есть символические или жесткие ссылки. Например, в каталоге C:\Windows находится много жестких ссылок на файлы в хранилище компонентов WinSxS. В результате такие файлы могут быть посчитаны несколько раз. Чтобы не учитывать в результатах жесткие ссылки, используйте следующую команду (выполняется довольно долго):

$targetfolder='C:\Users'
$dataColl = @()
gci -force $targetfolder -ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | % { $len = 0 gci -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length } $filesCount = (gci -recurse -force $_.fullname -File -ErrorAction SilentlyContinue | Measure-Object).Count $dataObject = New-Object PSObject -Property @{ Folder = $_.fullname SizeGb = ('{0:N3}' -f ($len / 1Gb)) -as [single] filesCount=$filesCount } $dataColl += $dataObject }
$dataColl | Out-GridView -Title "Размер вложенных каталогов и количество файлов"
% — это алиас для цикла foreach-object.
Не секрет, что начиная с первой версии PowerShell, Microsoft пытается сделать из него основной инструмент администрирования Windows. И во многом это получается! Сегодня на простых примерах, мы покажем возможности PowerShell, которые можно использовать для получения различной информации о пользователях Active Directory и их атрибутах.
Примечание. Ранее для получения информации об атрибутах учетных записей пользователей AD приходилось использовать различные инструменты: консоль ADUC (в том числе сохраненные запросы AD), vbs скрипты, утилиту dsquery и т.п. Выбор инструмента обычно основывался на поставленной задачи и способностях администратора в программировании.
Запускаем окно Powershll с правами администратора и импортируем модуль Active Directory командой:
Import-Module activedirectoryСовет. В Windows Server 2012 и выше этот пункт можно пропустить, так как модуль PowerShell Active Directory подключен по-умолчанию.

help Get-ADUserЧтобы вывести список всех учетных записей домена, выполним команду:
Get-ADUser -filter *Важно. Не рекомендуется выполнять эту команду в доменах с большим количеством аккаунтов, т.к. возможно перегрузка контроллера домена, предоставляющего данные.
Формат возвращаемого списка не очень удобен для использования, выводится только некоторые основные 10 из более 120 атрибутов и свойств учетных записей пользователей (DN, SamAccountName, Name, SID, UPN и т.д) кроме того, мы видим, что информация о времени последней смены пароля отсутствует.
Get-ADUser -identity tuser -properties *- PasswordExpired
- PasswordLastSet
- PasswordNeverExpires
Get-ADUser tuser -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires
Теперь в данных пользователя есть информация о дате смены пароля и времени, когда срок пароля истечет. Представим информацию в более удобном табличном виде:
Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires
Чтобы вывести данные пользователей из определенной OU, воспользуемся параметром SearchBase:
Get-ADUser -SearchBase ‘OU=Moscow,DC=winitpro,DC=loc’ -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpiresРезультат выполнения команды можно выгрузить в текстовый файл:
Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | ft Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires > C:\temp\users.txtИли в CSV, который в дальнейшем будет удобно экспортировать в Excel (дополнительно с помощью sort-object отсортируем таблицу по столбцу PasswordLastSet , а также добавим условие where – имя пользователя должно содержать строку «Dmitry»):
Get-ADUser -filter * -properties PasswordExpired, PasswordLastSet, PasswordNeverExpires | where {$_.name –like “*Dmitry*”} | sort-object PasswordLastSet | select-object Name, PasswordExpired, PasswordLastSet, PasswordNeverExpires | Export-csv -path c:\temp\user-password-expires-2015.csv
Таким образом, можно построить таблицу с любыми необходимыми атрибутами пользователей Active Directory.
Совет. Для получения данных о компьютерах Active Directory используется командлет Get-ADComputer.
Далее приведем еще несколько полезных вариантов запросов о пользователях Active Directory с помощью различных фильтров. Вы можете их комбинировать для получения необходимого списка пользователей AD:
Вывод пользователей AD, имя которых начинается с Roman:
Get-ADUser -filter {name -like "Roman*"}Чтобы подсчитать общее количество всех аккаунтов в Active Directory:
Get-ADUser -Filter {SamAccountName -like "*"} | Measure-ObjectСписок всех активных (не заблокированных) учетных записей в AD:
Get-ADUser -Filter {Enabled -eq "True"} | Select-Object SamAccountName,Name,Surname,GivenName | Format-TableСписок учетных записей с истекшим сроком действия пароля:
Get-ADUser -filter {Enabled -eq $True} -properties passwordExpired | where {$_.PasswordExpired}Список активных учеток с почтовыми адресами:
Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Format-TableЗадача: для списка учетных записей, которые хранятся в текстовом файле (по одной учетке в строке) нужно получить телефон пользователя в AD и выгрузить информацию в текстовый csv файл (можно легко импортировать в Esxel).
Import-Csv c:\ps\usernsme_list.csv | ForEach {
Get-ADUser -identity $_.user -Properties Name, telephoneNumber |
Select Name, telephoneNumber |
Export-CSV c:\ps\export_ad_list.csv -Append -Encoding UTF8
}Следующий пример позволяет выгрузить адресную книгу предприятия в виде csv файла, который в дальнейшем можно импортировать в Outlook или Mozilla Thunderbird:
Get-ADUser -Filter {(mail -ne "null") -and (Enabled -eq "true")} -Properties Surname,GivenName,mail | Select-Object Name,Surname,GivenName,mail | Export-Csv -NoTypeInformation -Encoding utf8 -delimiter "," $env:temp\mail_list.csvПользователи, которые не меняли свой пароль в течении последних 90 дней:
$90_Days = (Get-Date).adddays(-90)
Get-ADUser -filter {(passwordlastset -le $90_days)}Чтобы получить фотографию пользователя из Active Directory и сохранить ее в jpg файл:
$user = Get-ADUser winadmin -Properties thumbnailPhoto
$user.thumbnailPhoto | Set-Content winadmin.jpg -Encoding byteСписок групп, в которых состоит учетная запись пользователя
Get-AdUser winadmin -Properties memberof | Select memberof -expandproperty memberof
PowerShell – это средство автоматизации разработанное и выпущенное Microsoft в 2006 году на замену Командной строке и её батникам, помимо всего функционала cmd – Powershell обзавелась собственным скриптовым языком с поддержкой классов, объектов, переменных и т.д. По сути с её помощью можно обращаться ко всему функционалу Windows и Windows Server как к объектам и выполнять с ними действия. В статье я расскажу свой опыт, как автоматизировал создание пользователей в домене из писем-заявок в Outlook на удаленном сервере AD.

Все запланированные задачи в Windows можно посмотреть в “Планировщике задач”, автоматизировать Windows возможно как с его помощью, так и чисто на Powershell, чтобы вывести все текущие задачи необходимо выполнить:
Get-ScheduledJob Чтобы вывести запланированные только с помощью Powershell используется команда ниже, так как задачи созданные в Powershell хранятся в отдельной директории, достаточно их просто прочитать:
Get-ChildItem $HOME\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobsДля создания задания необходимо выполнить следующую команду, в квадратные скобки необходимо передать выполняемый скрипт:
$Условие = New-JobTrigger -Daily -At 12AM
Register-ScheduledJob -Name NewAD_User -ScriptBlock {######} -Trigger $УсловиеРассмотрим как происходит взаимодействие с Outlook, и сразу отмечу что для выполнения действий с почтой, необходимо закрыть открытое приложение, иначе команды не будут выполняться.
#Завершение Outlook
Get-Process | Where-Object {$_.ProcessName -eq "OUTLOOK"} | Stop-Process
Start-Sleep -Seconds 10
# Создание объекта Outlook
$outlook = New-Object -ComObject Outlook.Application
# Получение коллекции папок
$folders = $outlook.Session.Folders.Item("###Ваш адрес почты####").Folders
# Выбор папки "Входящие"
$Входящие = $folders.Item("Входящие")
$Исполнено = $folders.Item("Исполнено")
# Получение последнего письма
$Письма = $Входящие.Items | Sort-Object ReceivedTime -DescendingВ данном коде я получаю сортированный по дате список писем из папки “Входящие” и адрес папки “Исполнено” куда я планирую перемещать письма после выполнения скрипта.
foreach ($Письмо in $Письма) {
$lines = $Письмо.Body -split "`n"
#Условие чтения письма
if ($lines[0].Substring(0, 29) -ne "Заявка в IT - Новый сотрудник") {continue}
$Дата_заявки = $lines[0].Substring(32).Trim()
$Фамилия = $lines[2].Substring(18).Trim()
$Имя = $lines[4].Substring(4).Trim()
$Отчество = $lines[6].Substring(9).Trim()
$Отдел = $lines[8].Substring(6).Trim()
$Должность = $lines[10].Substring(10).Trim()
$Организация = $lines[12].Substring(12).Trim()
$Подразделение = $lines[14].Substring(14).Trim()
$Номер_телефона = $lines[16].Substring(15).Trim()
$Мобильный_телефон = $lines[18].Substring(18).Trim()
$Имя_пользователя_для_копирования_групп = $lines[20].Substring(29).Trim()В данном фрагменте начинается цикл который проходит по каждому письму, преобразует в список строк и получает значения из него, в начале я добавил простую проверку на случай если на выделенный почтовый ящик попадет случайное письмо. Далее самое важное – создание учетки, и в моем случае контакта, на удаленном сервере, для этого используется команда Invoke-Command:
$Сессия = New-PSSession -ComputerName ###Сетевое имя или IP-адресс компа###$Переменные = Invoke-Command -Session $Сессия -ScriptBlock {
param(####Все ваши переменные через запятую###)
команды на удаленном компе
return Переменные которые вернуться в массив обьектов "$Переменные"
} -ArgumentList ###Переменные через запятую которые вы передали в параметры###Переменная “$Переменные” примет, после выполнения команды на удаленном компьютере, переменные, указанные в return – они понадобятся для отправления письма-отчета.
#Транслит имени
function global:Translit {} - Функция принимает кирилицу и возвращает латиницу
$count = 0
#---------------Получаем список пользователей AD-----------------
$adUsers = Get-ADUser -Filter * -Properties UserPrincipalName
#---------------------Создание логина---------------------------
#чтобы транслейтить имя надо написать: $Транслит = Translit($имя)
$Имя_пользователя = Translit($Имя[0] + "." + $Фамилия)
$Отображаемое_имя = "$Фамилия $Имя"
#---------------Проверка на однофамильцев-----------------
while ($adUsers.SamAccountName -like "*$Имя_пользователя*") { $count = $count + 1 $Имя_пользователя = Translit($Имя[0] + $count + "." + $Фамилия) $Отображаемое_имя = "$Фамилия $Имя $count"
#---------------Создание почты на основе логина-----------------
$Эл_почта = $Имя_пользователя + "@mail"Теперь самое важное – создание учетной записи и контакта, Powershell не даст просто присвоить учетной записи пароль, для этого строку необходимо сначала преобразовать в защищенную.
#Пользователь
$Пароль = ConvertTo-SecureString -String "###Пароль###" -AsPlainText -Force
New-ADUser -SamAccountName "$Имя_пользователя" -UserPrincipalName "$Имя_пользователя" -Name $Отображаемое_имя -DisplayName $Отображаемое_имя -GivenName "$Имя" -Surname "$Фамилия" -Title "$Должность" -Mobile "$Мобильный_телефон" -OfficePhone "$Номер_телефона" -EmailAddress "$Эл_почта" -Department "$Отдел" -Company "$Организация" -AccountPassword $Пароль -Enabled $true -Path "OU=ТЕСТ,DC=domen,DC=local"
#Контакт
New-ADObject -Name "$Отображаемое_имя" -Type Contact -Path "OU=ТЕСТ_КОНТАКТЫ,OU=ТЕСТ,DC=domen,DC=local" -OtherAttributes @{DisplayName = $Отображаемое_имя; GivenName = "$Имя"; Sn = "$Фамилия"; Mobile = "$Мобильный_телефон"; Mail = "$Эл_почта";telephoneNumber = "444"; Title = "$Должность"; Department = "$Отдел"; Company = "$Организация"}$Исходные_группы = Get-ADUser $Имя_пользователя_для_копирования_групп -Properties MemberOf | Select-Object -ExpandProperty MemberOf
foreach ($группы in $Исходные_группы) { Add-ADGroupMember -Identity $группы -Members $Имя_пользователя
}На этом действия на сервере заканчиваются, закрываем скобки, и переходим в локальную сессию, в качестве отчета я отправлю письмо-ответ на адрес отправителя, для этого получаем переменные из объекта сессии и составляем письмо, после чего перемещаем письмо в папку “Исполнено”.
#Получение значений из сессии
$Имя_учетки = $Переменные.GetValue(0)
$Почта = $Переменные.GetValue(1)
#Ответное письмо
$Ответ = $Письмо.ReplyAll()
$Ответ.Body = @"
$Фамилия $Имя $Отчество
$Отдел
$Должность
$Организация
$Имя_учетки
$Почта
$Мобильный_телефон
$Номер_телефона
"@
$Ответ.Send( )
$Письмо.Move($Исполнено)После завершения цикла, закрываем сессию с сервером и закрываем Outlook, через 10 секунд чтобы письма успели отправиться.
#Завершение сессии
Remove-PSSession -Session $Сессия
#Завершение Outlook
Start-Sleep -Seconds 10
Get-Process | Where-Object {$_.ProcessName -eq "OUTLOOK"} | Stop-ProcessОбразец моей заявки:
Заявка в IT - Новый сотрудник от 12.04.2024 10:34:49
Описание: Фамилия: Жданов
Имя: Дмитрий
Отчество: Юрьевич
Отдел: Служба Качества
Должность: Контролер пищевой продукции
Организация: АО "Агрофирма "Бунятино"
Подразделение: -
Номер телефона:
Мобильный телефон: -
Пользователь для копирования:Полный листинг кода:
#----------------Создание сессии------------------------
$Сессия = New-PSSession -ComputerName ServerAD
#-------------------------Чтение почты-----------------------------
#Завершение Outlook
Get-Process | Where-Object {$_.ProcessName -eq "OUTLOOK"} | Stop-Process
Start-Sleep -Seconds 10
# Создание объекта Outlook
$outlook = New-Object -ComObject Outlook.Application
# Получение коллекции папок
$folders = $outlook.Session.Folders.Item("auto-user@agro-holding.ru").Folders
# Выбор папки "Входящие"
$Входящие = $folders.Item("Входящие")
$Исполнено = $folders.Item("Исполнено")
# Получение последнего письма
$Письма = $Входящие.Items | Sort-Object ReceivedTime -Descending
#-------------------------Рабочий алгоритм-----------------------------
#Получение значений переменных из письма
foreach ($Письмо in $Письма) {
$lines = $Письмо.Body -split "`n"
#Условие чтения письма
if ($lines[0].Substring(0, 29) -ne "Заявка в IT - Новый сотрудник") {continue}
$Дата_заявки = $lines[0].Substring(32).Trim()
$Фамилия = $lines[2].Substring(18).Trim()
$Имя = $lines[4].Substring(4).Trim()
$Отчество = $lines[6].Substring(9).Trim()
$Отдел = $lines[8].Substring(6).Trim()
$Должность = $lines[10].Substring(10).Trim()
$Организация = $lines[12].Substring(12).Trim()
$Подразделение = $lines[14].Substring(14).Trim()
$Номер_телефона = $lines[16].Substring(15).Trim()
$Мобильный_телефон = $lines[18].Substring(18).Trim()
$Имя_пользователя_для_копирования_групп = $lines[20].Substring(29).Trim()
#---------------Основная команда создания пользователя на удаленном сервере-----------------
$Переменные = Invoke-Command -Session $Сессия -ScriptBlock { param($Фамилия, $Имя, $Отчество, $Отдел, $Должность, $Организация, $Подразделение, $Номер_телефона, $Мобильный_телефон, $Имя_пользователя_для_копирования_групп)
#---------------Функция транслита-----------------
#Транслит имени
function global:Translit {
param([string]$inString)
$Translit = @{
[char]'а' = "a"
[char]'А' = "a"
[char]'б' = "b"
[char]'Б' = "b"
[char]'в' = "v"
[char]'В' = "v"
[char]'г' = "g"
[char]'Г' = "g"
[char]'д' = "d"
[char]'Д' = "d"
[char]'е' = "e"
[char]'Е' = "e"
[char]'ё' = "yo"
[char]'Ё' = "yo"
[char]'ж' = "zh"
[char]'Ж' = "zh"
[char]'з' = "z"
[char]'З' = "z"
[char]'и' = "i"
[char]'И' = "i"
[char]'й' = "j"
[char]'Й' = "j"
[char]'к' = "k"
[char]'К' = "k"
[char]'л' = "l"
[char]'Л' = "l"
[char]'м' = "m"
[char]'М' = "m"
[char]'н' = "n"
[char]'Н' = "n"
[char]'о' = "o"
[char]'О' = "o"
[char]'п' = "p"
[char]'П' = "p"
[char]'р' = "r"
[char]'Р' = "r"
[char]'с' = "s"
[char]'С' = "s"
[char]'т' = "t"
[char]'Т' = "t"
[char]'у' = "u"
[char]'У' = "u"
[char]'ф' = "f"
[char]'Ф' = "f"
[char]'х' = "h"
[char]'Х' = "h"
[char]'ц' = "c"
[char]'Ц' = "c"
[char]'ч' = "ch"
[char]'Ч' = "ch"
[char]'ш' = "sh"
[char]'Ш' = "sh"
[char]'щ' = "sch"
[char]'Щ' = "sch"
[char]'ъ' = ""
[char]'Ъ' = ""
[char]'ы' = "y"
[char]'Ы' = "y"
[char]'ь' = ""
[char]'Ь' = ""
[char]'э' = "e"
[char]'Э' = "e"
[char]'ю' = "yu"
[char]'Ю' = "yu"
[char]'я' = "ya"
[char]'Я' = "ya"
}
$outCHR=""
foreach ($CHR in $inCHR = $inString.ToCharArray())
{
if ($Translit[$CHR] -cne $Null )
{$outCHR += $Translit[$CHR]}
else
{$outCHR += $CHR}
}
Write-Output $outCHR
}
$count = 0
#---------------Получаем список пользователей AD-----------------
$adUsers = Get-ADUser -Filter * -Properties UserPrincipalName
#---------------------Получение логина---------------------------
#чтобы транслейтить имя надо написать: $Транслит = Translit($имя)
$Имя_пользователя = Translit($Имя[0] + "." + $Фамилия)
$Отображаемое_имя = "$Фамилия $Имя"
#---------------Проверка на однофамильцев-----------------
while ($adUsers.SamAccountName -like "*$Имя_пользователя*") { $count = $count + 1 $Имя_пользователя = Translit($Имя[0] + $count + "." + $Фамилия) $Отображаемое_имя = "$Фамилия $Имя $count"
}
#---------------Создание почты на основе логина-----------------
$Эл_почта = $Имя_пользователя + "@почта"
#---------------------Добавиление в AD-----------------------------
#Пользователь
$Пароль = ConvertTo-SecureString -String "пароль" -AsPlainText -Force
New-ADUser -SamAccountName "$Имя_пользователя" -UserPrincipalName "$Имя_пользователя" -Name $Отображаемое_имя -DisplayName $Отображаемое_имя -GivenName "$Имя" -Surname "$Фамилия" -Title "$Должность" -Mobile "$Мобильный_телефон" -OfficePhone "$Номер_телефона" -EmailAddress "$Эл_почта" -Department "$Отдел" -Company "$Организация" -AccountPassword $Пароль -Enabled $true -Path "OU=ТЕСТ,DC=bun,DC=local"
#Контакт
New-ADObject -Name "$Отображаемое_имя" -Type Contact -Path "OU=ТЕСТ_КОНТАКТЫ,OU=ТЕСТ,DC=bun,DC=local" -OtherAttributes @{DisplayName = $Отображаемое_имя; GivenName = "$Имя"; Sn = "$Фамилия"; Mobile = "$Мобильный_телефон"; Mail = "$Эл_почта";telephoneNumber = "444"; Title = "$Должность"; Department = "$Отдел"; Company = "$Организация"}
#-----------Копируем группы пользователя из контейнера-------------
$Исходные_группы = Get-ADUser $Имя_пользователя_для_копирования_групп -Properties MemberOf | Select-Object -ExpandProperty MemberOf
foreach ($группы in $Исходные_группы) { Add-ADGroupMember -Identity $группы -Members $Имя_пользователя
}
#-----------Возвращение переменных из сессии для ответного письма-------------
return $Имя_пользователя, $Эл_почта, $Фамилия, $Имя, $Отчество, $Отдел, $Должность, $Организация, $Подразделение, $Номер_телефона, $Мобильный_телефон, $Имя_пользователя_для_копирования_групп
} -ArgumentList $Фамилия, $Имя, $Отчество, $Отдел, $Должность, $Организация, $Подразделение, $Номер_телефона, $Мобильный_телефон, $Имя_пользователя_для_копирования_групп
#Получение значений из сессии
$Имя_учетки = $Переменные.GetValue(0)
$Почта = $Переменные.GetValue(1)
#Ответное письмо
$Ответ = $Письмо.ReplyAll()
$Ответ.Body = @"
$Фамилия $Имя $Отчество
$Отдел
$Должность
$Организация
$Имя_учетки
$Почта
$Мобильный_телефон
$Номер_телефона
"@
$Ответ.Send( )
$Письмо.Move($Исполнено)
}
#Завершение Outlook
Start-Sleep -Seconds 10
Get-Process | Where-Object {$_.ProcessName -eq "OUTLOOK"} | Stop-Process
#Завершение сессии
Remove-PSSession -Session $СессияНадеюсь вам помогла моя статья, я постарался максимально понятно разделить код на составные части чтобы его части можно было поменять на собственные.




