Четверг, 04.01.2024 15:55

Дорабатываем генератор виртуальной организации для Active Directory

Дорабатываем генератор виртуальной организации для Active Directory

В прошлой статье Создаем виртуальную организацию в Active Directory – мы написали генератор виртуальной организации для Active Directory.

Генератор хорошо работал, и создавал виртуальную организацию. Пока мы использовали её в качестве стенда для работы с запросами по LDAP всё работало нормально. При входе на ПК с создаваемыми учетными данными у меня возникли проблемы, так как не все поля учетной записи пользователя правильно заполнялись. 

Также изначально использовался домен .local время показало, что с этим доменом впоследствии могут возникнуть некоторые проблемы, поэтому генератор был переписан, чтобы иметь возможность выбрать имя организации и домен.

Сегодня мы модифицируем скрипт - исправим ошибки и добавим возможность выбрать домен и название организации.

В статье - Разбираем (парсим) параметры командной строки в Python. Параметры командной строки в Python. Часть 1 мы уже рассмотрели добавление обработки параметров командной строки.

Нам потребуется проект из этой части.

Добавим файл:

args.py

с содержимым:

import argparse
import sys
parser = argparse.ArgumentParser(
    prog='generator',
    description="Генератор виртуальной организации для импорта в Active Directory (Copyright 2024 altuninvv.ru)",
)
parser.add_argument(
    "command",
    type=str,
    help="Команда для запуска (run)",
)
parser.add_argument(
    "--domain", "-domain", "-d",
    type=str,
    help="Домен организации. По умолчанию:  soft.altuninvv.ru",
    default="soft.altuninvv.ru",
)
parser.add_argument(
    "--name", "-name", "-n",
    help="Имя организации на кириллице. По умолчанию:  Алтунин Софт",
    default="Алтунин Софт",
)
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
if sys.argv[1].strip().lower() != "run":
    parser.print_help(sys.stderr)
    sys.exit(1)    
args = parser.parse_args()

Внесем изменения в файл:

generator.py
import cyrtranslit
import string
import random
import codecs
 
from random import randint
from args import args
f = open('fio.csv', 'r')
fio = f.read().split(';')
fout = codecs.open('ad/users.csv', 'w', "utf-8")
 
fout.write("login;")
fout.write("fio;")
fout.write("fname;")
fout.write("lname;")
fout.write("initials;")
fout.write("samaccname;")
fout.write("cellphone;")
fout.write("workphone;")
fout.write("vntel;")
fout.write("fax;")
fout.write("email;")
fout.write("department;")
fout.write("jobtitle;")
fout.write("addr;")
fout.write("kab;")
fout.write("company;")
fout.write("ou;")
fout.write("passwd\n")
i = 0;
kab = 100;
for val in fio:
    fios = val.strip().split(' ')
    login = cyrtranslit.to_latin(fios[0],'ru') + cyrtranslit.to_latin(fios[1][0:1].upper(),'ru') + cyrtranslit.to_latin(fios[2][0:1].upper(),'ru')
    email = login + "@" + args.domain
    fname = fios[1]
    lname = fios[0]
    initials = fios[2][0:1] + "."
    samaccname = login
    cellphone = "+7(495)" + str(randint(0,9)) + str(randint(0,9)) + str(randint(0,9)) + "-" + str(randint(0,9)) + str(randint(0,9)) + "-" + str(randint(0,9)) + str(randint(0,9))
    department = ""
    company = args.name
    letters = string.ascii_uppercase + string.ascii_lowercase + string.digits + "-=+,.:@!%$&*()~"
    password = ''.join(random.choice(letters) for i in range(16)) + str(random.randint(100, 999))    
    kab = kab + 1  
    fax = "+7(495)1240001"
    vntel = 100
    if (i >-1 ) and (i < 4):
        workphone = "+7(495)1230001" + str(i)
        vntel = vntel + i
    if (i > 3) and (i < 8):
        workphone = "+7(495)1230002" + str(i)
        vntel = vntel + i
    if (i > 7) and (i < 10):
        workphone = "+7(495)1230003" + str(i)
        vntel = vntel + i
    if (i > 9) and (i < 32):
        workphone = "+7(495)12301" + str(i)
        vntel = vntel + i
    if (i > 31) and (i < 54):      
        workphone = "+7(495)12302" + str(i)
        vntel = 200
        vntel = vntel + i      
    if (i > 53) and (i < 76):
        workphone = "+7(495)12303" + str(i)
        vntel = 300
        vntel = vntel + i
    if (i > 75):
        vntel = 400
        workphone = "+7(495)12304" + str(i)
        vntel = vntel + i
    if (i == 3):
        fax = "+7(495)12400001"
    elif (i == 4):
        fax = "+7(495)12400002"
    elif (i == 7):
        fax = "+7(495)12400003"
    elif (i == 9):
        fax = "+7(495)12400004"
    elif (i == 31):
        fax = "+7(495)12400005"
    elif (i == 53):
        fax = "+7(495)12400006"
    elif (i == 75):
        fax = "+7(495)12400007"
    else:
        fax = ""
    if (i >-1 ) and (i < 4):
        department = "Руководство"
    if (i > 3) and (i < 8):
        department = "Бухгалтерия"
    if (i > 7) and (i < 10):
        department = "It"
    if (i > 9) and (i < 32):
        department = "Отдел 1"
    if (i > 31) and (i < 54):
        department = "Отдел 2"
    if (i > 53) and (i < 76):
        department = "Отдел 3"
    if (i > 75):
        department = "Отдел 4"
    jobtitle  = ""
    if (i == 0 ):
        jobtitle = "Директор"
    if (i == 1) or (i == 2):
        jobtitle = "Заместитель директора"
    if (i == 3):
        jobtitle = "Секретарь"
    if (i == 4):
        jobtitle = "Главный бухгалтер"
    if (i == 5):
        jobtitle = "Заместитель главного бухгалтера"
    if (i == 6) or (i == 7):
        jobtitle = "Бухгалтер"
    if (i == 8) or (i == 9):
        jobtitle = "Системный администратор"
    if (i == 10):
        jobtitle = "Начальник"
    if (i == 11):
        jobtitle = "Заместитель начальника"
    if (i > 11) and (i < 32):
        jobtitle = "Специалист"
    if (i == 32):
        jobtitle = "Начальник"
    if (i == 33):
        jobtitle = "Заместитель начальника"
    if (i > 33) and (i < 54):
        jobtitle = "Специалист"
    if (i == 54):
        jobtitle = "Начальник"
    if (i == 55):
        jobtitle = "Заместитель начальника"
    if (i > 55) and (i < 76):
        jobtitle = "Специалист"
    if (i == 76):
        jobtitle = "Начальник"
    if (i == 77):
        jobtitle = "Заместитель начальника"
    if (i > 77):
        jobtitle = "Специалист"
 
    if (i >-1 ) and (i < 54):
        addr = "Ленина 1"
    if (i > 53) and (i < 76):
        addr = "Горького 1"
    if (i > 75):
        addr = "Пушкина 1"
        
    domain = args.domain.strip().split('.')
   
    domain_str = ""
    cnt=0
    for vals in domain:
        if cnt == 0:
            domain_str += ",DC=" + vals
        else:
            domain_str += ",DC=" + vals
        cnt+=1        
 
    if (i >-1 ) and (i < 4):
        ou = "OU=ruk,OU=Company"+domain_str
    if (i > 3) and (i < 8):
        ou = "OU=buh,OU=Company"+domain_str
    if (i > 7) and (i < 10):
        ou = "OU=it,OU=Company"+domain_str
    if (i > 9) and (i < 32):
        ou = "OU=otdel1,OU=Company"+domain_str
    if (i > 31) and (i < 54):
        ou = "OU=otdel2,OU=Company"+domain_str
    if (i > 53) and (i < 76):
        ou = "OU=otdel3,OU=Company"+domain_str
    if (i > 75):
        ou = "OU=otdel4,OU=Company"+domain_str
    print("Processing: " + login)
    i = i + 1
    fout.write(login+";")
    fout.write(val+";")
    fout.write(fname+";")
    fout.write(lname+";")
    fout.write(initials+";")
    fout.write(samaccname+";")
    fout.write(cellphone+";")
    fout.write(workphone+";")
    fout.write(str(vntel)+";")
    fout.write(fax+";")
    fout.write(email+";")
    fout.write(department+";")
    fout.write(jobtitle+";")
    fout.write(addr+";")
    fout.write(str(kab)+";")
    fout.write(company+";")
    fout.write(ou+";")
    fout.write(password)
    fout.write("\n")
fout.close()
                              
domain_str=domain_str[1:]
                                       
print("---------------")
f.close()
fout = codecs.open('ad/ous.csv', 'w', "utf-8")
fout.write("name;descr;domain\n")
fout.write("ruk;Руководство;OU=Company,"+domain_str+"\n")
fout.write("buh;Бухгалтерия;OU=Company,"+domain_str+"\n")
fout.write("it;IT;OU=Company,"+domain_str+"\n")
fout.write("otdel1;Отдел 1;OU=Company,"+domain_str+"\n")
fout.write("otdel2;Отдел 2;OU=Company,"+domain_str+"\n")
fout.write("otdel3;Отдел 3;OU=Company,"+domain_str+"\n")
fout.write("otdel4;Отдел 4;OU=Company,"+domain_str+"")
fout.close()
fout = codecs.open('ad/org.csv', 'w', "utf-8")
fout.write("name;domain\n")
fout.write(args.name+";"+domain_str)
fout.close()
print("Done!")

Создадим файл

generator.cmd

С содержимым:

@echo off
python3 generator.py %*

Создадим папку ad

mkdir ad

Все файлы теперь будут создаваться в этой папке, так что теперь её просто нужно будет скопировать на сервер AD для запуска импорта.

Запустим:

generator.cmd
usage: generator [-h] [--domain DOMAIN] [--name NAME] command
Генератор виртуальной организации для импорта в Active Directory (Copyright 2024 altuninvv.ru)
positional arguments:
  command               Команда для запуска (run)
options:
  -h, --help            show this help message and exit
  --doman DOMAN, -domain DOMAN, -d DOMAN
                        Имя организации на кириллице. По умолчанию: Алтунин Софт
  --name NAME, -name NAME, -n NAME
                        Домен организации. По умолчанию: soft.altuninvv.ru

Запустим:

generator.cmd run --domain=soft.altuninvv.ru --name "Sky Soft"

Будет создан файл users.csv

Посмотрим на его вторую строку:

AntonovMD;Антонов Максим Дмитриевич;Максим;Антонов;Д.;AntonovMD;+7(495)294-72-75;+7(495)12300010;100;;AntonovMD@soft.altuninvv.ru;Руководство;Директор;Ленина 1;101;Sky Soft;OU=ruk,OU=Company,DC=soft,DC=altuninvv,DC=ru;M1aNVmhGV(9,dMs=209

Параметры указанные в командной строке заменены.

Если же мы просто запустим:

generator.cmd run

То будут применены параметры по умолчанию:

AntonovMD;Антонов Максим Дмитриевич;Максим;Антонов;Д.;AntonovMD;+7(495)888-52-17;+7(495)12300010;100;;AntonovMD@soft.altuninvv.ru;Руководство;Директор;Ленина 1;101;Алтунин Софт;OU=ruk,OU=Company,DC=soft,DC=altuninvv,DC=ru;9-52%3-wz(tBggBp376

Изменения в скрипте импорта в Ad

Скрипт import.ps1 тоже претерпел изменения, теперь всё данные берутся из .csv-файлов.

В папке ad создадим файл:

import.ps1
Import-Module ActiveDirectory
echo Запуск
echo ""

echo "Создание организации "
$org = Import-Csv -Encoding UTF8 -Delimiter ';' -Path $PSScriptRoot"\org.csv"

foreach ($o in $org) {
    New-ADOrganizationalUnit -Name Company -Path $o.domain -Description $o.name
    Write-Host "." -NoNewline    
}

echo ""
echo "Организация создана!"

echo ""
echo "Создание отделов "
$ous = Import-Csv -Encoding UTF8 -Delimiter ';' -Path $PSScriptRoot"\ous.csv"

foreach ($ou in $ous) {

New-ADOrganizationalUnit -Name $ou.name `
-Path $ou.domain `
-Description $ou.descr
Write-Host "." -NoNewline

}

echo ""
echo "Отделы созданы!"

echo ""
echo "Добавление пользователей "

$users = Import-Csv -Encoding UTF8 -Delimiter ';' -Path $PSScriptRoot"\users.csv"



foreach ($user in $users) {

New-ADUser -Name $user.login `
-DisplayName $user.fio `
-GivenName $user.fname `
-Surname $user.lname `
-Initials $user.initials `
-OfficePhone $user.workphone `
-Department $user.department `
-Title $user.jobtitle `
-UserPrincipalName $user.email `
-MobilePhone $user.cellphone `
-SamAccountName $user.samaccname `
-Path $user.ou `
-EmailAddress $user.email `
-StreetAddress $user.addr `
-Office $user.kab `
-Company $user.company `
-Fax $user.fax `
-AccountPassword (ConvertTo-SecureString $user.passwd -AsPlainText -force) -Enabled $true
 
Set-ADUser -Identity $user.login `
-Add @{otherTelephone=$user.vntel} 

Write-Host "." -NoNewline
}

echo ""
echo "Пользователи добавлены!"
echo ""
echo Закончено.

В скрипт дополнительные информационные сообщения о прогрессе работы.

Заключение

Сегодня мы внесли изменения в скрипт генерации виртуальной организации для Active Directory.

Добавили два параметра:

--domain – имя виртуального домена

--name – имя виртуальной организации

Внесли изменения для генерации дополнительной информации, используемой скриптом импорта PowerSell.

Внесли изменения в скрипт PowerShell для импорта данных в AD.

Категория Python

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 157