Скрипт PowerShell для установки сложных паролей списку пользователей AD Печать

Скрипт Set-ADAccountStaticComplexPassword позволяющий устанавливать пользователям в Active Directory сложные пароли.

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

  • Получить список логинов пользователей Active Directory из текстового файла, массива или по конвейеру для последующей обработки
  • Установить каждому пользователю из списка сгенерированный сложный пароль от 7 до 8 символов, не требующий периодического изменения
  • Установить каждому пользователю из списка запрет на самостоятельное изменение пароля
  • Снять с каждого пользователя из списка необходимость изменить пароль при первом входе в систему
  • Вывести соответствующие логины и присвоенные им пароли в текстовый файл либо на экран

 

Как им пользоваться:

PS C:\> Get-Help Set-ADAccountStaticComplexPassword -Examples

Function Global:Set-ADAccountStaticComplexPassword ([parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)][System.Array]$SourceSamAccountNameArray,
                                                    [parameter(Mandatory=$false)][string]$SourceSamAccountNameListFromFile,
                                                    [parameter(Mandatory=$false)][string]$DestinationList,
                                                    [parameter(Mandatory=$false)]$Server,
                                                    [parameter(Mandatory=$false)]$Credential)
{

<#
    .SYNOPSIS
    Set complex password to AD accounts, which users can not change.

    .DESCRIPTION
    This function sets options (Password Never Expires, User Can Not Change Password, User Needn't Change Password At First Logon) to each AD account from either of file SourceSamAccountNameListFromFile or Array. Besides it specifies complex password for appropriate AD account.   Original and comments:  http://vam.in.ua/index.php/it/25-ms-powershell/209-powershell-ad-account-complex-password.html   Feedback:  http://vam.in.ua/index.php/contacts/2-admins/1-aleksey.html

    .PARAMETER SourceSamAccountNameArray
    Specify "System Array" with list of AD accounts. You can also use it over pipeline. It is necessary if you aren't going to specify "SourceSamAccountNameListFromFile" parameter.

    .PARAMETER SourceSamAccountNameListFromFile
    Set path to file with list of AD accounts. It is necessary if you haven't specified "SourceSamAccountNameArray" parameter.

    .PARAMETER DestinationList
    Set path to file in which function puts result.

    .PARAMETER Server
    You can specify certain domain controller for processing.

    .PARAMETER Credential
    You can specify certain credentials for processing.

    .EXAMPLE
    PS C:\> Set-ADAccountStaticComplexPassword -SourceSamAccountNameListFromFile C:\WorkDir\accounts.txt

    .EXAMPLE
    PS C:\> Set-ADAccountStaticComplexPassword -SourceSamAccountNameListFromFile C:\WorkDir\accounts.txt -DestinationList C:\WorkDir\result.txt -Server DC1.domain.local -Credential domain\administrator

    .EXAMPLE
    PS C:\> $users = @("User01","User02","User03")
    PS C:\> Set-ADAccountStaticComplexPassword -SourceSamAccountNameArray $users
    
    .EXAMPLE
    PS C:\> $users = @("User01","User02","User03")
    PS C:\> $users | Set-ADAccountStaticComplexPassword -Server DC1.domain.local -Credential domain\administrator

    .EXAMPLE
    PS C:\> Get-ADUser -Filter {name -like 'User0*'} | Set-ADAccountStaticComplexPassword

    .EXAMPLE
    PS C:\> Get-ADUser -Filter * -Properties whenCreated | where {$_.whenCreated -gt (Get-Date).AddDays(-1)} | Set-ADAccountStaticComplexPassword
#>

    
    if ($input) # Если существует переменная input (в неё заносится ввод через конвейер, если таковой имел место)
    {
        $SourceSamAccountNameArray = $input
    }

    if (($SourceSamAccountNameArray) -and ($SourceSamAccountNameListFromFile)) # Если указаны сразу оба способа передачи входных данных в командлет
    {
        Write-Error -Message "You have specified both source parameters for input. Please specify only one certain source parameter either of SourceSamAccountNameArray or SourceSamAccountNameListFromFile" -RecommendedAction "Specify one certain source parameter either of SourceSamAccountNameArray or SourceSamAccountNameListFromFile" 
        Break
    }
    
    if ((!$SourceSamAccountNameArray) -and (!$SourceSamAccountNameListFromFile)) # Если не указан ни один способ передачи входных данных в командлет
    {
        Write-Error -Message "You haven't specified any source parameter for input. Please specify one certain source parameter either of SourceSamAccountNameArray or SourceSamAccountNameListFromFile" -RecommendedAction "Specify one certain source parameter either of SourceSamAccountNameArray or SourceSamAccountNameListFromFile" 
        Break
    }

    Import-Module ActiveDirectory -ErrorAction Stop # Подключим модуль AD
    
    if ($Credential) # Если указаны учетные данные
    {
	    $script:passwd = Get-Credential -Credential $Credential -ErrorAction Stop # Занесем в переменную полученные учетные данные
	    if ((!$passwd) -or ($passwd.Length -lt 1)) {Break} 
    }

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

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

    Function script:Get-RandomPassword # Генератор сложных паролей на PowerShell
    {
        <#
            .SYNOPSIS
            Get random complex password.
            
            .DESCRIPTION
            This function generate random complex password.

            .PARAMETER PasswordLength
            Set needed length of password.

            .EXAMPLE
            PS C:\> Get-RandomPassword 8

            .EXAMPLE
            PS C:\> 5..7| Get-RandomPassword
        #>

        [CmdletBinding()]   # Добавляем в командлет дополнительные возможности
        Param(
            [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
            [ValidateRange(4,15)]
            [Int]
            $PasswordLength
        )
        Begin{}
        Process{

            $numberchars=0..9 | % {$_.ToString()}
            $lochars = ([char]'a' .. [char]'k') + ([char]'m' .. [char]'n')  + ([char]'p' .. [char]'z') | % {[char]$_} # исключаем из пароля "непонятные" символы
            $hichars = ([char]'A' .. [char]'H') + ([char]'J' .. [char]'N') + ([char]'P' .. [char]'Z') | % {[char]$_}
            $punctchars = [char[]](33..38) + [char[]](40..43) + [char[]](45)

            $PasswordArray = Get-Random -InputObject @($hichars + $lochars + $numberchars + $punctchars) -Count $PasswordLength

            $char1 = Get-Random -InputObject $hichars
            $char2 = Get-Random -InputObject $lochars
            $char3 = Get-Random -InputObject $numberchars
            $char4 = Get-Random -InputObject $punctchars

            $RndIndexArray = Get-Random (0..($PasswordLength-1)) -Count 4

            $PasswordArray[$RndIndexArray[0]] = $char1
            $PasswordArray[$RndIndexArray[1]] = $char2
            $PasswordArray[$RndIndexArray[2]] = $char3
            $PasswordArray[$RndIndexArray[3]] = $char4

            Return [system.string]::Join('', $PasswordArray)

        }
        End{}
    }


    $script:accs = @() # Объявление массива

    if ($SourceSamAccountNameArray) # Если входные данные были определены через массив или по конвейеру
    {
        foreach ($specitem in $SourceSamAccountNameArray)
        {
            if ($specitem.GetType().FullName -eq "Microsoft.ActiveDirectory.Management.ADUser") # Если тип данных является dotNet "ADUser"
            {
                $accs += $specitem.SamAccountName
            }
            else
            {
                $accs += $specitem
            }
        }
    }
    else
    {
        $accs = Get-Content $SourceSamAccountNameListFromFile -ErrorAction Stop # Возьмем список учеток samaccountname из файла
    }

    Write-Host 
    Write-Host
    Write-Host

    $script:result = @() # Объявление массива

    foreach ($acc in $accs) 
    {
        $passd = Get-RandomPassword (Get-Random -Minimum 7 -Maximum 9) # Длина пароля от 7 до 8 символов

        if ($Credential) 
        {
            $ADuser = Get-ADUser -Credential $passwd -Server $Server -Identity $acc -ErrorAction Stop # Занесем в переменную текущего пользователя

            $ADuser | Set-ADUser -Credential $passwd -Server $Server -ChangePasswordAtLogon $false -CannotChangePassword $true -PasswordNeverExpires $true -ErrorAction Stop # Устанавливаем текущему пользователю параметры

            $ADuser | Set-ADAccountPassword -Credential $passwd -Server $Server -Reset -NewPassword (ConvertTo-SecureString -AsPlainText -Force ($passd)) -ErrorAction Stop # Устанавливаем текущему пользователю пароль
        }
        else
        {
            $ADuser = Get-ADUser -Server $Server -Identity $acc -ErrorAction Stop

            $ADuser | Set-ADUser -Server $Server -ChangePasswordAtLogon $false -CannotChangePassword $true -PasswordNeverExpires $true -ErrorAction Stop

            $ADuser | Set-ADAccountPassword -Server $Server -Reset -NewPassword (ConvertTo-SecureString -AsPlainText -Force ($passd)) -ErrorAction Stop
        }

        $result += $acc + "`t`t" + $passd # Собираем логины и пароли в массив через два табулятора
    }

    if ($DestinationList) # Если определен файл, в который необходимо поместить результат
    {
        Out-File -InputObject $result -FilePath $DestinationList -Width 512 -ErrorAction Stop # Куда выкладывать результат
    }
    else
    {
        Remove-Variable -Name passd, passwd, Credential, ADuser -ErrorAction SilentlyContinue
        Return $result # Выводим результат на экран
    }
    
    Remove-Variable -Name passd, passwd, Credential, ADuser, result -ErrorAction SilentlyContinue

}