One of my first PowerShell scripts was to write an inventory that finds all the expired and about to expire user accounts. You can find that script on All expired user accounts and the accounts about to expire.

Now, I made a new version. You have the following options:

  • Create an overview of all the user accounts
  • Create an overview of all the accounts that expired or are about to expire within 7 days.
  • Create an overview of all the disabled user accounts
  • Create an overview of all the locked user accounts

And you can perform the following actions with the selected user accounts:

  • Set 'User must change password at next logon'.
  • Set 'User cannot change password'
  • Set 'Password never expires'
  • Unlock account
  • Enable account
  • Remove the account expiration date
  • Change the expiry date

 

This is what you see when you start the script. 

First, you have to set the default OU. That is your starting point. 

Select the default OU and click [Ok].

If you want to, you can check the option to include the sub-OUs as well. So when you check that box the OUs demo.local/1_OLD_OU/User Accounts and demo.local/1_OLD_OU/User Accounts/Additional OU will be checked.

Get all the user accounts from the OU demo.local/1_OLD_OU/User Accounts.

Get all the user accounts from the OU demo.local/1_OLD_OU/User Accounts and demo.local/1_OLD_OU/User Accounts/Additional OU.

 

Get all the locked userids from the OUs demo.local/1_OLD_OU/User Accounts and demo.local/1_OLD_OU/User Accounts/Additional OU.

 

Select all the accounts by selecting Check or uncheck all users, select Unlock account and click on [Perform Account Actions].

And a confirmation is shown.

Get all the expired and about-to-expire users in the OUs demo.local/1_OLD_OU/User Accounts and demo.local/1_OLD_OU/User Accounts/Additional OU.

Select all the users and select Change the expiry date to: Select a date in the future. In this example, it is November 30th, 2021. Click [Perform Account Actions].

And the confirmation. 

And this is how it is shown in Active Directory. With the script, the date is changed to November 30th, 2021 00:00:00 but that is the same as the end of November 29, 2021

You can select some accounts, you do not have to select all accounts. 

And a confirmation box. 

You can export the data to a CSV file. Change the delimiter character if needed.

And a confirmation box. 

get-help ModifyUserADAccountSettingsInBulk_v02.ps1 -Detailed

NAME
    C:\tmp\ModifyUserADAccountSettingsInBulk_v02\ModifyUserADAccountSettingsInBulk_v02.ps1
    
SYNOPSIS
    Gives an option to change Active Directory User Settings in bulk.
    
    
SYNTAX
    C:\tmp\ModifyUserADAccountSettingsInBulk_v02\ModifyUserADAccountSettingsInBulk_v02.ps1 [-DetailedLogging] 
    [-LogPath <String>] [-Delimiter <String>] [<CommonParameters>]
    
    
DESCRIPTION
    Gives an option to change Active Directory User Settings in bulk.
    

PARAMETERS
    -DetailedLogging [<SwitchParameter>]
        
    -LogPath <String>
        
    -Delimiter <String>
        
    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see 
        about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216). 
    
    -------------------------- EXAMPLE 1 --------------------------
    
    PS C:\>Start the application.
    
    ."ModifyUserADAccountSettingsInBulk_v02.ps1"
    
    
    
    
    -------------------------- EXAMPLE 2 --------------------------
    
    PS C:\>Start the application with detailed logging in a logfile. The default log location is the samen where
    
    the script is located.
    ."ModifyUserADAccountSettingsInBulk_v01.ps2" -DetailedLogging
    
    
    
    
    -------------------------- EXAMPLE 3 --------------------------
    
    PS C:\>Start the application with detailed logging in a logfile. The log location c:\temp is used now.
    
    ."ModifyUserADAccountSettingsInBulk_v01.ps2" -DetailedLogging -LogPath c:\temp
    
    
    
    
    -------------------------- EXAMPLE 4 --------------------------
    
    PS C:\>Start the application, logging on the screen
    
    ."ModifyUserADAccountSettingsInBulk_v01.ps2" -Verbose
    
    
    
    
REMARKS
    To see the examples, type: "get-help 
    C:\tmp\ModifyUserADAccountSettingsInBulk_v02\ModifyUserADAccountSettingsInBulk_v02.ps1 -examples".
    For more information, type: "get-help 
    C:\tmp\ModifyUserADAccountSettingsInBulk_v02\ModifyUserADAccountSettingsInBulk_v02.ps1 -detailed".
    For technical information, type: "get-help 
    C:\tmp\ModifyUserADAccountSettingsInBulk_v02\ModifyUserADAccountSettingsInBulk_v02.ps1 -full".

The help function. 

And now, the script:

<#
.SYNOPSIS
    Gives an option to change Active Directory User Settings in bulk.

.DESCRIPTION
    Gives an option to change Active Directory User Settings in bulk.

.EXAMPLE
     Start the application.
     ."ModifyUserADAccountSettingsInBulk_v02.ps1"

.EXAMPLE
     Start the application with detailed logging in a logfile. The default log location is the samen where
     the script is located.
     ."ModifyUserADAccountSettingsInBulk_v01.ps2" -DetailedLogging

.EXAMPLE
     Start the application with detailed logging in a logfile. The log location c:\temp is used now.
     ."ModifyUserADAccountSettingsInBulk_v01.ps2" -DetailedLogging -LogPath c:\temp

.EXAMPLE
     Start the application, logging on the screen
     ."ModifyUserADAccountSettingsInBulk_v01.ps2" -Verbose


.NOTES
    Author:  Willem-Jan Vroom
    Website: 
    Twitter: @TheStingPilot

v0.1:
   * Initial version. 

v0.2:
   * Changed the date notation of the logfile to yyyy-MM-dd HH-mm-ss, for example '2022-11-14 22-23-09'.
   * Improved error handling regarding the requirements.

#>

[CmdletBinding(DefaultParameterSetName = 'Default')]

Param
  (
   [Parameter(HelpMessage='Enable detailed logging to a log file.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $DetailedLogging,

   [Parameter(HelpMessage='Specify the log directory.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String]   $LogPath = "",

   [Parameter(HelpMessage='Specify the delimiter character. Default = ;')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String]   $Delimiter = ";"
  )

  Clear-Host

# =============================================================================================================================================
# Function block
# =============================================================================================================================================

  Function Display-MessageBox
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       24-May-2021 / 24-Apr-2024 / 09-June-2022
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Display-MessageBox
    =============================================================================================================================================
    .SYNOPSIS

    This function displays a message box.

    The return value is:

    None (no result) 	0
    OK 	                1
    Cancel 	            2
    Yes 	            6
    No. 	            7

    #>

    param
     (
      [Parameter(Mandatory=$True)] [ValidateNotNullOrEmpty()][String] $Text,
      [Parameter(Mandatory=$True)] [ValidateNotNullOrEmpty()][String] $Title,
      [Parameter(Mandatory=$False)][Switch] $GUI,
      [Parameter(Mandatory=$False)][Switch] $Error,
      [Parameter(Mandatory=$False)][ValidateSet('Ok','AbortRetryIgnore','OkCancel','YesNoCancel','YesNo')][String] $Button = "Ok"
     )
         
    If ($GUI)
     {
      If ($Error)
       {
        $Return = [System.Windows.Forms.MessageBox]::Show($this,$Text.Trim(),$Title,$Button,"Error")
       }
        else
       {
        $Return = [System.Windows.Forms.MessageBox]::Show($this,$Text.Trim(),$Title,$Button,"Asterisk")
       }
     }
      else
     {
      Write-Host "$Text`n"
      Return 0
     }

     Return $($Return.value__)
   }

  Function Add-EntryToLogFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       17-May-2020 / Modified 09-May-2022: Includes the function name
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Add-EntryToLogFile
    =============================================================================================================================================
    .SYNOPSIS

    This function adds a line to a log file

    #>

    Param
     (
      [Parameter(Mandatory=$True)]  [string] $Entry,
      [Parameter(Mandatory=$False)] [String] $FunctionName
     )
      
     Write-Verbose "[Function: $FunctionName] - $Entry"
     If ($Global:gblDetailedLogging -and $Global:gblLogFile)
      {
       $Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
       Add-Content $Global:gblLogFile -Value $($Timestamp + "[Function: $FunctionName] - $Entry") -Force -ErrorAction SilentlyContinue
      }
   }

  Function Create-Folder
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Create-Folder
    =============================================================================================================================================
    .SYNOPSIS

    This function creates the given folder.
    The function returns two results:
     1. A message.
     2. True or false (success or failure)

    #>
    
    param
     (
      [String] $FolderName
     )

   $bolResult     = $True
   $ResultMessage = ""

   if(-not(Test-Path $('FileSystem::' + $FolderName)))
    {
     New-Item -Path $FolderName -ItemType Directory | Out-Null
     Sleep 1
     if(test-path $('FileSystem::' + $FolderName))
      {
       $ResultMessage = "The folder '$FolderName' has been created."
      }
       else
      {
       $ResultMessage = "Something went wrong while creating the folder '$FolderName'. "
       $bolResult     = $false
      }
    }
     else
    {
     $ResultMessage = "The folder $FolderName already exists."
    }

    Return $ResultMessage,$bolResult 

   }

  Function Get-AccountInformation
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       13-Nov-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-AccountInformation
    =============================================================================================================================================
    .SYNOPSIS

    Search in an OU to accounts that either are:
     - Locked
     - Expired
     - Will expire soon
     - Disabled
     
     Or all accounts.

     Some help was given via the URL: https://stackoverflow.com/questions/69981152/powershell-expression-gives-no-results/69989948#69989948

    #>
  
    param
     (
      [string] $objOU,
      [Switch] $InclChildOUs,
      [Switch] $IncludeAllAccounts,
      [Switch] $IncludeDisabledAccounts,
      [Switch] $OnlyLockedAccounts,
      [Switch] $OnlyDisabledAccounts,
      [string] $NumDays = 7
     )

    $arrItems            = @()
    $strSearchScope      = "OneLevel"
    
    if($InclChildOUs) {$strSearchScope = "SubTree"} 

    Try
     {
      if($IncludeAllAccounts)
       {
        $arrAllAccounts       = @(Get-ADUser       -SearchBase $objOU -SearchScope $strSearchScope -Filter * -Properties *)                       | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},"Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires" 
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "All accounts are included. Total: $($arrAllAccounts.Count)." 
        Return $arrAllAccounts
       }
      elseif($OnlyLockedAccounts)
       {
        $arrLockedAccounts    = @(Search-ADAccount -LockedOut       -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope)                   | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},@{Name="AccountDisabled";Expression={$True}}, "Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "There are $(($arrLockedAccounts | Measure-Object).Count) locked accounts."
        Return $arrLockedAccounts
       }
      elseif($OnlyDisabledAccounts)
       {
        $arrDisabledAccounts  = @(Search-ADAccount -AccountDisabled -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope)                   | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},@{Name="AccountDisabled";Expression={$True}}, "Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "There are $(($arrDisabledAccounts  | Measure-Object).Count) disabled accounts."
        Return $arrDisabledAccounts
       }
      else
       {
        $arrItems            = @()
        $arrAboutToExp       = @(Search-ADAccount -AccountExpiring -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope -TimeSpan $NumDays) | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},@{Name="ExpiredAccount";Expression={$False}},"Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
        $arrExpired          = @(Search-ADAccount -AccountExpired  -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope)                    | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},@{Name="ExpiredAccount";Expression={$True}}, "Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
        if($IncludeDisabledAccounts)
         {
          $arrDisabledAccounts = @(Search-ADAccount -AccountDisabled -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope)                  | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={(Get-ADOrganizationalUnit -Identity $_.DistinguishedName.Split(',',2)[1] -Properties CanonicalName).CanonicalName}},@{Name="Loginname";Expression={($_."SAMAccountName")}},@{Name="AccountDisabled";Expression={$True}}, "Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
         }

        $arrItems += $arrAboutToExp
        $arrItems += $arrExpired     

        $Message = "There are $($arrItems.Count) expired or about to expire accounts."
        if($IncludeDisabledAccounts)
         {
          $arrItems += $IncludeDisabledAccounts
          $Message  += " That excludes $($arrDisabledAccounts.Count) disabled accounts."
         }
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $Message 
        Return $arrItems
       }
     }
      Catch
     {
      $ErrorMessage = "There is an error: $($_.Exception.Message)."
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $ErrorMessage
      Write-Warning -Message $ErrorMessage
     }
   }

  Function Check-HasElevatedRights
   {

    <#
    .NOTES
    ========================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       11-January-2019 / Modified 22-Apr-2022 / Modified 05-May-2022
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Check-HasElevatedRights
    ========================================================================================================================
    .SYNOPSIS

    This function checks if an user has admin rights. The function returns $True or $False

    Initially, the function was ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'544')
    But that command throws up an error due to the PowerShell ConstrainedMode.
    "S-1-5-32-544" -in (whoami /groups /FO csv | convertfrom-csv).sid does not work either as it will always return 'true', even if not elevated but
    the logged on user is an admin
    So the only good test: check if you can create a file in c:\windows\fonts. If yes, then admin / elevated rights otherwise not. 

    #>

    $RandomFile = ""
    For($a=1; $a -le 8; $a++)
     {
      $RandomFile += [char](Random(97..122))
     }

    $RandomFile = "$($env:windir)\Fonts\$RandomFile.txt"

    Try
     {
      New-Item $RandomFile -Force -ErrorAction SilentlyContinue | Out-Null
      If (test-path($RandomFile))
       {
        Remove-Item $RandomFile -Force
        Return $True
       }
        else
       {
        Return $False
       }
     }
      Catch
     {  
      Return $False
     } 
   }
 
  Function Select-OUWithGUI
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       08 November 2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Select-OUWithGUI
    =============================================================================================================================================
    .SYNOPSIS

    This function gives the user an option to select an OU

    #>

    $arrOUDN = @(Get-ADOrganizationalUnit -Filter *).DistinguishedName
    $arrOUCN = @()
   
    ForEach ($objOUDN in $arrOUDN)
     { 
      $Record        = [ordered] @{"OU"="";"DN"=""}
      $Record."OU"   = (Get-ADOrganizationalUnit -Identity $objOUDN -Properties CanonicalName).CanonicalName
      $Record."DN"   = $objOUDN
      $objRecord     = New-Object PSObject -Property $Record
      $arrOUCN      += $objRecord
     }

     $arrOUCN = $arrOUCN | Sort-Object -Property OU

    # =============================================================================================================================================
    # Add assembly
    # =============================================================================================================================================
          
      Add-Type -AssemblyName System.Windows.Forms
      
    # =============================================================================================================================================
    # Make the form
    # =============================================================================================================================================

      $frmSelectAnOU                                 = New-Object 'System.Windows.Forms.Form'
      $dgvSelectOU                                   = New-Object 'System.Windows.Forms.DataGridView'
      $btnCancel                                     = New-Object 'System.Windows.Forms.Button'
      $btnOK                                         = New-Object 'System.Windows.Forms.Button'

      #
      # frmSelectAnOU 
      #
      $frmSelectAnOU.Controls.Add($dgvSelectOU)
      $frmSelectAnOU.Controls.Add($btnCancel)
      $frmSelectAnOU.Controls.Add($btnOK)
      $frmSelectAnOU.AcceptButton                    = $btnOK
      $frmSelectAnOU.AutoScaleDimensions             = New-Object System.Drawing.SizeF(6, 13)
      $frmSelectAnOU.AutoScaleMode                   = 'Font'
      $frmSelectAnOU.BackColor                       = [System.Drawing.SystemColors]::ControlLight 
      $frmSelectAnOU.ClientSize                      = New-Object System.Drawing.Size(469, 262)
      $frmSelectAnOU.FormBorderStyle                 = 'FixedDialog'
      $frmSelectAnOU.MaximizeBox                     = $False
      $frmSelectAnOU.MinimizeBox                     = $False
      $frmSelectAnOU.Name                            = 'frmSelectAnOU'
      $frmSelectAnOU.StartPosition                   = 'CenterParent'
      $frmSelectAnOU.Text                            = 'Select an OU'
      $frmSelectAnOU.ControlBox                      = $false
      #
      # btnCancel
      #
      $btnCancel.Anchor                              = 'Bottom, Right'
      $btnCancel.Location                            = New-Object System.Drawing.Point(289, 227)
      $btnCancel.Name                                = 'btnCancel'
      $btnCancel.Size                                = New-Object System.Drawing.Size(75, 23)
      $btnCancel.TabIndex                            = 1
      $btnCancel.Text                                = '&Cancel'
      $btnCancel.UseCompatibleTextRendering          = $True
      $btnCancel.UseVisualStyleBackColor             = $True
      #
      # btnOK
      #
      $btnOK.Anchor                                  = 'Bottom, Right'
      $btnOK.Location                                = New-Object System.Drawing.Point(382, 227)
      $btnOK.Name                                    = 'btnOK'
      $btnOK.Size                                    = New-Object System.Drawing.Size(75, 23)
      $btnOK.TabIndex                                = 0
      $btnOK.Text                                    = '&Ok'
      $btnOK.UseCompatibleTextRendering              = $True
      $btnOK.UseVisualStyleBackColor                 = $True
      #
      # dgvSelectOU
      #
      $dgvSelectOU.ColumnHeadersHeightSizeMode       = 'AutoSize'
      $dgvSelectOU.AutoSizeColumnsMode               = 'Fill'
      $dgvSelectOU.Location                          = New-Object System.Drawing.Point(12, 15)
      $dgvSelectOU.Name                              = 'dgvSelectOU'
      $dgvSelectOU.Size                              = New-Object System.Drawing.Size(445, 197)
      $dgvSelectOU.TabIndex = 2
      $dgvSelectOU.SelectionMode = "FullRowSelect"
      $dgvSelectOU.MultiSelect                       = $False
      $dgvSelectOU.ReadOnly                          = $True
      $dgvSelectOU.DataSource                        = $null
      $dgvSelectOU.Rows.Clear()
      $dgvSelectOU.ColumnHeadersHeightSizeMode       = "AutoSize"
      $dgvSelectOU.DataSource = [System.Collections.ArrayList]$arrOUCN
      $dgvSelectOU.Columns["DN"].Visible = $False
        
      $btnOK.add_Click({
       $Row = $dgvSelectOU.SelectedRows
       $Global:ReturnValue = $dgvSelectOU.Rows[$Row.Index].Cells['DN'].Value
       $frmSelectAnOU.Close()   
       })

      $btnCancel.add_Click({
       $Global:ReturnValue = "-"
       $frmSelectAnOU.Close()
       })

      [void]$frmSelectAnOU.ShowDialog()
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "The OU '$Global:ReturnValue' has been selected." 
      Return $Global:ReturnValue
   }

  Function Show-ResultsInAGui
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       13 November 2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Show-ResultsInAGui
    =============================================================================================================================================
    .SYNOPSIS

    This shows the results of the Active Directory actions that are performed.

    #>

    param
      (
       [String] $TextToBeShown
      )

    # =============================================================================================================================================
    # Add assembly
    # =============================================================================================================================================
          
      Add-Type -AssemblyName System.Windows.Forms
      
    # =============================================================================================================================================
    # Make the form
    # =============================================================================================================================================

      $frmResults                                    = New-Object 'System.Windows.Forms.Form'
      $btnClose                                      = New-Object 'System.Windows.Forms.Button'
      $txtBoxWithResults                             = New-Object 'System.Windows.Forms.RichTextBox'
      #
      # frmResults
      #
      $frmResults.Controls.Add($btnClose)
      $frmResults.Controls.Add($txtBoxWithResults)
      $frmResults.AutoScaleDimensions                = New-Object System.Drawing.SizeF(6, 13)
      $frmResults.AutoScaleMode                      = 'Font'
      $frmResults.ClientSize                         = New-Object System.Drawing.Size(459, 523)
      $frmResults.FormBorderStyle                    = 'FixedDialog'
      $frmResults.Name                               = 'frmResults'
      $frmResults.ShowIcon                           = $False
      $frmResults.Text                               = 'Results'
      $frmResults.StartPosition                      = 'CenterParent'
      $frmResults.ControlBox                         = $false
      #
      # btnClose
      #
      $btnClose.Location                             = New-Object System.Drawing.Point(371, 488)
      $btnClose.Name                                 = 'btnClose'
      $btnClose.Size                                 = New-Object System.Drawing.Size(75, 23)
      $btnClose.TabIndex                             = 1
      $btnClose.Text                                 = 'Close'
      $btnClose.UseVisualStyleBackColor              = $True
      $btnClose.Add_Click({
       $frmResults.Close()
       })
      #
      # txtBoxWithResults
      #
      $txtBoxWithResults.Location                    = New-Object System.Drawing.Point(13, 13)
      $txtBoxWithResults.Name                        = 'txtBoxWithResults'
      $txtBoxWithResults.Size                        = New-Object System.Drawing.Size(434, 468)
      $txtBoxWithResults.TabIndex                    = 0
      $txtBoxWithResults.Text                        = $TextToBeShown
      $txtBoxWithResults.ReadOnly                    = $True

      [void]$frmResults.ShowDialog()
   }

# =============================================================================================================================================
# End function block
# =============================================================================================================================================

# =============================================================================================================================================
# Functions, used in the forms blocks
# =============================================================================================================================================

  Function btnExportToCSV
   {
    $CSVLogFile = $Global:gblLogPath + "\"+ $PreFixLogFile + " (" + $Global:PartForCSVFileName + ") " + $($strLastPartOfFileName + ".csv")
    $Global:arrDataForDatagrid | Select-Object -Property "AccountExpirationDate","Name","OU","Loginname","ExpiredAccount","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires" | Export-CSV $CSVLogFile -NoTypeInformation -Force -Delimiter:$($txtDelimiter.Text)
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "A CSV file has been created:"
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "   -Name:      $CSVLogFile"
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "   -Delimiter: $($txtDelimiter.Text)" 
    Display-MessageBox -Text "The CSV file '$CSVLogFile' has been created." -GUI -Title "Done!"
   }

  Function btnDisabledAccounts
   {
    if($chkIncludeSubOU.Checked) {$bolInclChildOUs = $True} else {$bolInclChildOUs = $False}
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "Getting all the disabled user accounts from the OU '$($(Get-ADOrganizationalUnit -Identity $Global:gblCurrentOU -Properties CanonicalName).CanonicalName)'."
    $Global:arrDataForDatagrid   = @(Get-AccountInformation -objOU $Global:gblCurrentOU -OnlyDisabledAccounts -InclChildOUs:$bolInclChildOUs)
    $dgvUsers.DataSource         = [System.Collections.ArrayList]$Global:arrDataForDatagrid
    if(($Global:arrDataForDatagrid.Count) -gt 0)
     {
      $dgvUsers.Columns["AccountDisabled"].Visible = $False
      $btnExportToCSV.Enabled                      = $True
     }
      else
     {
      $btnExportToCSV.Enabled                      = $False
     }
    $Global:PartForCSVFileName   = $btnDisabledAccounts_CSV
   }

  Function btnAllUsers
   {
    if($chkIncludeSubOU.Checked) {$bolInclChildOUs = $True} else {$bolInclChildOUs = $False}
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "Getting all the users from the OU '$($(Get-ADOrganizationalUnit -Identity $Global:gblCurrentOU -Properties CanonicalName).CanonicalName)'."
    $Global:arrDataForDatagrid  = @(Get-AccountInformation -objOU $Global:gblCurrentOU -IncludeAllAccounts -InclChildOUs:$bolInclChildOUs)
    $dgvUsers.DataSource        = [System.Collections.ArrayList]$Global:arrDataForDatagrid
    if(($Global:arrDataForDatagrid.Count) -gt 0)
     {
      $btnExportToCSV.Enabled                      = $True
     }
      else
     {
      $btnExportToCSV.Enabled                      = $False
     }
    $Global:PartForCSVFileName  = $btnAllUsers_CSV
   }

  Function btnExpiredUsers
   {
    if($chkIncludeSubOU.Checked) {$bolInclChildOUs = $True} else {$bolInclChildOUs = $False}
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "Getting all the expired user accounts from the OU '$($(Get-ADOrganizationalUnit -Identity $Global:gblCurrentOU -Properties CanonicalName).CanonicalName)'."
    $Global:arrDataForDatagrid  = @(Get-AccountInformation -objOU $Global:gblCurrentOU -InclChildOUs:$bolInclChildOUs -NumDays 7)
    $dgvUsers.DataSource = [System.Collections.ArrayList]$Global:arrDataForDatagrid
    if(($Global:arrDataForDatagrid.Count) -gt 0)
     {
      $btnExportToCSV.Enabled                      = $True
     }
      else
     {
      $btnExportToCSV.Enabled                      = $False
     }
    $Global:PartForCSVFileName = $btnExpiredUsers_CSV
   }

  Function btnAccountsFromOU
   {
    $tmpText = Select-OUWithGUI
    if($tmpText -ne "-")
     {
      $Global:gblCurrentOU             = $tmpText
      $txtDefaultOU.Text               = $((Get-ADOrganizationalUnit -Identity $($Global:gblCurrentOU) -Properties CanonicalName).CanonicalName)
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "The default OU has been set to $($txtDefaultOU.Text)." 
      $grpButtons.Enabled              = $true
      $grpActions.Enabled              = $True
      $chkIncludeSubOU.Enabled         = $True
     }
   }

  Function btnLockedUsers
   {
    if($chkIncludeSubOU.Checked) {$bolInclChildOUs = $True} else {$bolInclChildOUs = $False}
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "Finding all the locked user account in the OU '$($(Get-ADOrganizationalUnit -Identity $Global:gblCurrentOU -Properties CanonicalName).CanonicalName)'."
    $Global:arrDataForDatagrid   = @(Get-AccountInformation -objOU $Global:gblCurrentOU -InclChildOUs:$bolInclChildOUs -OnlyLockedAccounts)
    $dgvUsers.DataSource         = [System.Collections.ArrayList]$Global:arrDataForDatagrid
    if(($Global:arrDataForDatagrid.Count) -gt 0)
     {
      $dgvUsers.Columns["AccountDisabled"].Visible = $False
      $btnExportToCSV.Enabled                      = $True
     }
      else
     {
      $btnExportToCSV.Enabled                      = $False
     }
    $Global:PartForCSVFileName   = $btnLockedUsers_CSV
   }

  Function btnPerformAccountActions
   {
    $pgbADActions.Visible = $True
    $pgbADActions.Enabled = $True
    $Rows    = $dgvUsers.SelectedRows

    # Count the number of checked checkboxes.

    $CheckedCheckboxes = 0
    if($chkChangeExpiryDate.Checked)       {$CheckedCheckboxes++}
    if($chkUnlockAccount.Checked)          {$CheckedCheckboxes++}
    if($chkEnableAccount.Checked)          {$CheckedCheckboxes++}
    if($chkRemoveAccountExpirat.Checked)   {$CheckedCheckboxes++}
    if($chkChangePassword.Checked)         {$CheckedCheckboxes++}
    if($chkCannotChangePassword.Checked)   {$CheckedCheckboxes++}
    if($chkPasswordNeverExpires.Checked)   {$CheckedCheckboxes++}

    # Number of actions: that is the number of checked checkboxes multiplied by the number of selected users.

    $ActionNumbers = $CheckedCheckboxes * ($Rows.Count)
   
    $ActionNumber  = 1
   
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "There are $CheckedCheckboxes checkboxes checked."
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "There are $($Rows.Count) users selected."
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "That makes $ActionNumbers number of AD actions." 
   
    $LogText = ""
    if($chkChangeExpiryDate.Checked)
     {
      [datetime] $($strDate = $calChangeExpiryDateTo.SelectionStart)
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "The expiration date for user $Loginname is changed to $strDate."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Set-ADAccountExpiration -Identity $Loginname -DateTime $strDate
        $LogText += $tmpText + "`r`n"

        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n" 
     }

    if($chkUnlockAccount.Checked)
     {
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "The account $Loginname will be unlocked."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText 
        Unlock-ADAccount -Identity $Loginname
        $LogText += $tmpText + "`r`n"

        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }

    if($chkEnableAccount.Checked)
     {
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "The account $Loginname will be enabled."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Enable-ADAccount -Identity $Loginname
        $LogText += $tmpText + "`r`n"
        
        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }

    if($chkRemoveAccountExpirat.Checked)
     {
      ForEach($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "The account expiration date will be removed from $Loginname."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Clear-ADAccountExpiration -Identity $Loginname
        $LogText += $tmpText + "`r`n"
         
        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }
     
    if($chkChangePassword.Checked)
     {
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "Setting 'User must change password at next logon' for user: $Loginname."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Set-ADUser -Identity $Loginname -ChangePasswordAtLogon:$true
        $LogText += $tmpText + "`r`n"
         
        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }

    if($chkCannotChangePassword.Checked)
     {
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "Setting 'User cannot change password' for user: $Loginname."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Set-ADUser -Identity $Loginname -CannotChangePassword:$True
        $LogText += $tmpText + "`r`n"
         
        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }

    if($chkPasswordNeverExpires.Checked)
     {
      ForEach ($Row in $Rows)
       {
        $Loginname                      = $dgvUsers.Rows[$Row.Index].Cells['Loginname'].Value
        $tmpText                        = "Setting 'Password never expires' for user: $Loginname."
        Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $tmpText
        Set-ADUser -Identity $Loginname -PasswordNeverExpires:$True
        $LogText += $tmpText + "`r`n"
         
        # Update the progress bar

        $Percentage = $ActionNumber / $ActionNumbers * 100
        $pgbADActions.Value = $Percentage
        $ActionNumber++

        # End update the progress bar        

       }
      $LogText += "`r`n"
     }
      
    $chkChangePassword.Checked        = $False
    $chkCannotChangePassword.Checked  = $False
    $chkPasswordNeverExpires.Checked  = $False
    $chkUnlockAccount.Checked         = $False
    $chkEnableAccount.Checked         = $False
    $chkRemoveAccountExpirat.Checked  = $False
    $chkChangeExpiryDate.Checked      = $False
    $chkAllUsers.Checked              = $False
    $dgvUsers.ClearSelection()
     
    Show-ResultsInAGui -TextToBeShown $LogText 
    $pgbADActions.Visible             = $False
    $pgbADActions.Enabled             = $False
   }

# =============================================================================================================================================
# End functions, used in the forms blocks.
# =============================================================================================================================================

# =============================================================================================================================================
# Define the variables
# =============================================================================================================================================

  $PowerShellLanguageMode                        = $ExecutionContext.SessionState.LanguageMode
  $Global:gblFullLanguage                        = $PowerShellLanguageMode -eq "FullLanguage"
  $Global:gblDetailedLogging                     = $DetailedLogging
  $Global:gblLogPath                             = $LogPath
  $Global:gblDelimiter                           = $Delimiter
  $Global:gblCurrentOU                           = ""
  $arrUsers                                      = @()
  $strCurrentDir                                 = Split-Path -parent $MyInvocation.MyCommand.Definition
  $MinimumWidth                                  = 700
  $MinimumHeight                                 = 1030
  $ApplicationName                               = "Modify User AD Account Settings in bulk"
  $ApplicationVersion                            = "0.2"

  $ErrorNumber                                   = 0
  $ErrorText                                     = ""

  if(-not($Global:gblLogPath))
   {
    $Global:gblLogPath         = Split-Path -parent $MyInvocation.MyCommand.Definition
   }

  if(-not(test-path $Global:gblLogPath))
   {
    $Returntext, $bolResult    = Create-Folder -FolderName $Global:gblLogPath
    if($bolResult)
     {
      $Message = $Returntext
     }
      else
     {
      Write-Error $Returntext -Category WriteError
      Exit 2
     }
   }

# =============================================================================================================================================
# Define the results file. This file contains all the results.
# It is saved as yyyy-MM-dd HH-mm-ss, for example 2022-11-14 22-23-09
# =============================================================================================================================================
 
  $strLastPartOfFileName                         = " ($((Get-Date -format "yyyy-MM-dd HH-mm-ss").ToString()))"
  $PreFixLogFile                                 = $ApplicationName.Replace(" ","")
   
  if($Global:gblDetailedLogging)
   {
    $Global:gblLogFile = $Global:gblLogPath + "\"+ $PreFixLogFile + $($strLastPartOfFileName + ".log")
    New-Item $Global:gblLogFile -ItemType File -Force | Out-Null
   }

  If ($Message)
   {
    If ($bolError)
     {
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "$Message"
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "This script will now quit."
      Write-Error $Message -Category CloseError
      Exit 3
     }
      else
     {
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "[Warning]: $Message"
     }
   }

# =============================================================================================================================================
# Find all the arguments and put them in the log file
# Source: https://ss64.com/ps/psboundparameters.html
# =============================================================================================================================================

  If ($Global:gblFullLanguage)
   {
    $Global:TableWithParameters  = @()
    $RecordWithParameters = [ordered] @{"Key"     = "";
                                        "Value"   = ""}
  
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "***** Parameters part           *****"
  
    ForEach($boundparam in $PSBoundParameters.GetEnumerator()) 
     {
      $tmpValue                     = $($boundparam.Value)
      $Value                        = ""
      If ($tmpValue -is [array])
       {
        ForEach ($object in $tmpValue)
         {
          If (-not($value))
           {
            $Value = $object
           }
            else
           {
            $Value +=",$($object)"
           }
         }
       }
        else
       {
        $Value = $tmpValue
       }
      Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "Key: $($boundparam.Key) Value: $Value" 
     }
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "***** End Parameters part       *****`r`n" 
   }
    else
   {
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry "The parameters are not written to the logfile due to PowerShell ConstrainedMode."
   }

# =============================================================================================================================================
# Define the error number and messages
# =============================================================================================================================================

  $Error01 = "The Powershell Language mode '$PowerShellLanguageMode' is not supported."
  $Error02 = "The current user has no admin rights. Please, rerun the script with elevated rights."
  $Error04 = "The detected screen width of $DetectedWidth is less than the minimum width of $MinimumWidth."
  $Error08 = "The detected screen height of $DetectedHeight is less than of the minimum height of $MinimumHeight."
  $Error16 = "The module ActiveDirectory is not found. Thus quitting."

# =============================================================================================================================================
#  Do some error handling.
# =============================================================================================================================================

  If (-not($Global:gblFullLanguage))                       {$ErrorNumber += 1}
  if (-not(Check-HasElevatedRights))                       {$ErrorNumber += 2}
  if (-not(Get-Module -ListAvailable ActiveDirectory))     {$ErrorNumber += 16}

# =============================================================================================================================================
# Add assemblies.
# =============================================================================================================================================

  If ($Global:gblFullLanguage)
   {
    Add-Type -AssemblyName System.Windows.Forms


  # =============================================================================================================================================
  # Check the screenwidth and screenheight. If too small than falling back to silent mode.
  # Source: https://stackoverflow.com/questions/7967699/get-screen-resolution-using-wmi-powershell-in-windows-7
  # =============================================================================================================================================

    [System.Windows.Forms.Application]::EnableVisualStyles()
    $DetectedWidth  = ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize).Width
    $DetectedHeight = ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize).Height
    If ($DetectedWidth -le $MinimumWidth)                  {$ErrorNumber += 4}
    If ($DetectedHeight -le $MinimumHeight)                {$ErrorNumber += 8}
   }

# =============================================================================================================================================
# Error handling.
# =============================================================================================================================================

  If (($ErrorNumber -band 1) -eq 1)                                                         {$ErrorText = $Error01}
  If (($ErrorNumber -band 2) -eq 2)    {If ($ErrorText) {$ErrorText += "`n`n$Error02"} else {$ErrorText = $Error02}}
  If (($ErrorNumber -band 4) -eq 4)    {If ($ErrorText) {$ErrorText += "`n`n$Error04"} else {$ErrorText = $Error04}}
  If (($ErrorNumber -band 8) -eq 8)    {If ($ErrorText) {$ErrorText += "`n`n$Error08"} else {$ErrorText = $Error08}}
  If (($ErrorNumber -band 16) -eq 16)  {If ($ErrorText) {$ErrorText += "`n`n$Error16"} else {$ErrorText = $Error16}}

  If ($ErrorNumber -gt 0)
   {
    Add-EntryToLogFile -FunctionName $($MyInvocation.MyCommand.Name) -Entry $ErrorText
    $Null = Display-MessageBox -Text $ErrorText -GUI:$Global:gblFullLanguage -Error -Title "Error."
    Exit $ErrorNumber
   }

# =============================================================================================================================================
# Forms block
# =============================================================================================================================================

  $btnDisabledAccounts_CSV                          = "Get all the disabled user accounts"
  $btnAllUsers_CSV                                  = "Get all user accounts"
  $btnExpiredUsers_CSV                              = "Get all the expired user accounts and the user accounts that will expire within 7 days"
  $btnLockedUsers_CSV                               = "Get all the locked user accounts"

  [System.Windows.Forms.Application]::EnableVisualStyles()
  $frmModifyUserSettings                            = New-Object 'System.Windows.Forms.Form'
  $chkIncludeSubOU                                  = New-Object 'System.Windows.Forms.CheckBox'
  $lblDelimter                                      = New-Object 'System.Windows.Forms.Label'
  $txtDelimiter                                     = New-Object 'System.Windows.Forms.TextBox'
  $btnExportToCSV                                   = New-Object 'System.Windows.Forms.Button'
  $pgbADActions                                     = New-Object 'System.Windows.Forms.ProgressBar'
  $lblDefaultOU                                     = New-Object 'System.Windows.Forms.Label'
  $txtDefaultOU                                     = New-Object 'System.Windows.Forms.TextBox'
  $chkAllUsers                                      = New-Object 'System.Windows.Forms.CheckBox'
  $grpActions                                       = New-Object 'System.Windows.Forms.GroupBox'
  $chkRemoveAccountExpirat                          = New-Object 'System.Windows.Forms.CheckBox'
  $btnPerformAccountActions                         = New-Object 'System.Windows.Forms.Button'
  $calChangeExpiryDateTo                            = New-Object 'System.Windows.Forms.MonthCalendar'
  $chkUnlockAccount                                 = New-Object 'System.Windows.Forms.CheckBox'
  $chkChangeExpiryDate                              = New-Object 'System.Windows.Forms.CheckBox'
  $chkEnableAccount                                 = New-Object 'System.Windows.Forms.CheckBox'
  $chkPasswordNeverExpires                          = New-Object 'System.Windows.Forms.CheckBox'
  $chkCannotChangePassword                          = New-Object 'System.Windows.Forms.CheckBox'
  $chkChangePassword                                = New-Object 'System.Windows.Forms.CheckBox'
  $dgvUsers                                         = New-Object 'System.Windows.Forms.DataGridView'
  $grpButtons                                       = New-Object 'System.Windows.Forms.GroupBox'
  $btnDisabledAccounts                              = New-Object 'System.Windows.Forms.Button'
  $btnAllUsers                                      = New-Object 'System.Windows.Forms.Button'
  $btnExpiredUsers                                  = New-Object 'System.Windows.Forms.Button'
  $btnAccountsFromOU                                = New-Object 'System.Windows.Forms.Button'
  $btnLockedUsers                                   = New-Object 'System.Windows.Forms.Button'
  $btnQuit                                          = New-Object 'System.Windows.Forms.Button'
  #
  # frmModifyUserSettings
  #
  $frmModifyUserSettings.Controls.Add($chkIncludeSubOU)
  $frmModifyUserSettings.Controls.Add($lblDelimter)
  $frmModifyUserSettings.Controls.Add($txtDelimiter)
  $frmModifyUserSettings.Controls.Add($btnExportToCSV)
  $frmModifyUserSettings.Controls.Add($pgbADActions)
  $frmModifyUserSettings.Controls.Add($lblDefaultOU)
  $frmModifyUserSettings.Controls.Add($txtDefaultOU)
  $frmModifyUserSettings.Controls.Add($btnAccountsFromOU)
  $frmModifyUserSettings.Controls.Add($chkAllUsers)
  $frmModifyUserSettings.Controls.Add($grpActions)
  $frmModifyUserSettings.Controls.Add($dgvUsers)
  $frmModifyUserSettings.Controls.Add($grpButtons)
  $frmModifyUserSettings.Controls.Add($btnQuit)
  $frmModifyUserSettings.AutoScaleDimensions        = New-Object System.Drawing.SizeF(6, 13)
  $frmModifyUserSettings.AutoScaleMode              = 'Font'
  $frmModifyUserSettings.CancelButton               = $btnQuit
  $frmModifyUserSettings.ClientSize                 = New-Object System.Drawing.Size(663, 993)
  $frmModifyUserSettings.FormBorderStyle            = 'FixedDialog'
  $frmModifyUserSettings.MaximizeBox                = $False
  $frmModifyUserSettings.MinimizeBox                = $False
  $frmModifyUserSettings.Name                       = 'frmModifyUserSettings'
  $frmModifyUserSettings.StartPosition              = 'CenterScreen'
  $frmModifyUserSettings.Text                       = "$ApplicationName $ApplicationVersion"
  #
  # chkIncludeSubOU
  #
  $chkIncludeSubOU.Location                         = New-Object System.Drawing.Point(536, 192)
  $chkIncludeSubOU.Name                             = 'chkIncludeSubOU'
  $chkIncludeSubOU.Size                             = New-Object System.Drawing.Size(109, 24)
  $chkIncludeSubOU.TabIndex                         = 15
  $chkIncludeSubOU.Text                             = 'Include sub OUs'
  $chkIncludeSubOU.UseVisualStyleBackColor          = $True
  $chkIncludeSubOU.Enabled                          = $False
  #
  # lblDelimter
  #
  $lblDelimter.AutoSize                             = $True
  $lblDelimter.Location                             = New-Object System.Drawing.Point(58, 668)
  $lblDelimter.Name                                 = 'lblDelimter'
  $lblDelimter.Size                                 = New-Object System.Drawing.Size(149, 13)
  $lblDelimter.TabIndex                             = 14
  $lblDelimter.Text                                 = 'Specify the delimiter character'
  #
  # txtDelimiter
  #
  $txtDelimiter.Location                            = New-Object System.Drawing.Point(32, 663)
  $txtDelimiter.Name                                = 'txtDelimiter'
  $txtDelimiter.Size                                = New-Object System.Drawing.Size(20, 20)
  $txtDelimiter.TabIndex                            = 13
  $txtDelimiter.Text                                = $Global:gblDelimiter
  #
  # btnExportToCSV
  #
  $btnExportToCSV.Location                          = New-Object System.Drawing.Point(454, 663)
  $btnExportToCSV.Name                              = 'btnExportToCSV'
  $btnExportToCSV.Size                              = New-Object System.Drawing.Size(198, 23)
  $btnExportToCSV.TabIndex                          = 12
  $btnExportToCSV.Text                              = 'Export results to CSV'
  $btnExportToCSV.UseVisualStyleBackColor           = $True
  $btnExportToCSV.Enabled                           = $False
  $btnExportToCSV.Add_Click({btnExportToCSV})
  #
  # pgbADActions
  #
  $pgbADActions.Location                            = New-Object System.Drawing.Point(20, 958)
  $pgbADActions.Name                                = 'pgbADActions'
  $pgbADActions.Size                                = New-Object System.Drawing.Size(462, 23)
  $pgbADActions.Style                               = 'Continuous'
  $pgbADActions.TabIndex                            = 11
  $pgbADActions.Value                               = 0
  $pgbADActions.Visible                             = $False
  #
  # lblDefaultOU
  #
  $lblDefaultOU.AutoSize                            = $True
  $lblDefaultOU.Location                            = New-Object System.Drawing.Point(18, 195)
  $lblDefaultOU.Name                                = 'lblDefaultOU'
  $lblDefaultOU.Size                                = New-Object System.Drawing.Size(63, 13)
  $lblDefaultOU.TabIndex                            = 10
  $lblDefaultOU.Text                                = 'Default OU:'
  #
  # txtDefaultOU
  #
  $txtDefaultOU.Location                            = New-Object System.Drawing.Point(87, 192)
  $txtDefaultOU.Name                                = 'txtDefaultOU'
  $txtDefaultOU.Size                                = New-Object System.Drawing.Size(421, 20)
  $txtDefaultOU.TabIndex                            = 9
  #
  # chkAllUsers
  #
  $chkAllUsers.Location                             = New-Object System.Drawing.Point(12, 218)
  $chkAllUsers.Name                                 = 'chkAllUsers'
  $chkAllUsers.Size                                 = New-Object System.Drawing.Size(178, 24)
  $chkAllUsers.TabIndex                             = 8
  $chkAllUsers.Text                                 = 'Check or uncheck all users'
  $chkAllUsers.UseVisualStyleBackColor              = $True
  $chkAllUsers.Add_CheckedChanged({if($chkAllUsers.Checked){$dgvUsers.SelectAll()} else {$dgvUsers.ClearSelection()}})
  #
  # grpActions
  #
  $grpActions.Controls.Add($btnPerformAccountActions)
  $grpActions.Controls.Add($chkRemoveAccountExpirat)
  $grpActions.Controls.Add($calChangeExpiryDateTo)
  $grpActions.Controls.Add($chkUnlockAccount)
  $grpActions.Controls.Add($chkChangeExpiryDate)
  $grpActions.Controls.Add($chkEnableAccount)
  $grpActions.Controls.Add($chkPasswordNeverExpires)
  $grpActions.Controls.Add($chkCannotChangePassword)
  $grpActions.Controls.Add($chkChangePassword)
  $grpActions.Location                              = New-Object System.Drawing.Point(13, 692)
  $grpActions.Name                                  = 'grpActions'
  $grpActions.Size                                  = New-Object System.Drawing.Size(639, 260)
  $grpActions.TabIndex                              = 7
  $grpActions.TabStop                               = $False
  $grpActions.Text                                  = 'Select one or more actions to perform'
  $grpActions.Enabled                               = $False
  #
  # chkRemoveAccountExpirat
  #
  $chkRemoveAccountExpirat.Location                 = New-Object System.Drawing.Point(7, 170)
  $chkRemoveAccountExpirat.Name                     = 'chkRemoveAccountExpirat'
  $chkRemoveAccountExpirat.Size                     = New-Object System.Drawing.Size(284, 25)
  $chkRemoveAccountExpirat.TabIndex                 = 9
  $chkRemoveAccountExpirat.Text                     = 'Remove account expiration date'
  $chkRemoveAccountExpirat.UseVisualStyleBackColor  = $True
  #
  # btnPerformAccountActions
  #
  $btnPerformAccountActions.Location                = New-Object System.Drawing.Point(7, 218)
  $btnPerformAccountActions.Name                    = 'btnPerformAccountActions'
  $btnPerformAccountActions.Size                    = New-Object System.Drawing.Size(620, 23)
  $btnPerformAccountActions.TabIndex                = 8
  $btnPerformAccountActions.Text                    = 'Perform Account Actions'
  $btnPerformAccountActions.UseVisualStyleBackColor = $True
  $btnPerformAccountActions.Add_Click({btnPerformAccountActions})
  #
  # calChangeExpiryDateTo
  #
  $calChangeExpiryDateTo.Location                   = New-Object System.Drawing.Point(400, 44)
  $calChangeExpiryDateTo.Name                       = 'calChangeExpiryDateTo'
  $calChangeExpiryDateTo.TabIndex                   = 7
  #
  # chkUnlockAccount
  #
  $chkUnlockAccount.Location                        = New-Object System.Drawing.Point(7, 110)
  $chkUnlockAccount.Name                            = 'chkUnlockAccount'
  $chkUnlockAccount.Size                            = New-Object System.Drawing.Size(284, 25)
  $chkUnlockAccount.TabIndex                        = 6
  $chkUnlockAccount.Text                            = 'Unlock account'
  $chkUnlockAccount.UseVisualStyleBackColor         = $True
  #
  # chkChangeExpiryDate
  #
  $chkChangeExpiryDate.Location                     = New-Object System.Drawing.Point(385, 20)
  $chkChangeExpiryDate.Name                         = 'chkChangeExpiryDate'
  $chkChangeExpiryDate.Size                         = New-Object System.Drawing.Size(242, 24)
  $chkChangeExpiryDate.TabIndex                     = 4
  $chkChangeExpiryDate.Text                         = 'Change the expiry date to:'
  $chkChangeExpiryDate.UseVisualStyleBackColor      = $True
  #
  # chkEnableAccount
  #
  $chkEnableAccount.Location                        = New-Object System.Drawing.Point(7, 140)
  $chkEnableAccount.Name                            = 'chkEnableAccount'
  $chkEnableAccount.Size                            = New-Object System.Drawing.Size(284, 25)
  $chkEnableAccount.TabIndex                        = 3
  $chkEnableAccount.Text                            = 'Enable account'
  $chkEnableAccount.UseVisualStyleBackColor         = $True
  #
  # chkPasswordNeverExpires
  #
  $chkPasswordNeverExpires.Location                 = New-Object System.Drawing.Point(7, 80)
  $chkPasswordNeverExpires.Name                     = 'chkPasswordNeverExpires'
  $chkPasswordNeverExpires.Size                     = New-Object System.Drawing.Size(284, 25)
  $chkPasswordNeverExpires.TabIndex                 = 2
  $chkPasswordNeverExpires.Text                     = 'Password never expires'
  $chkPasswordNeverExpires.UseVisualStyleBackColor  = $True
  #
  # chkCannotChangePassword
  #
  $chkCannotChangePassword.Location                 = New-Object System.Drawing.Point(6, 50)
  $chkCannotChangePassword.Name                     = 'chkCannotChangePassword'
  $chkCannotChangePassword.Size                     = New-Object System.Drawing.Size(284, 25)
  $chkCannotChangePassword.TabIndex                 = 1
  $chkCannotChangePassword.Text                     = 'User cannot change password'
  $chkCannotChangePassword.UseVisualStyleBackColor  = $True
  $chkCannotChangePassword.Add_CheckedChanged({if($chkCannotChangePassword.Checked){$chkChangePassword.Enabled = $False} else {$chkChangePassword.Enabled = $True}})
  #
  # chkChangePassword
  #
  $chkChangePassword.Location                       = New-Object System.Drawing.Point(6, 20)
  $chkChangePassword.Name                           = 'chkChangePassword'
  $chkChangePassword.Size                           = New-Object System.Drawing.Size(284, 25)
  $chkChangePassword.TabIndex                       = 0
  $chkChangePassword.Text                           = 'User must change password at next logon'
  $chkChangePassword.UseVisualStyleBackColor        = $True
  $chkChangePassword.Add_CheckedChanged({if($chkChangePassword.Checked){$chkCannotChangePassword.Enabled = $False} else {$chkCannotChangePassword.Enabled = $True}})
  #
  # dgvUsers
  #
  $dgvUsers.ColumnHeadersHeightSizeMode             = 'AutoSize'
  $dgvUsers.Location                                = New-Object System.Drawing.Point(14, 248)
  $dgvUsers.Name                                    = 'dgvUsers'
  $dgvUsers.Size                                    = New-Object System.Drawing.Size(638, 407)
  $dgvUsers.TabIndex                                = 6
  $dgvUsers.ReadOnly                                = $True
  $dgvUsers.ColumnHeadersHeightSizeMode             = 'AutoSize'
  $dgvUsers.AutoSizeRowsMode                        = 'AllCells'
  $dgvUsers.AutoSizeColumnsMode                     = 'AllCells'
  #
  # grpButtons
  #
  $grpButtons.Controls.Add($btnDisabledAccounts)
  $grpButtons.Controls.Add($btnAllUsers)
  $grpButtons.Controls.Add($btnExpiredUsers)
  $grpButtons.Controls.Add($btnLockedUsers)
  $grpButtons.Location                              = New-Object System.Drawing.Point(12, 12)
  $grpButtons.Name                                  = 'grpButtons'
  $grpButtons.Size                                  = New-Object System.Drawing.Size(639, 143)
  $grpButtons.TabIndex                              = 5
  $grpButtons.TabStop                               = $False
  $grpButtons.Text                                  = 'Make your choice'
  $grpButtons.Enabled                               = $False
  #
  # btnDisabledAccounts
  #
  $btnDisabledAccounts.Location                     = New-Object System.Drawing.Point(6, 110)
  $btnDisabledAccounts.Name                         = 'btnDisabledAccounts'
  $btnDisabledAccounts.Size                         = New-Object System.Drawing.Size(627, 25)
  $btnDisabledAccounts.TabIndex                     = 5
  $btnDisabledAccounts.Text                         = $btnDisabledAccounts_CSV
  $btnDisabledAccounts.UseVisualStyleBackColor      = $True
  $btnDisabledAccounts.Enabled                      = $True
  $btnDisabledAccounts.Add_Click({btnDisabledAccounts})
  #
  # btnAllUsers
  #
  $btnAllUsers.Location                             = New-Object System.Drawing.Point(6, 20)
  $btnAllUsers.Name                                 = 'btnAllUsers'
  $btnAllUsers.Size                                 = New-Object System.Drawing.Size(627, 25)
  $btnAllUsers.TabIndex                             = 4
  $btnAllUsers.Text                                 = $btnAllUsers_CSV
  $btnAllUsers.UseVisualStyleBackColor              = $True
  $btnAllUsers.Enabled                              = $True
  $btnAllUsers.add_Click({btnAllUsers})
  #
  # btnExpiredUsers
  #
  $btnExpiredUsers.Location                         = New-Object System.Drawing.Point(6, 50)
  $btnExpiredUsers.Name                             = 'btnExpiredUsers'
  $btnExpiredUsers.Size                             = New-Object System.Drawing.Size(627, 25)
  $btnExpiredUsers.TabIndex                         = 1
  $btnExpiredUsers.Text                             = $btnExpiredUsers_CSV
  $btnExpiredUsers.UseVisualStyleBackColor          = $True
  $btnExpiredUsers.Enabled                          = $True
  $btnExpiredUsers.add_Click({btnExpiredUsers})
  #
  # btnAccountsFromOU
  #
  $btnAccountsFromOU.Location                       = New-Object System.Drawing.Point(19, 161)
  $btnAccountsFromOU.Name                           = 'btnAccountsFromOU'
  $btnAccountsFromOU.Size                           = New-Object System.Drawing.Size(627, 25)
  $btnAccountsFromOU.TabIndex                       = 3
  $btnAccountsFromOU.Text                           = 'Sets the default OU'
  $btnAccountsFromOU.UseVisualStyleBackColor        = $True
  $btnAccountsFromOU.add_Click({btnAccountsFromOU})
  #
  # btnLockedUsers
  #
  $btnLockedUsers.Location                          = New-Object System.Drawing.Point(6, 80)
  $btnLockedUsers.Name                              = 'btnLockedUsers'
  $btnLockedUsers.Size                              = New-Object System.Drawing.Size(627, 25)
  $btnLockedUsers.TabIndex                          = 2
  $btnLockedUsers.Text                              = $btnLockedUsers_CSV
  $btnLockedUsers.UseVisualStyleBackColor           = $True
  $btnLockedUsers.Enabled                           = $True
  $btnLockedUsers.add_Click({btnLockedUsers})
  #
  # btnQuit
  #
  $btnQuit.Anchor                                   = 'Bottom, Right'
  $btnQuit.DialogResult                             = 'OK'
  $btnQuit.Location                                 = New-Object System.Drawing.Point(488, 958)
  $btnQuit.Name                                     = 'btnQuit'
  $btnQuit.Size                                     = New-Object System.Drawing.Size(163, 23)
  $btnQuit.TabIndex                                 = 0
  $btnQuit.Text                                     = '&Quit'
  $btnQuit.UseCompatibleTextRendering               = $True
  $btnQuit.UseVisualStyleBackColor                  = $True
 
  [void]$frmModifyUserSettings.ShowDialog()
  $frmModifyUserSettings.Dispose()

# =============================================================================================================================================
# End application
# =============================================================================================================================================


Please 'unblock' the Powershell script and/or the batch file after extracting the ZIP file. 

Unblock
Unblock