Что такое репозиторий
Репозиторий — папка с файлами вашего проекта на сервере GitHub. Так вы можете работать с проектом откуда угодно, не переживая, что какие-то файлы потеряются — все данные останутся в репозитории.
Если над проектом работает несколько программистов, сначала создаётся мастер-репозиторий — это общий репозиторий с рабочей версией проекта. А каждый программист работает с форком — то есть полной копией мастер-репозитория. В форке вы можете безнаказанно менять код и не бояться что-то сломать в основной версии проекта.
Задача: форкнуть репозиторий в GitHub, создать ветку и работать с кодом.

Сразу появляется много вопросов — что такое GitHub, какие для этого нужны команды, зачем, а главное, как всем этим пользоваться? Давайте разберёмся.
Больше из рубрики Git: введение, основные команды, решение проблем.
Когда мы пишем код, мы постоянно туда что-то добавляем, удаляем, и иногда всё может ломаться. Поэтому перед любыми изменениями стоит сделать копию проекта. Если собирать проекты в папки с именами проект1, проект1_финали проект2_доделка, вы быстро запутаетесь и точно что-нибудь потеряете. Поэтому для работы с кодом используют системы контроля версий.
Система контроля версий — программа, которая хранит разные версии одного документа, позволяет переключаться между ними, вносить и отслеживать изменения. Таких систем много и все они работают по принципу компьютерной игры, где вы можете вернуться к месту сохранения, если что-то пошло не так.
Git — самая популярная система контроля версий. С Git можно работать через командную строку (или терминал). В каждой системе своя встроенная программа для работы с командной строкой. В Windows это PowerShell или cmd, а в Linux или macOS — Terminal. Вместо встроенных программ можно использовать любую другую — например, Git Bash в Windows или iTerm2 для macOS.
Как работает терминал: мы вводим команду и получаем ответ компьютера — или всё получилось, или где-то ошибка, или нужно ввести что-то ещё — например, пароль. Поэтому большая часть этой инструкции состоит из команд для терминала. Сначала будет непривычно, но вам понравится.
Но давайте по порядку — установим Git на компьютер.
Если скрипт не работает на некоторых ПК с Windows 7 и Windows 11, это может быть вызвано различиями в настройках или правах доступа. Пожалуйста, попробуйте следующие рекомендации:
1. Проверьте права доступа: Убедитесь, что у пользователя, запускающего скрипт, есть достаточные права доступа для чтения файлов на рабочем столе и записи на диск C.
2. Проверьте путь к файлу: Убедитесь, что путь к файлу “qwerty.zip” указан корректно и что файл действительно существует на рабочем столе.
3. Запустите скрипт с правами администратора: Попробуйте запустить скрипт с правами администратора, особенно на Windows 7, где могут потребоваться дополнительные разрешения.
4. Используйте PowerShell: Вместо batch-скрипта вы можете попробовать использовать скрипт на PowerShell, который может быть более совместим с разными версиями Windows. Вот пример PowerShell скрипта для копирования файла “qwerty.zip” с рабочего стола на диск C:
$source = "$env:USERPROFILE\Desktop" $destination = "C:\" $fileToFind = "qwerty.zip" Get-ChildItem -Path $source -Recurse | Where-Object { $_.Name -eq $fileToFind } | ForEach-Object { Copy-Item $_.FullName $destination }Попробуйте эти рекомендации и сообщите, если у вас возникнут дополнительные вопросы или проблемы.
Для того чтобы запустить скрипт на PowerShell из batch-файла, вам нужно добавить команду вызова PowerShell с вашим скриптом. Вот как это можно сделать:
1. Создайте новый batch-файл (например, script.bat) и откройте его в текстовом редакторе.
2. Добавьте следующую строку в ваш batch-файл, чтобы вызвать PowerShell и выполнить ваш скрипт:
powershell.exe -ExecutionPolicy Bypass -File "путь_к_вашему_скрипту.ps1"Замените “путьквашему_скрипту.ps1″ на путь к вашему скрипту на PowerShell (например, “C:\путь\к\вашему\скрипту.ps1”).
3. Сохраните изменения в batch-файле.
Теперь, когда вы запустите batch-файл, он вызовет PowerShell и выполнит ваш скрипт на PowerShell. Пожалуйста, убедитесь, что в вашем скрипте на PowerShell нет ошибок и он работает корректно.
Попробуйте это решение и сообщите, если у вас возникнут дополнительные вопросы или проблемы.
Для того чтобы запустить скрипт на PowerShell из batch-файла, вам нужно добавить команду вызова PowerShell с вашим скриптом. Вот как это можно сделать:
1. Создайте новый batch-файл (например, script.bat) и откройте его в текстовом редакторе.
2. Добавьте следующую строку в ваш batch-файл, чтобы вызвать PowerShell и выполнить ваш скрипт:
powershell.exe -ExecutionPolicy Bypass -File "путь_к_вашему_скрипту.ps1"Замените “путьквашему_скрипту.ps1″ на путь к вашему скрипту на PowerShell (например, “C:\путь\к\вашему\скрипту.ps1”).
3. Сохраните изменения в batch-файле.
Теперь, когда вы запустите batch-файл, он вызовет PowerShell и выполнит ваш скрипт на PowerShell. Пожалуйста, убедитесь, что в вашем скрипте на PowerShell нет ошибок и он работает корректно.
Попробуйте это решение и сообщите, если у вас возникнут дополнительные вопросы или проблемы.
Для того чтобы внутри batch-файла отработал скрипт PowerShell без необходимости создания отдельного файла .ps1, вы можете вставить сам скрипт PowerShell прямо внутрь batch-файла. Вот пример того, как это можно сделать:
@echo off
set "source=%USERPROFILE%\Desktop"
set "destination=C:\"
set "fileToFind=qwerty.zip"
echo $source = "%source%" > tmp.ps1
echo $destination = "%destination%" >> tmp.ps1
echo $fileToFind = "%fileToFind%" >> tmp.ps1
echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1
echo Copy-Item $_.FullName $destination >> tmp.ps1
echo } >> tmp.ps1
powershell.exe -ExecutionPolicy Bypass -File tmp.ps1
del tmp.ps1В этом примере скрипт PowerShell вставлен внутрь batch-файла. Он создает временный файл tmp.ps1, в который записывает скрипт PowerShell, а затем запускает PowerShell для выполнения этого скрипта. После выполнения скрипта PowerShell временный файл удаляется.
Попробуйте использовать этот подход и проверьте, работает ли он для вашего случая. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать.
Для того чтобы внутри batch-файла отработал скрипт PowerShell без необходимости создания отдельного файла .ps1, вы можете вставить сам скрипт PowerShell прямо внутрь batch-файла. Вот пример того, как это можно сделать:
@echo off set "source=%USERPROFILE%\Desktop" set "destination=C:\" set "fileToFind=qwerty.zip" echo $source = "%source%" > tmp.ps1 echo $destination = "%destination%" >> tmp.ps1 echo $fileToFind = "%fileToFind%" >> tmp.ps1 echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1 echo Copy-Item $_.FullName $destination >> tmp.ps1 echo } >> tmp.ps1 powershell.exe -ExecutionPolicy Bypass -File tmp.ps1 del tmp.ps1В этом примере скрипт PowerShell вставлен внутрь batch-файла. Он создает временный файл tmp.ps1, в который записывает скрипт PowerShell, а затем запускает PowerShell для выполнения этого скрипта. После выполнения скрипта PowerShell временный файл удаляется.
Попробуйте использовать этот подход и проверьте, работает ли он для вашего случая. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать.
Для того чтобы продолжить выполнение batch-файла после отработки скрипта PowerShell без изменения вида консоли, можно использовать оператор call для запуска скрипта PowerShell. Вот пример того, как это можно сделать:
@echo off
set "source=%USERPROFILE%\Desktop"
set "destination=C:\"
set "fileToFind=qwerty.zip"
echo $source = "%source%" > tmp.ps1
echo $destination = "%destination%" >> tmp.ps1
echo $fileToFind = "%fileToFind%" >> tmp.ps1
echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1
echo Copy-Item $_.FullName $destination >> tmp.ps1
echo } >> tmp.ps1
call powershell.exe -ExecutionPolicy Bypass -File tmp.ps1
del tmp.ps1
REM Продолжение batch-файла
echo Скрипт PowerShell отработал. Продолжаем выполнение batch-файла. В этом примере после выполнения скрипта PowerShell с помощью call, выполнение batch-файла продолжится без изменения вида консоли. После удаления временного файла tmp.ps1, можно добавить любые дополнительные команды или скрипты для продолжения работы batch-файла.
Попробуйте использовать этот подход и проверьте, работает ли он для вашего случая. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать.
Для того чтобы продолжить выполнение batch-файла после отработки скрипта PowerShell без изменения вида консоли, можно использовать оператор
callдля запуска скрипта PowerShell. Вот пример того, как это можно сделать:@echo off set "source=%USERPROFILE%\Desktop" set "destination=C:\" set "fileToFind=qwerty.zip" echo $source = "%source%" > tmp.ps1 echo $destination = "%destination%" >> tmp.ps1 echo $fileToFind = "%fileToFind%" >> tmp.ps1 echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1 echo Copy-Item $_.FullName $destination >> tmp.ps1 echo } >> tmp.ps1 call powershell.exe -ExecutionPolicy Bypass -File tmp.ps1 del tmp.ps1 REM Продолжение batch-файла echo Скрипт PowerShell отработал. Продолжаем выполнение batch-файла.В этом примере после выполнения скрипта PowerShell с помощью
call, выполнение batch-файла продолжится без изменения вида консоли. После удаления временного файла tmp.ps1, можно добавить любые дополнительные команды или скрипты для продолжения работы batch-файла.Попробуйте использовать этот подход и проверьте, работает ли он для вашего случая. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать.
Если скрипт PowerShell меняет вид консольного окна batch-файла, это может быть вызвано тем, что PowerShell запускается в новом окне по умолчанию. Для того чтобы избежать этого, можно попробовать запустить PowerShell скрипт в том же окне консоли. Вот как это можно сделать:
@echo off
set "source=%USERPROFILE%\Desktop"
set "destination=C:\"
set "fileToFind=qwerty.zip"
echo $source = "%source%" > tmp.ps1
echo $destination = "%destination%" >> tmp.ps1
echo $fileToFind = "%fileToFind%" >> tmp.ps1
echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1
echo Copy-Item $_.FullName $destination >> tmp.ps1
echo } >> tmp.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { .\tmp.ps1 }"
del tmp.ps1
REM Продолжение batch-файла
echo Скрипт PowerShell отработал. Продолжаем выполнение batch-файла.Попробуйте использовать этот подход и проверьте, помог ли он избежать изменения вида консоли. Если проблема остается, пожалуйста, уточните, какие именно изменения происходят в консоли после выполнения скрипта PowerShell.
Если скрипт PowerShell меняет вид консольного окна batch-файла, это может быть вызвано тем, что PowerShell запускается в новом окне по умолчанию. Для того чтобы избежать этого, можно попробовать запустить PowerShell скрипт в том же окне консоли. Вот как это можно сделать:
@echo off set "source=%USERPROFILE%\Desktop" set "destination=C:\" set "fileToFind=qwerty.zip" echo $source = "%source%" > tmp.ps1 echo $destination = "%destination%" >> tmp.ps1 echo $fileToFind = "%fileToFind%" >> tmp.ps1 echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1 echo Copy-Item $_.FullName $destination >> tmp.ps1 echo } >> tmp.ps1 powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { .\tmp.ps1 }" del tmp.ps1 REM Продолжение batch-файла echo Скрипт PowerShell отработал. Продолжаем выполнение batch-файла.Попробуйте использовать этот подход и проверьте, помог ли он избежать изменения вида консоли. Если проблема остается, пожалуйста, уточните, какие именно изменения происходят в консоли после выполнения скрипта PowerShell.
Если скрипт PowerShell изменяет параметры консоли batch-файла, то это может быть вызвано тем, что PowerShell по умолчанию настраивает свои параметры консоли при запуске. Для того чтобы избежать этого, можно сохранить текущие параметры консоли перед запуском PowerShell и восстановить их после выполнения скрипта. Вот пример того, как это можно сделать:
@echo off
:: Сохраняем текущие параметры консоли
for /f "tokens=1,2 delims= " %%a in ('mode con ^| findstr Columns') do set original_columns=%%b
for /f "tokens=1,2 delims= " %%a in ('mode con ^| findstr Lines') do set original_lines=%%b
for /f "tokens=1,2 delims= " %%a in ('reg query "HKCU\Console" /v FaceName ^| find "REG_SZ"') do set original_font=%%b
for /f "tokens=1,2 delims= " %%a in ('reg query "HKCU\Console" /v FontSize ^| find "REG_DWORD"') do set original_fontsize=%%b
:: Ваш скрипт PowerShell
set "source=%USERPROFILE%\Desktop"
set "destination=C:\"
set "fileToFind=qwerty.zip"
echo $source = "%source%" > tmp.ps1
echo $destination = "%destination%" >> tmp.ps1
echo $fileToFind = "%fileToFind%" >> tmp.ps1
echo Get-ChildItem -Path $source -Recurse ^| Where-Object { $_.Name -eq $fileToFind } ^| ForEach-Object { >> tmp.ps1
echo Copy-Item $_.FullName $destination >> tmp.ps1
echo } >> tmp.ps1
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "& { .\tmp.ps1 }"
del tmp.ps1
:: Восстанавливаем параметры консоли
mode con cols=%original_columns% lines=%original_lines%
reg add "HKCU\Console" /v FaceName /t REG_SZ /d %original_font% /f
reg add "HKCU\Console" /v FontSize /t REG_DWORD /d %original_fontsize% /f
REM Продолжение batch-файла
echo Скрипт PowerShell отработал. Продолжаем выполнение batch-файла.Этот скрипт сохраняет текущие параметры консоли (количество столбцов, количество строк, шрифт и размер шрифта), запускает скрипт PowerShell, а затем восстанавливает исходные параметры консоли. Попробуйте использовать этот подход и проверьте, помог ли он сохранить параметры консоли без изменений после выполнения скрипта PowerShell.
![]()
<# : @echo off setlocal powershell /noprofile /executionpolicy bypass^ "&{[ScriptBlock]::Create((Get-Content '%~f0') -join [Char]10).Invoke(@(&{$args}%*))}" endlocal exit /b
#>
# здесь ваш код PowershellА что именно он изменяет и на какой версии ОС? У меня, например, размер окон разный, но ничего не изменяется.
Попробуйте удалить подразделы ключа реестра:
HKEY_CURRENT_USER\Console
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 $СессияНадеюсь вам помогла моя статья, я постарался максимально понятно разделить код на составные части чтобы его части можно было поменять на собственные.
Регистрируемся на GitHub
GitHub (или Гитхаб) — веб-сервис на основе Git, который помогает совместно разрабатывать IT-проекты. На Гитхабе разработчики публикуют свой и редактируют чужой код, комментируют проекты и следят за новостями других пользователей.
Профиль на Гитхабе и все проекты в нём — ваше публичное портфолио разработчика, поэтому нужно завести профиль, если у вас его ещё нет.
- Зайдите на сайт https://github.com и нажмите кнопку Sign up.
- Введите имя пользователя (понадобится в дальнейшей работе), адрес электронной почты (такой же, как при настройке Git) и пароль.
- На почту придёт код активации — введите на сайте.
- Появится окно с выбором тарифного плана. Если вы пользуетесь Гитхабом для учёбы, то укажите, что профиль нужен только для вас и вы студент.
- Опросы и выбор интересов можно пропустить.
На этом всё — вы зарегистрировались и у вас есть собственный профиль.
Отправляем изменения на GitHub — git push
Сохранённые изменения пока не видны коллегам, потому что находятся в нашем локальном репозитории. Нужно отправить коммиты на GitHub. Для этого введите команду
git push origin название-текущей-веткиГде origin означает репозиторий на компьютере, то есть ваш форк. Слово origin — часть команды, не меняйте это название на своё.

Добавляем SSH-ключ на GitHub
Это нужно сделать, чтобы GitHub вас узнавал.
Перейдите на страницу для работы с ключами в вашем профиле на GitHub и нажмите кнопку New SSH key.

В поле Title нужно добавить название нового ключа. Например, если вы используете Mac, вы можете назвать ключ MacBook Air, или, если ключ для курсов Академии, то Academy. А ключ, который вы скопировали на прошлом шаге, вставьте в поле Key.

Не копируйте ключ со скриншота — он уже не работает.
Теперь нажмите кнопку Add SSH key и, если потребуется, введите свой пароль от GitHub, чтобы подтвердить сохранение. Если всё сделано верно, новый ключ появится в списке на странице https://github.com/settings/keys.

Теперь мы можем поработать с проектом в репозитории.
Создаём новую ветку — git branch
Откройте терминал и введите команду
git branchОна показывает список веток, с которыми мы работаем в проекте, и выделяет текущую. Если мы находимся в master , то создаём новую ветку командой
git checkout -b имя-новой-ветки.➜ 1173761-device-34 git:(master) git checkout -b task1
Переключено на новую ветку «task1»
➜ 1173761-device-34 git:(task1)Если текущая ветка не master, переключитесь на неё с помощью команды checkout. После git checkout надо указать название нужной ветки.
git checkout masterМы делаем это, чтобы новая ветка содержала свежую рабочую версию проекта. Если вы ошиблись в названии, например, допустили опечатку, вы можете изменить название ветки с помощью команды:
git branch -m старое-имя-ветки новое-имя-ветки.Устанавливаем и настраиваем Git
Linux. Установите Git через встроенный менеджер пакетов. Если у вас Ubuntu, используйте команду sudo apt-get install git. Команды для других дистрибутивов можно посмотреть здесь.
Как проверить, что Git установился
Откройте терминал и введите команду
git --versionЕсли Git установлен, то вы увидите номер версии, например, 2.35.1.
Настраиваем Git
Теперь нужно ввести имя и адрес электронной почты, чтобы ваши действия в Git были подписаны, а ещё для привязки к GitHub.
Добавить имя (введите его внутри кавычек):
git config --global user.name "ваше имя"git config --global user.email email@example.comОпция --global значит, что имя и почта будут использоваться для всех ваших действий в Git. Если вы хотите менять эту информацию для разных проектов, то вводите эти же команды, только без опции --global.
Добавляем SSH-ключ в ssh-agent
ssh-agent — программа для хранения и управления SSH-ключами. Давайте запустим её и добавим туда наш SSH-ключ. Запускаем командой eval "$(ssh-agent -s)":
eval "$(ssh-agent -s)"Если в ответ терминал покажет надпись «Agent pid» и число — значит, всё ок, агент запущен.
Теперь добавим наш ключ командой.
ssh-add ~/.ssh/id_ed25519Если у вашего ключа другое имя, замените название id_ed25519 именем файла с ключом (это правило применяется и дальше в инструкции). Если вы устанавливали пароль на ключ, введите его два раза после ввода команды ssh-add (терминал подскажет, когда это сделать).
Теперь, если всё хорошо, появится надпись Identity added — значит, можно переходить к добавлению ключа на GitHub.
Клонируем форк на компьютер — git clone
Открываем терминал и переходим в папку с будущим проектом — для этого используем команду cd your-project. Если вы хотите, чтобы проект лежал в папке device, введите
cd deviceЕсли такой папки на компьютере нет, то сначала введите md your-project, чтобы создать эту папку, а затем cd your-project. Когда перейдёте в папку, введите команду git clone для клонирования репозитория:
git clone git@github.com:your-nickname/your-project.gitЗамените your-nickname на ваше имя пользователя на GitHub, а your-project на название проекта. Проще всего их найти прямо наверху страницы репозитория.
Если вы правильно настроили SSH-ключи, Git скопирует репозиторий на ваш компьютер.
➜ device git clone git@github.com:academy-student/1173761-device-34.git
Клонирование в «1173761-device-34»…
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 15 (delta 0), reused 15 (delta 0), pack-reused 0
Получение объектов: 100% (15/15), 145.07 КиБ | 900.00 КиБ/с, готово.Если вы видите ошибку Error: Permission denied (publickey), скорее всего, вы ошиблись в настройке SSH-ключа. Вернитесь в этот раздел инструкции и повторите процесс настройки.
Кстати, если вы хотите, чтобы название папки с проектом у вас на компьютере отличалось от имени репозитория, можете дополнить команду клонирования, добавив в конце другое название:
git clone git@github.com:_your-nickname_/_your-project_.git folder_nameТеперь на вашем компьютере в папке your_project или в той, название которой вы указали, находится полная копия репозитория c GitHub.
В каждом репозитории есть как минимум одна основная ветка, которую создаёт сам Git — она называется master. Обычно в ней хранят проверенную версию программы без ошибок.
А если вы хотите исправить ошибку в коде или добавить что-то в проект, но не хотите сломать код в основной ветке, нужно создать новую ветку из master и работать из неё. Каждая ветка — что-то вроде второстепенной дороги, которая затем снова соединится с основной.
Сохраняем изменения — git add
После того, как вы создали ветку и поработали в ней у себя на компьютере, нужно сохранить результат, чтобы появился в репозитории и не пропал.
Если вы хотите сохранить изменения не во всех файлах, для начала введите команду git status. Она покажет текущее состояние в вашей ветке, а именно список с названиями изменённых файлов, если они есть, и укажет на те, которые ожидают записи и сохранения (обычно они выделены красным цветом).

Чтобы сохранить все изменения разом, используйте команду
git add -AЧтобы сохранить изменения только отдельных файлов, укажите их имена вручную. Например, если вы изменили файл index.html, введите
git add index.htmlЕсли название очень длинное, вы начните его писать, нажмите Tab и терминал сам предложит продолжение пути к файлу.
Делаем форк мастер-репозитория
Заходим в нужный репозиторий и нажимаем на «вилку» с надписью fork.

Появится окно Create a new fork — проверьте, что он называется так, как вам нужно, и жмите кнопку Create fork. Через пару секунд всё готово.

Создаём новый SSH-ключ
Откройте терминал и скопируйте туда эту команду. Не забудьте подставить в кавычки почту, на которую вы регистрировались на Гитхабе.
ssh-keygen -t ed25519 -C "your_email@example.com"ed25519 — это алгоритм для генерации ключей. Если ваша система не поддерживает алгоритм ed25519 (и вы увидели ошибку), используйте немного другую команду с алгоритмом rsa:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"Терминал спросит, куда сохранить ключ. Если не хотите менять имя файла, которое предлагает терминал, просто нажмите Enter.
> Generating public/private имя-ключа key pair.
> Enter a file in which to save the key (/c/Users/ваш-профиль/.ssh/id_имя-ключа):*[Press enter]*Теперь нужно добавить пароль, которым будет зашифрован ваш ключ. Это стоит сделать, иначе в дальнейшем могут быть проблемы с настройкой, да и так просто безопаснее.
В результате создаётся новый SSH-ключ, привязанный к вашей электронной почте.
Создание ключа по шагам:

Устанавливаем SSH-ключи
Чтобы получить доступ к проектам на GitHub со своего компьютера и выполнять команды без постоянного ввода пароля, нужно, чтобы сервер вас узнавал. Для этого используются SSH-ключи.
SSH — протокол для безопасного соединения между компьютерами.
SSH-ключ состоит из двух частей — открытого и закрытого ключа. Открытый ключ мы отправляем на сервер. Его можно не прятать от всех и не переживать, что кто-то его украдёт, потому что без закрытого ключа он бесполезен. А вот закрытый ключ — секретная часть, доступ к нему должен быть только у вас. Это важно.
Мы будем подключаться к GitHub по SSH. Это работает так:
- Вы отправляете какую-то информацию на GitHub, который знает ваш открытый ключ.
- GitHub по открытому ключу понимает, что вы это вы, и отправляет что-то в ответ.
- Только вы можете расшифровать этот ответ, потому что только у вас есть подходящий закрытый ключ.
А чтобы подключиться к GitHub с помощью SSH-ключа, сначала нужно его создать.
Словарик
Система контроля версий — программа, которая хранит разные версии одного документа, позволяет переключаться между ними, вносить и отслеживать изменения.
Git — самая популярная система контроля версий. С Git можно работать через терминал.
Как работает терминал: мы вводим команду и получаем ответ компьютера — или всё получилось, или где-то ошибка, или нужно ввести что-то ещё.
GitHub (или Гитхаб) — веб-сервис, основанный на Git, который помогает совместно разрабатывать IT-проекты. На Гитхабе разработчики публикуют свой и редактируют чужой код, комментируют проекты и следят за новостями других пользователей.
SSH-ключ нужен, чтобы получить доступ к проектам на GitHub со своего компьютера и выполнять команды без постоянного ввода пароля, нужно, чтобы сервер нас узнавал.
ssh-agent — программа для хранения и управления SSH-ключами.
Репозиторий — папка с файлами вашего проекта на сервере GitHub или у вас на компьютере.
Мастер-репозиторий — это общий для всей команды репозиторий с рабочей версией проекта.
Форк — полная копия мастер-репозитория, в которой вы можете безопасно работать.
Пулреквест (или PR) — предложение изменить код в репозитории. PR должен проверить администратор мастер-репозитория — это может быть коллега-разработчик, техлид или наставник на курсе.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Делаем коммит — git commit
Сделать коммит — значит зафиксировать все сохранённые изменения и дать им название. Это делается с помощью команды commit
git commit -m "ваше сообщение"Текст сообщения должен быть лаконичным и вместе с этим сообщать о том, что делает коммит (внесённые изменения). Например,
- Добавляет имя наставника в Readme
- Вводит функцию сортировки изображений
- Правит ошибку в поиске городов на карте

Копируем SSH-ключ
Чтобы добавить ключ на GitHub, нужно сначала его скопировать из вашего файла командой clip. Вы не увидите ключ на экране, но он появится в буфере обмена, и его можно будет вставить на Гитхаб.
clip < ~/.ssh/id_ed25519.pubКоманда clip может не сработать на вашем компьютере, тогда есть два способа узнать ключ — простой и сложный.
Сложный способ. Найдите скрытую папку .ssh, откройте файл id_ed25519.pub в текстовом редакторе и скопируйте его содержимое.
Простой способ. Введите команду ниже и ключ появится прямо в терминале — его нужно вручную скопировать в буфер обмена. Ключ начинается с ssh-ed22519 или ssh-rsa (или похожей строки) — поэтому копируйте строку прямо с самого начала.
~ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaCZvnr4ax+Fr shklyar@htmlacademy.ruНе копируйте этот ключ из статьи — он уже не работает.
Проверяем SSH-ключи
Перед созданием нового SSH-ключа проверим, есть ли на компьютере другие ключи. Обычно они лежат в папке с названием .ssh — поэтому посмотрим, есть ли в ней что-то, с помощью команды в терминале:
ls -al ~/.sshЕсли у вас уже есть SSH-ключ, то в списке будут файлы с именами вроде id_rsa.pub, id_ecdsa.pub или id_ed25519.pub. А если терминал ругается, что директории ~/.ssh не существует, значит, у вас нет SSH-ключей. Давайте это исправим.
Создаём пулреквест
Пулреквест (или PR) — это предложение изменить код в репозитории. PR должен проверить администратор мастер-репозитория — это может быть коллега-разработчик, техлид или наставник на курсе.
Если к коду нет вопросов, пулреквест принимается. Если нужно что-то исправить — отклоняется, и придётся исправить код и снова пройти цепочку git add — git commit — git push. Если вы и дальше работаете в той же ветке, а пулреквест ещё не принят, все ваши изменения автоматически добавятся в пулреквест, созданный из этой ветки после команды git push origin название-текущей-ветки.
Чтобы создать пулреквест, зайдите на страницу вашего форка на GitHub. Вверху появилась плашка Compare & pull request, а ещё можно зайти на вкладку Pull Requests.

Нажмите на неё и окажетесь на странице открытия пулреквеста. Проверьте описание и нажмите Create pull request.

Готово, теперь ждём остаётся ждать одобрения пулреквеста или комментариев к нему.
Синхронизируем репозитории
Предположим, вы исправили код, руководитель или наставник одобрил ваши правки и принял пулреквест.

Теперь код в мастер-репозитории обновился, а в вашем форке нет, вы ведь не обновляли свою версию репозитория с тех пор, как клонировали её себе на компьютер. Приведём форк в актуальное состояние.
В локальном репозитории переключаемся на ветку master.
git checkout masterЗабираем изменения из ветки master мастер-репозитория
git pull git@github.com:academy-student/1173761-device-34.git masterОтправляем изменения уже из своей ветки master в ваш форк на GitHub с помощью команды
git push origin masterГотово, теперь форк и оригинальный репозиторий находятся в актуальном состоянии.


