PowerShell is an automation tool developed and released by Microsoft in 2006 to replace the Command Line and its batch files, in addition to all the functionality of cmd – Powershell acquired its own scripting language with support for classes, objects, variables, etc. Essentially, with its help you can access all the functionality of Windows and Windows Server as objects and perform actions with them. In this article I will tell you my experience of how I automated the creation of users in a domain from application letters in Outlook on a remote AD server.
All scheduled tasks in Windows can be viewed in the “Task Scheduler”; it is possible to automate Windows both with its help and purely using Powershell, in order to display all current tasks that need to be performed:
Get-ScheduledJob
To display those scheduled only using Powershell, use the command below, since tasks created in Powershell are stored in a separate directory, you just need to read them:
Get-ChildItem $HOME\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs
To create a task, you need to run the following command, passing the script to be executed in square brackets:
$Условие = New-JobTrigger -Daily -At 12AM
Register-ScheduledJob -Name NewAD_User -ScriptBlock {######} -Trigger $Условие
Let’s look at how interaction with Outlook occurs, and I’ll immediately note that to perform actions with mail, you need to close the open application, otherwise the commands will not be executed.
#Завершение 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
In this code, I get a list of letters sorted by date from the Inbox folder and the address of the Completed folder where I plan to move the letters after executing the script.
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()
In this fragment, a loop begins that goes through each letter, converts it into a list of strings and gets values from it. At the beginning, I added a simple check in case a random letter lands on the selected mailbox. Next, the most important thing is creating an account, and in my case a contact, on a remote server, using the Invoke-Command command:
$Сессия = New-PSSession -ComputerName ###Сетевое имя или IP-адресс компа###
$Переменные = Invoke-Command -Session $Сессия -ScriptBlock {
param(####Все ваши переменные через запятую###)
команды на удаленном компе
return Переменные которые вернуться в массив обьектов "$Переменные"
} -ArgumentList ###Переменные через запятую которые вы передали в параметры###
The variable “$Variables” will accept, after executing the command on the remote computer, the variables specified in return – they will be needed to send the report letter.
Next, I convert the first and last name into a login, check namesakes and, if necessary, add a number to the login (Translit function at the end of the article in the full listing)
#Транслит имени
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"
Now the most important thing is creating an account and contact. Powershell will not allow you to simply assign a password to the account; to do this, the string must first be converted into a secure one.
#Пользователь
$Пароль = 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 = "$Организация"}
Now we copy for the user of the security group; for this, in the last line of the application, we take the login of the account to be copied, which is contained in the same container
$Исходные_группы = Get-ADUser $Имя_пользователя_для_копирования_групп -Properties MemberOf | Select-Object -ExpandProperty MemberOf
foreach ($группы in $Исходные_группы) {
Add-ADGroupMember -Identity $группы -Members $Имя_пользователя
}
This is where the actions on the server end, close the brackets and go to the local session. As a report, I will send a response letter to the sender’s address. To do this, we get the variables from the session object and compose the letter, after which we move the letter to the “Completed” folder.
#Получение значений из сессии
$Имя_учетки = $Переменные.GetValue(0)
$Почта = $Переменные.GetValue(1)
#Ответное письмо
$Ответ = $Письмо.ReplyAll()
$Ответ.Body = @"
$Фамилия $Имя $Отчество
$Отдел
$Должность
$Организация
$Имя_учетки
$Почта
$Мобильный_телефон
$Номер_телефона
"@
$Ответ.Send( )
$Письмо.Move($Исполнено)
After the cycle is completed, close the session with the server and close Outlook, after 10 seconds so that the letters can be sent.
#Завершение сессии
Remove-PSSession -Session $Сессия
#Завершение Outlook
Start-Sleep -Seconds 10
Get-Process | Where-Object {$_.ProcessName -eq "OUTLOOK"} | Stop-Process
Sample of my application:
Заявка в IT - Новый сотрудник от 12.04.2024 10:34:49
Описание: Фамилия: Жданов
Имя: Дмитрий
Отчество: Юрьевич
Отдел: Служба Качества
Должность: Контролер пищевой продукции
Организация: АО "Агрофирма "Бунятино"
Подразделение: -
Номер телефона:
Мобильный телефон: -
Пользователь для копирования:
Full code listing:
#----------------Создание сессии------------------------
$Сессия = 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("[email protected]").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 $Сессия
I hope my article helped you, I tried to divide the code into its component parts as clearly as possible so that its parts could be changed to your own.
Acknowledgement and Usage Notice
The editorial team at TechBurst Magazine acknowledges the invaluable contribution of the author of the original article that forms the foundation of our publication. We sincerely appreciate the author’s work. All images in this publication are sourced directly from the original article, where a reference to the author’s profile is provided as well. This publication respects the author’s rights and enhances the visibility of their original work. If there are any concerns or the author wishes to discuss this matter further, we welcome an open dialogue to address potential issues and find an amicable resolution. Feel free to contact us through the ‘Contact Us’ section; the link is available in the website footer.