Скрипт PowerShell для создания аккаунта в AD (плюс система создания) Печать

Расширенный скрипт New-ADUserExtended для создания аккаунта в Active Directory

Скрипт PowerShell, позволяющий:

  • создать учетную запись в домене Active Directory с основным набором параметров,
  • найдя коллегу по отделу, поместить новую учетную запись в тот же контейнер AD,
  • добавить новую учетную запись в те же группы безопасности AD, в которых состоит коллега по отделу,
  • обозначить контроллер домена и учетные данные для подключения
 # Модуль New-ADUserExtended

Function Global:New-ADUserExtended ([parameter(Mandatory=$true)][string]$samAccountName,
                                    [parameter(Mandatory=$true)][string]$Name,
                                    [parameter(Mandatory=$true)][string]$SecondName,
                                    [parameter(Mandatory=$true)][string]$Surname,
                                    [parameter(Mandatory=$true)][string]$ColleagueSamAccountName,
                                    [parameter(Mandatory=$false)][string]$Office,
                                    [parameter(Mandatory=$false)][string]$TelephoneNumber,
                                    [parameter(Mandatory=$false)][string]$IPphone,
                                    [parameter(Mandatory=$false)][string]$MobilePhone,
                                    [parameter(Mandatory=$false)][string]$Street,
                                    [parameter(Mandatory=$true)][string]$JobTitle,
                                    [parameter(Mandatory=$false)][string]$Departament,
                                    [parameter(Mandatory=$false)][string]$Company,
                                    [parameter(Mandatory=$false)][string]$Description,
                                    [parameter(Mandatory=$false)][string]$Email,
                                    [parameter(Mandatory=$false)][datetime]$ExpireAccount,
                                    [parameter(Mandatory=$false)][switch]$AddToColleagueGroups,
                                    [parameter(Mandatory=$true)][string]$AccountPassword,
                                    [parameter(Mandatory=$false)]$Server,
                                    [parameter(Mandatory=$false)]$Credential) {

    Write-Host  
    $error.Clear | Out-Null
    Write-Host 'Original and comments: http://vam.in.ua/index.php/it/25-ms-powershell/154-powershell-ad-account-create.html'
    Write-Host 'Feedback: http://vam.in.ua/index.php/contacts/2-admins/1-aleksey.html'
    $passwd=''
    Remove-Variable commonError,passwd,colleague -ErrorAction SilentlyContinue
    Write-Host  
    
    #--- Импортируем модуль AD
    Import-Module -Name ActiveDirectory -ErrorVariable commonError

    # Выделяем односимвольный инициал
    $Initial = $SecondName.Substring(0,1).ToUpper()
    # Собираем полное имя
    $displayName = $Name + ' ' + $Initial + '. ' + $Surname
    # Добавляем несокращенные ФИО к описанию
    $Description += &{' [' + $Name + ' ' + $SecondName + ' ' + $Surname + ']'}

    Write-Host 'Sam Account Name/User Principal Name/Login: ('$samAccountName.Length")     `t" $samAccountName -ForegroundColor Yellow
    Write-Host 'Full Name: ('$displayName.Length")     `t`t`t`t`t" $displayName
    Write-Host 'Description: ('$Description.Length")     `t`t`t`t" $Description -ForegroundColor Yellow
    Write-Host 'Street: ('$Street.Length")     `t`t`t`t`t" $Street
    Write-Host 'Telephone: ('$TelephoneNumber.Length")     `t`t`t`t`t" $TelephoneNumber -ForegroundColor Yellow
    Write-Host 'IP Phone: ('$IPphone.Length")     `t`t`t`t`t" $IPphone
    Write-Host 'Mobile Phone: ('$MobilePhone.Length")     `t`t`t`t" $MobilePhone -ForegroundColor Yellow
    Write-Host 'Company: ('$Company.Length")     `t`t`t`t`t" $Company 
    Write-Host 'Departament: ('$Departament.Length")     `t`t`t`t`t" $Departament -ForegroundColor Yellow
    Write-Host 'Office: ('$Office.Length")     `t`t`t`t`t" $Office 
    Write-Host 'Job Title: ('$JobTitle.Length")     `t`t`t`t`t" $JobTitle -ForegroundColor Yellow
    Write-Host 'E-Mail: ('$Email.Length")     `t`t`t`t`t" $Email 
    Write-Host "Account will expire:     `t`t`t`t" $ExpireAccount -ForegroundColor Yellow
    Write-Host "Account password:     `t`t`t`t`t" $AccountPassword 
    Write-Host "Collegue:     `t`t`t`t`t`t" $ColleagueSamAccountName -ForegroundColor Yellow
    Write-Host  

    while (($ContinOk.Length -ne 1) -or ($ContinOk -inotmatch {[yn]})) {
        $mess = 'Создать такую учетную запись? (Y/N)'
        $ContinOk = Read-Host -Prompt $mess
    }

    if ($ContinOk -ieq "N") {
        Remove-Variable ContinOk -ErrorAction SilentlyContinue        
        Write-Error -Message "Операция была отменена" -ErrorAction Stop
    } else {


        #--- Если указаны учетные данные
        if ($Credential) {
            $passwd = Get-Credential -Credential $Credential -ErrorVariable commonError
            if ((!$passwd) -or ($passwd.Length -lt 1)) {Break}
        }

        #--- Если переменная Server не определена, то подставить ей значение текущего контроллера домена
        if ($Server) {
            if ($Credential) {
                $Server = Get-ADDomainController -Credential $passwd -Server $Server -ErrorVariable commonError
                $Domain = $Server.Domain
                $Server = $Server.HostName
            } else {
                $Server = Get-ADDomainController -Server $Server -ErrorVariable commonError
                $Domain = $Server.Domain
                $Server = $Server.HostName
            }
        } else {
            if ($Credential) {
                $Server = Get-ADDomainController -Credential $passwd -ErrorVariable commonError
                $Domain = $Server.Domain
                $Server = $Server.HostName
            } else {
                $Server = Get-ADDomainController -ErrorVariable commonError            
                $Domain = $Server.Domain
                $Server = $Server.HostName
            }
        }

        # Если произошла общая ошибка - прервать функцию
        if ($commonError) {
            Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
            Break
        }
    
        # Узнаем где находится учетная запись коллеги
        if ($Credential) {
            $colleague = Get-ADUser -Identity $ColleagueSamAccountName -Server $Server -Credential $passwd -ErrorVariable commonError
        } else {
            $colleague = Get-ADUser -Identity $ColleagueSamAccountName -Server $Server -ErrorVariable commonError
        }
        $colleague = $colleague.DistinguishedName | Out-String
        $colleague = $colleague | where {$_ -match ",(.+)"} | foreach {$Matches[1]}

        # Если произошла общая ошибка - прервать функцию
        if ($commonError) {
            Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
            Break
        }

        # Если не определено время просроченности аккаунта - то устанавливаем его в Never
        if ((!$ExpireAccount) -or ($ExpireAccount.Length -lt 1)) {
            $ExpireAccount = "1/1/1970"
        }
    
        # Если определен сервер и для коллеги есть хоть один символ - создать аккаунт AD
        if (($Server) -and ($colleague.Length -gt 0)) {

            # Формируем командлет New-ADUser в зависимости от наличия параметров
            [string]$comandLet = 'New-ADUser -SamAccountName $samAccountName -Name $displayName `
                                             -DisplayName $displayName -Surname $Surname -Initials $Initial `
                                             -ErrorVariable commonError -ErrorAction Stop `
                                             -AccountPassword (ConvertTo-SecureString -String $AccountPassword -AsPlainText -Force) `
                                             -Path $colleague -Server $Server'
        
            # Создаем массив переменных (параметр командлета New-ADUser, пробел, переменная; о одинарных кавычках, через запятую)
            $cmltParameters = ('-Office $Office','-OfficePhone $TelephoneNumber','-StreetAddress $Street',`
                                '-Title $JobTitle','-Department $Departament','-Company $Company',`
                                '-Description $Description','-EmailAddress $Email','-MobilePhone $MobilePhone',`
                                '-AccountExpirationDate $ExpireAccount','-Credential $passwd')
        
            # Если длина параметра не ноль, добавляем его в командлет New-ADUser
            foreach ($parameter in $cmltParameters) {
               [string]$expression = 'if (' + ([regex]::Match($parameter,'(?<=\s)(\$.+)')) + '.Length -ge 1) {$comandLet += " $parameter"}'
                Invoke-Expression $expression
            }

            $userPrincipalName = $samAccountName + '@' + $Domain

            # Добавляем в командлет New-ADUser дополнительные статические атрибуты
            $comandLet += ' -OtherAttributes @{userPrincipalName=$userPrincipalName;givenName=$Name;countryCode="804";co="Ukraine";c="UA";l="Kharkov"'

            # Создаем массив дополнительных динамических атрибутов (параметр равно переменная; в одинарных кавычках, через запятую)
            $cmltParametersAdditional = ('ipPhone=$IPphone')

            # Если длина дополнительного атрибута не ноль, добавляем его в командлет New-ADUser
            foreach ($additionalParameter in $cmltParametersAdditional) {
                [string]$expression = 'if (' + ([regex]::Match($additionalParameter,'(?<=\=)(\$.+)')) + '.Length -ge 1) {$comandLet += ";$additionalParameter"}'
                Invoke-Expression $expression
            }

            # Закрываем скобку перечисления дополнительных атрибутов -OtherAttributes в командлете New-ADUser
            $comandLet += '}'

            # Командлет New-ADUser собран, выполняем его
            Invoke-Expression $comandLet

            # Если нет ошибок - выполнить блок кода
            if ((!$commonError) -and (!$commonWarn)) {
                # Активируем новый аккаунт
                if ($Credential) {
                    Set-ADUser -Identity $samAccountName -ChangePasswordAtLogon $true -Server $Server -Credential $passwd
                    Enable-ADAccount -Identity $samAccountName -Server $Server -Credential $passwd
                } else {
                    Set-ADUser -Identity $samAccountName -ChangePasswordAtLogon $true -Server $Server
                    Enable-ADAccount -Identity $samAccountName -Server $Server
                }
                # Поздравим с успешным созданием
                $mess = 'Новая учетная запись "' + $samAccountName + '" успешно создана на сервере "' + $Server + '" в ' + $colleague
                Write-Host $mess
            
                # Если указан параметр добавления нового аккаунта в группы коллеги, выполняем блок кода
                if ($AddToColleagueGroups.IsPresent) {
                    if ($Credential) {
                        # Узнаем в каких группах состоит коллега
                        $grps = Get-ADUser -Identity $ColleagueSamAccountName -Properties MemberOf -Server $Server -Credential $passwd -ErrorVariable commonError
                    } else {
                        $grps = Get-ADUser -Identity $ColleagueSamAccountName -Properties MemberOf -Server $Server -ErrorVariable commonError
                    }

                    # Выделяем группы коллеги в переменную
                    $grps = $grps.MemberOf
                    if ($grps.Length -ge 1) {
                        # Объявляем строковую переменную, в которую будем через запятую заносить имена групп для вывода на экран
                        [string]$strgrp = ''

                        # Добавляем созданный нами аккаунт в те же группы, что и у коллеги
                        foreach ($grp in $grps) {
                            if ($Credential) {
                                Add-ADGroupMember -Identity $grp -Members $samAccountName -Server $Server -Credential $passwd -ErrorVariable commonError                    
                            } else {
                                Add-ADGroupMember -Identity $grp -Members $samAccountName -Server $Server -ErrorVariable commonError
                            }
                            # Регулярное выражение, которое выделит название группы в удобочитаемом виде
                            $strgrp = $strgrp + [regex]::Match($grp,'(?<=\=).*?(?=\,)') + ', '
                        }

                        # Поздравим с успешным добавлением в группы к коллеге
                        if (!$commonError) {
                            # Удаляем из строчного списка групп последнюю запятую
                            $strgrp = $strgrp.Substring(0,($strgrp.Length -2))
                            # Формируем сообщение со списком групп
                            $mess = 'Новая учетная запись успешно добавлена в группы: ' + $strgrp
                            Write-Host $mess
                        }
                    }
                }
            }
        }
    }
    $passwd=''
    Remove-Variable passwd,Credential,mess,strgrp,grp,grps,colleague,AccountPassword,Domain -ErrorAction SilentlyContinue
}

 

Применение:

New-ADUserExtended -samAccountName <string> -Name <string> -Surname <string> -SecondName <string> -ColleagueSamAccountName <string> -Office <string> -TelephoneNumber <string> -IPphone <string> -Street <string> -JobTitle <string> -Departament <string> -Company <string> -Description <string> -Email <string> -ExpireAccount <datetime> -AddToColleagueGroups -AccountPassword <string> -Server <string> -Credential <PSCredential>

 

PS C:\> New-ADUserExtended -samAccountName petrov_i -Name Ivan -Surname Petrov -SecondName Sergeevich -ColleagueSamAccountName sidorov_p -Office 19 -TelephoneNumber "(057)3210102" -IPphone 65412 -Street "Lenina 38" -JobTitle Manager -Departament Econimic -Company "Roga&Kopita" -Description "Test account, created by PowerShell script" -Email "petrov_i@domain.local" -ExpireAccount 06/21/2012 -AddToColleagueGroups -AccountPassword "pSW0rD" -Server dc1.domain.local -Credential domain\admin # Создаст новый аккаунт petrov_i на сервере dc1, используя учетные данные domain\admin. Новый аккаунт будет помещен в тот же OU, в котором находится коллега по работе sidorov_p. К тому же, т.к. указан ключ -AddToColleagueGroups, группы безопасности коллеги Сидорова будут также назначены созданному аккаунту

Добавляем скрипт в профиль и модуль New-ADUserExtended будет доступен также как и все остальные командлеты. Как работать с профилями смотрите в моей статье (ссылка).

Для того чтобы скрипт нормально отработал, необходимо чтобы был установлен родной модуль PowerShell ActiveDirectory. Он входит в набор Remote Server Administration Tools (RSAT) [Remote Server Administration Tools/Role Administration Tools/AD DS and AD LDS Tools/Active Directory module for Windows PowerShell] и автоматически ставится на контроллерах домена вместе с Active Directory.

Сборка данных для создания учетной записи Assemble_New-ADUserExtended

Данный скрипт Assemble_New-ADUserExtended.ps1 идёт в дополнение к вышеописанному скрипту New-ADUserExtended.ps1. Он представляет собой средство сбора информации для дальнейшей передачи её на скрипт создания. Собранную информацию скрипт записывает в текстовый файл.

Идея такова:

Скрипт Assemble_New-ADUserExtended.ps1 передается сотрудникам техподдержки. С его помощью они принимают заявки на создание новых учетных записей и заполняют предлагаемые скриптом поля. Все эти данные скрипт сохраняет в файл на сетевую папку. Соответственно никаких разрешений в Active Directory сотрудникам техподдержки иметь не нужно, они лишь только создают запросы на создание для последующей обработки. После этого шага администратор, с правами на создание объектов в Active Directory, выполняет второй модуль New-ADUserExtendedParseFile.ps1 (представлен ниже), который поочередно выдергивает из файла на сетевой папке уже подготовленные запросы на создание и передает их в модуль New-ADUserExtended.ps1.

Модуль сборки, который передается сотрудниками техподдержки

 # Модуль Assemble_New-ADUserExtended

Clear-Host

# Зададим заголовок, размер буфера и окна PowerShell
try {
    $a = $host.UI.RawUI
    $a.WindowTitle = "Запрос на создание новой учетной записи в домене"
    $b = $a.BufferSize
    $b.Width = 130
    $b.Height = 255
    $a.BufferSize = $b
    $b = $a.WindowSize
    $b.Width = 130
    $b.Height = 50
    $a.WindowSize = $b
} finally {
    Remove-Variable a,b -ErrorAction SilentlyContinue
}

# Функция, изменяющая регистр первого символа в строке на верхний
Function Private:FirstSymbolCaseToUpper ([string]$StringToChange) {
    Return $StringToChange.Substring(0,1).ToUpper() + $StringToChange.Substring(1,($StringToChange.Length - 1))
}

Remove-Variable collOk,mess,expireDate,willExpire,okExpire,expireDay,expireMonth,expireYear,expireBool,copyGroups,surname, `
name,secondName,office,telephone,ipphone,street,jobtitle,departament,company,description,email,samaccountname,colleague, `
colleagueTMP,colleagueTMP2,colleagueBool -ErrorAction SilentlyContinue

$error.Clear | Out-Null
Write-Host  
Write-Host 'Original and comments: http://vam.in.ua/index.php/it/25-ms-powershell/154-powershell-ad-account-create.html' -ForegroundColor DarkCyan
Write-Host 'Feedback: http://vam.in.ua/index.php/contacts/2-admins/1-aleksey.html' -ForegroundColor DarkCyan
Write-Host  

# Импортируем модуль AD
Import-Module -Name ActiveDirectory -ErrorAction Stop

Write-Host ' -= Запрос на создание новой учетной записи в домене =- ' -BackgroundColor Cyan -ForegroundColor DarkBlue
Write-Host 'Все данные необходимо вводить английской раскладкой' -ForegroundColor Green
Write-Host  

while ($collOk -ine 'N') {

    # Объявляем булевой переключатель
    [bool]$colleagueBool = $false

    while ($colleague.Length -lt 1) {
        $colleagueTMP = Read-Host -Prompt 'Укажите учетную запись коллеги по отделу'
        # Добавляем интерактивно-определенной переменной символ "звездочка" для обработки оператором -like. Записываем результат в переменную colleagueTMP2
        $colleagueTMP2 = '*' + $colleagueTMP + '*'
        # Если в переменной colleagueTMP2 есть что-то кроме двух "звоздочек" - выполнить блок кода
        if ($colleagueTMP2.Length -gt 2) {
            # Собираем в переменную colleague всех пользователей AD, попадающих под шаблон colleagueTMP2
            $colleague = Get-ADUser -Filter {SamAccountName -like $colleagueTMP2} -Properties DisplayName -ErrorAction SilentlyContinue
            # Для каждого собранного в colleague пользователя
            foreach ($col in $colleague) {
                Write-Host  
                # Выведем на экран
                Write-Host "Учетная запись коллеги: `t" $col.SamAccountName -ForegroundColor White
                Write-Host "Полное имя коллеги: `t`t" $col.DisplayName -ForegroundColor White
                # Если текущий пользователь точно соответствует интерактивно введенной учетке - установить переключатель colleagueBool в истинное значение. 
                        if ($col.SamAccountName -eq $colleagueTMP) {
                $colleagueBool = $true
            }
            }
        } else {
            # Продолжим цикл, тем самым заново предложим ввести учетную запись коллеги
            Continue
        }

        # Если в массиве colleague только одна учетка, или переключатель colleagueBool истин - выполнить блок кода
        if (($colleague.Length -eq 1) -or ($colleagueBool -eq $true)) {
            $colleagueBool = $false
            # Заносим в переменную colleague точно определенного коллегу
            $colleague = Get-ADUser -Identity $colleagueTMP -Properties DisplayName,company,department,title, `
                            lastlogon,msDS-UserPasswordExpiryTimeComputed,accountExpires, `
                            msDS-User-Account-Control-Computed,description -ErrorAction Stop
            # Коллега определен, заканчиваем цикл while
            Break
        } else {
            Remove-Variable -Name colleague
        }
    
        Write-Host  
        Write-Host  
        Write-Host  
    }

    Write-Host  
    Write-Host  
    Write-Host  
    Write-Host "Вами определен коллега:" -ForegroundColor DarkYellow
    Write-Host "Учетная запись коллеги: `t`t" $colleague.SamAccountName -ForegroundColor White
    Write-Host "Полное имя коллеги: `t`t`t" $colleague.DisplayName -ForegroundColor White
    Write-Host "Организация коллеги: `t`t`t" $colleague.company -ForegroundColor White
    Write-Host "Департамент коллеги: `t`t`t" $colleague.department -ForegroundColor White
    Write-Host "Должность коллеги: `t`t`t" $colleague.title -ForegroundColor White
    Write-Host "Описание коллеги: `t`t`t" $colleague.description -ForegroundColor White
    if (($colleague.accountExpires -eq 9223372036854775807) -or ($colleague.accountExpires -eq 0)) {
        Write-Host "Коллега является стажером: `t`t нет" -ForegroundColor White
    } else {
        Write-Host "Коллега является стажером до: `t`t" ([datetime]::FromFileTime($colleague.accountExpires)) -ForegroundColor White
    }

    if (($colleague.lastlogon -eq $null) -or ($colleague.lastlogon -eq 0) -or ($colleague.lastlogon -eq 9223372036854775807)) {
        Write-Host "Коллега последний раз логинился: `t никогда" -ForegroundColor White
    } else {
        Write-Host "Коллега последний раз логинился: `t" ([datetime]::FromFileTime($colleague.lastlogon)) -ForegroundColor White 
    }

    if ($colleague.{msDS-UserPasswordExpiryTimeComputed} -eq 9223372036854775807) {
        Write-Host "Коллега не обязан менять пароль: `t да" -ForegroundColor White
    } else {
        if ($colleague.{msDS-UserPasswordExpiryTimeComputed} -eq 0) {
            Write-Host "Коллега должен поменять пароль: `t сразу, при первом входе" -ForegroundColor White
        } else {
            Write-Host "Коллега должен поменять пароль до: `t" ([datetime]::FromFileTime($colleague.{msDS-UserPasswordExpiryTimeComputed})) -ForegroundColor White
        }
    }
    if ($colleague.Enabled -eq $true) {
        Write-Host "Учетная запись коллеги активирована: `t да" -ForegroundColor White
    } else {
        Write-Host "Учетная запись коллеги активирована: `t нет" -ForegroundColor Red
    }
    if ($colleague.{msDS-User-Account-Control-Computed} -eq 16) {
        Write-Host "Учетная запись коллеги заблокирована: `t да" -ForegroundColor Red
    } else {
        Write-Host "Учетная запись коллеги заблокирована: `t нет" -ForegroundColor White
    }
    $DC = Get-ADDomainController
    $DC = $DC.Name + '.' + $DC.Domain
    Write-Host "Информация получена с сервера: `t`t" $DC -ForegroundColor White
    Remove-Variable $DC -ErrorAction SilentlyContinue
    Write-Host  
    Write-Host  

    while (($collOk.Length -ne 1) -or ($collOk -inotmatch {[yn]})) {
        $mess = 'Искать другого коллегу? (Y/N)'
        $collOk = Read-Host -Prompt $mess
    }
    if ($collOk -ieq "Y") {
        $collOk = ''
        $colleague = ''
        Write-Host  
    }

}

# Выбираем из .NET объекта атрибут SamAccountName и оставляем только его в текстовом формате
[string]$colleague = $colleague.SamAccountName

Write-Host  
Write-Host  
Write-Host 'Создаем новую учетную запись' -ForegroundColor DarkYellow
# Пока интерактивно не будет указана фамилия - повторять запрос (обязательный параметр)
while (($surname.Length -lt 1) -or ($surname.Length -gt 32)) {
    $surname = Read-Host -Prompt 'Укажите фамилию'

    if ($surname.Length -gt 32) {
        $itemLength = $surname.Length - 32
        Write-Host "Это поле не должно превышать 32 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
    }
}
while (($name.Length -lt 1) -or ($name.Length -gt 32)) {
    $name = Read-Host -Prompt 'Укажите имя'

    if ($name.Length -gt 32) {
        $itemLength = $name.Length - 32
        Write-Host "Это поле не должно превышать 32 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
    }
}
while (($secondName.Length -lt 1) -or ($secondName.Length -gt 32)) {
    $secondName = Read-Host -Prompt 'Укажите отчество'

    if ($secondName.Length -gt 32) {
        $itemLength = $secondName.Length - 32
        Write-Host "Это поле не должно превышать 32 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
    }
}

$office = Read-Host -Prompt 'Укажите номер офиса'
if ($office.Length -gt 0) {
    while ($office.Length -gt 32) {

        if ($office.Length -gt 32) {
            $itemLength = $office.Length - 32
            Write-Host "Это поле не должно превышать 32 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $office = Read-Host -Prompt 'Укажите номер офиса'
    }
}

$telephone = Read-Host -Prompt 'Укажите городской номер телефона'
if ($telephone.Length -gt 0) {
    while ($telephone.Length -gt 16) {
        if ($telephone.Length -gt 16) {
            $itemLength = $telephone.Length - 16
            Write-Host "Это поле не должно превышать 16 символов. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $telephone = Read-Host -Prompt 'Укажите городской номер телефона'
    }
}

$ipphone = Read-Host -Prompt 'Укажите внутренний номер телефона'
if ($ipphone.Length -gt 0) {
    while ($ipphone.Length -gt 16) {
        if ($ipphone.Length -gt 16) {
            $itemLength = $ipphone.Length - 16
            Write-Host "Это поле не должно превышать 16 символов. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $ipphone = Read-Host -Prompt 'Укажите внутренний номер телефона'
    }
}

$mobphone = Read-Host -Prompt 'Укажите номер мобильного телефона'
if ($mobphone.Length -gt 0) {
    while ($mobphone.Length -gt 16) {
        if ($mobphone.Length -gt 16) {
            $itemLength = $mobphone.Length - 16
            Write-Host "Это поле не должно превышать 16 символов. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $mobphone = Read-Host -Prompt 'Укажите номер мобильного телефона'
    }
}

while (($street.Length -lt 1) -or ($street.Length -gt 64)) {
    $street = Read-Host -Prompt 'Укажите улицу и номер дома ( Konstitucii 7 )'

    if ($street.Length -gt 64) {
        $itemLength = $street.Length - 64
        Write-Host "Это поле не должно превышать 64 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
    }
}

while (($jobTitle.Length -lt 1) -or ($jobTitle.Length -gt 128)) {
    $jobTitle = Read-Host -Prompt 'Укажите должность'

    if ($jobTitle.Length -gt 128) {
        $itemLength = $jobTitle.Length - 128
        Write-Host "Это поле не должно превышать 128 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
    }
}

$departament = Read-Host -Prompt 'Укажите департамент'
if ($departament.Length -gt 0) {
    while ($departament.Length -gt 64) {
        if ($departament.Length -gt 64) {
            $itemLength = $departament.Length - 64
            Write-Host "Это поле не должно превышать 64 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $departament = Read-Host -Prompt 'Укажите департамент'
    }
}

$company = Read-Host -Prompt 'Укажите название организации'
if ($company.Length -gt 0) {
    while ($company.Length -gt 64) {
        if ($company.Length -gt 64) {
            $itemLength = $company.Length - 64
            Write-Host "Это поле не должно превышать 64 символа. Сократите его на $itemLength" -ForegroundColor DarkGray
        }

        $company = Read-Host -Prompt 'Укажите название организации'
    }
}

# Если не определен департамент или организация - обязать указать описание создаваемой учетной записи
if (($company.Length -lt 1) -or ($departament.Length -lt 1)) {
    Write-Host 'Название организации и/или департамент не определены, поэтому описание учетной записи обязательно' -ForegroundColor DarkGray
    while ($description.Length -lt 1) {
        $description = Read-Host -Prompt 'Укажите описание'
    }
} else {
    $description = Read-Host -Prompt 'Укажите описание'
}

$eMail = Read-Host -Prompt 'Укажите E-Mail адрес'

# Пока в переменной copyGroups не будет один символ Y, или N - повторять запрос
while (($copyGroups.Length -ne 1) -or ($copyGroups -inotmatch {[yn]})) {
    $copyGroups = Read-Host -Prompt 'Назначить разрешения коллеги для новой учетной записи? (Y/N)'
}

while (($willExpire.Length -ne 1) -or ($willExpire -inotmatch {[yn]})) {
    $willExpire = Read-Host -Prompt 'Учетная запись стажера? (Y/N)'
}

# Устанавливаем переключатель expireBool в значение ложь
[bool]$expireBool = $false
# Если переменная willExpire соответствует Y - выполнить блок кода
if ($willExpire -ieq 'y') {
    Write-Host 'Год, месяц и день, до которых действительна учетная запись: ' -ForegroundColor DarkGray
    # Пока не указан год, или месяц, или день, или переключатель expireBool не истин - выполнять блок кода в цикле
    while ((!$expireYear) -or (!$expireMonth) -or (!$expireDay) -or ($expireBool -eq $false)) {
        $expireYear = Read-Host -Prompt 'Укажите год'
        $expireMonth = Read-Host -Prompt 'Укажите месяц'
        $expireDay = Read-Host -Prompt 'Укажите число'
        # Собираем в переменную expireDate день, месяц и год и в нужной командлету последовательности
        $expireDate = $expireMonth + '/' + $expireDay + '/' + $expireYear
        # Если дата не соответствует формату - погнать цикл по-новой
        if ($expireDate -notmatch "(^\d{1,2})/(\d{1,2})/(\d{4})") {
            Write-Host 'Указана неверная дата (правильный формат: DD/MM/YYYY)' -ForegroundColor DarkGray
            Continue
        } else {
            if (([int16]$expireMonth -gt 12) -or ([int16]$expireMonth -lt 1) -or ([int16]$expireDay -gt 31) -or ([int16]$expireDay -lt 1)) {
                Write-Host 'Указана неверная дата (проверьте дни и месяцы)' -ForegroundColor DarkGray
                Continue
            }
        }
        # Подтверждение правильности ввода даты
        while (($okExpire.Length -ne 1) -or ($okExpire -inotmatch {[yn]})) {
            $mess = 'Учетная запись стажера активна до '+ $expireDay + '/' + $expireMonth + '/' + $expireYear + '. Все верно? (Y/N)'
            $okExpire = Read-Host -Prompt $mess
        }
        if ($okExpire -ieq 'y') {
            $expireBool = $true
        } else {
            $okExpire = ''
        }
    }
}

# Формируем логин в формате "фамилия_перваяБукваИмени"
$samAccountName = $surname.ToLower() + '_' + $name.Substring(0,1).ToLower()

# Изменим регистр значений основных переменных (регистр остальных параметров изменяется в цикле foreach ниже)
$name = FirstSymbolCaseToUpper -StringToChange $name
$surname = FirstSymbolCaseToUpper -StringToChange $surname
$secondName = FirstSymbolCaseToUpper -StringToChange $secondName
$jobTitle = FirstSymbolCaseToUpper -StringToChange $jobTitle

# Формируем командлет New-ADUserExtended в зависимости от наличия параметров
[string]$comandLet = 'New-ADUserExtended -SamAccountName "' + $samAccountName + '" -Name "' + $name + '" -Surname "' + $Surname + '" -SecondName "' + $secondName + '" -ColleagueSamAccountName "' + $colleague + '" -JobTitle "' + $JobTitle + '" -AccountPassword "Pa$$w0rd-To-Change"'
        
# Создаем массив переменных (параметр командлета New-ADUserExtended, пробел, переменная; о одинарных кавычках, через запятую)
$cmltParameters = ('-Office $Office','-TelephoneNumber $telephone','-Street $Street',`
                            '-Departament $Departament','-Company $Company',`
                            '-Description $Description','-Email $Email',`
                            '-ExpireAccount $expireDate','-IPphone $ipphone',`
                            '-MobilePhone $mobphone')


[bool]$addOk = $false
# Если длина параметра не ноль, добавляем его в командлет New-ADUserExtended
foreach ($parameter in $cmltParameters) {
    # Выляем в переменную varA первую часть выражения учитывая пробел. Например [-TelephoneNumber ]
    [string]$varA = [regex]::Match($parameter,'^\-\w+\s')
    # Выляем в переменную varB вторую часть выражения. Например [$telephone] 
    [string]$varB = [regex]::Match($parameter,'(?<=\s)(\$.+)')
    # В строковой переменной expression формируем выражение if. Если существует значение для переменной, заключенной в переменную varB - то переключить булевую переменную $addOk в истину ( например [if ($telephone.Length -ge 1) {$addOk = $true}] )
    [string]$expression = 'if (' + $varB + '.Length -ge 1) {$addOk = $true}'
    # Вызываем сформированное выражение из переменной expression
    Invoke-Expression $expression
    # Если значение переключателя истинно
    if ($addOk -eq $true) {
        # varB пока содержит подпеременную в текстовом виде. Внести в переменную varB значение подпеременной ( например [вместо $telephone занести ее значение - (057)567-12-32] )
        $varB = Invoke-Expression $varB
        # Изменим регистр значения переменной varB (первая буква большая)
        if ($varA -ine "-Email ") {
            $varB = FirstSymbolCaseToUpper -StringToChange $varB
        }
        # Нам не нужно оборачивать в кавычки значение переменной expireDate.
        if ($varA -eq '-ExpireAccount ') {
            $comandLet += (' ' + $varA + $varB)
        } else {
            $comandLet += (' ' + $varA + '"' + $varB + '"')
        }
        # Установим переключатель в ложь
        $addOk = $false
    }
}

# Если стоит флаг добавления новой учетной записи в те же группы, что и у коллеги - выполнить блок кода
if ($copyGroups -ieq 'y') {
    # Добавить к результирующему командлету параметр -AddToColleagueGroups
    $comandLet += ' -AddToColleagueGroups'
}

# Экспортировать результат в файл, для дальнейшей обработки функцией New-ADUserExtended (http://vam.in.ua/index.php/it/25-ms-powershell/154-powershell-ad-account-create.html)
Out-File -InputObject $comandLet -FilePath '\\10.0.3.5\NewDomainAccount$\scriptBase.txt' -Append -Width 1024

Модуль обработки созданных запросов и передача их на модуль создания

 # Модуль New-ADUserExtendedParseFile

Function Global:New-ADUserExtendedParseFile ([parameter(Mandatory=$true)][string]$FilePath,
                                             [parameter(Mandatory=$false)][string]$Credential,
                                             [parameter(Mandatory=$false)][string]$Server) {

    Remove-Variable StrMassiveFile,StrMassive -ErrorAction SilentlyContinue

    if ($Credential) {
        $Credential = ' -Credential ' + $Credential
    }

    if ($Server) {
        $Server = ' -Server ' + $Server
    }

    $StrMassiveFile = Get-Content -Path $FilePath -ErrorAction Stop
    
    $StrMassive = @()

    foreach ($collectedCmdlt in $StrMassiveFile) {
        if ($collectedCmdlt.Substring(0,1) -ne '#') {
            $StrMassive += ('# ' + $collectedCmdlt)
        } else {
            $StrMassive += $collectedCmdlt
        }
    }

    Out-File -FilePath $FilePath -InputObject $StrMassive

    foreach ($collectedCmdlt in $StrMassiveFile) {
        if ($collectedCmdlt.Substring(0,1) -ne '#') {
            $toInvoke = $collectedCmdlt + $Credential + $Server
            Invoke-Expression $toInvoke
        }
    }
}