ELM-ADTools.psm1

Function Export-Users {

Param(
    [int]$Days
) # end param


# Get path friendly date (dd-mm-yy)
$Today = Get-Date -UFormat %d-%m-%y

# Get ALL users in domain
$AllUsers = Get-ADUser -filter * -Properties *

# Filter uses only if Days variable has been assigned
if ($Days) {

    # Filter to those logged in within last 90 days
    $AllUsers = $AllUsers | Where-Object  lastlogondate -gt ((Get-Date).AddDays(-$Days))
    }

# Output to a CSV file with firstname, lastname, username, and also OU they were in
$AllUsers |
select givenname, surname, samaccountname, distinguishedname |
ConvertTo-Csv -NoTypeInformation |
Out-File -FilePath "$Home\Desktop\User_Export-$Today.csv"

}
function Get-InactiveAccounts {

    Param(
        [int] $DaysInactive = 30,
        [Parameter(Mandatory)]  
        [ValidateSet('Users','Computers')]
        $Object
        )

    if ($Object -eq 'Users') {
        
        Search-ADAccount -UsersOnly -AccountInactive -TimeSpan "$DaysInactive.00:00:00" | Sort LastLogonDate | Select Name,LastLogonDate

    }

    if ($Object -eq 'Computers') {
        
        Search-ADAccount -ComputersOnly -AccountInactive -TimeSpan "$DaysInactive.00:00:00" | Sort LastLogonDate | Select Name,LastLogonDate
    
    }

}
function Get-OrphanedFolders {
    
    param(
        [Parameter(Mandatory=$true)]
        [string]$ProfileDir,
        [Parameter(Mandatory=$true)]
        [string]$HomeDir
    )

$Date = Get-Date -UFormat %Y-%m-%d

###########################
##### Home FOLDERS #####
###########################

# create an array to put all folders in
$AllHomeFolders = @()

# scan through subfolders and add them to the array
$AllHomeFolders += (Get-ChildItem $HomeDir -Exclude Archive | Get-ChildItem)

# create an array to put orphaned folders in
$OrphanedHomeFolders = @()

# test each folder name against active directory samaccountnames and if they dont exist place them in the orphaned folders array
Foreach ($HomeFolder in $AllHomeFolders) {

    try {

            Get-ADUser -Identity $HomeFolder.Name | Out-Null

    } catch {

        $OrphanedHomeFolders += $HomeFolder

    }

}

# display the orphaned folders that were found
Write-Host "here are the current oprhaned Home folders"

$OrphanedHomeFolders | sort lastaccesstime | ft name,fullname,lastaccesstime

# prompt user if they want to archive them
$confirm = Read-Host "Would you like to move these to an archive folder (y/n)"

# test for archive folder and create it if it does not exist
if ($confirm -eq "y") {

    $HomeArchiveDir = "$HomeDir\Archive\$Date"

    if (!(Test-Path $HomeArchiveDir)) {

        New-Item $HomeArchiveDir -ItemType Directory

        }

# move all orphaned folders to the archive folder
    $OrphanedHomeFolders | Move-Item -Destination $HomeArchiveDir -Force
    Write-Host "The folders have been successfully moved to $HomeArchiveDir" -ForegroundColor Green

}

###########################
##### Profile FOLDERS #####
###########################

# create an array to put all folders in
$AllProfileFolders = @()

# scan through subfolders and add them to the array
$AllProfileFolders += (Get-ChildItem $ProfileDir -Exclude Archive | Get-ChildItem)

# create an array to put orphaned folders in
$OrphanedProfileFolders = @()

# test each folder name against active directory samaccountnames and if they dont exist place them in the orphaned folders array
Foreach ($ProfileFolder in $AllProfileFolders) {

    try {

            Get-ADUser -Identity $ProfileFolder.Name.Replace(".V6","") | Out-Null

    } catch {

        $OrphanedProfileFolders += $ProfileFolder

    }

}

# display the orphaned folders that were found
Write-Host "here are the current oprhaned Profile folders"

$OrphanedProfileFolders | sort lastaccesstime | ft name,fullname,lastaccesstime

# prompt user if they want to archive them
$confirm = Read-Host "Would you like to move these to an archive folder (y/n)"

# test for archive folder and create it if it does not exist
if ($confirm -eq "y") {

    $ProfileArchiveDir = "$ProfileDir\Archive\$Date"

    if (!(Test-Path $ProfileArchiveDir)) {

        New-Item $ProfileArchiveDir -ItemType Directory

        }

# move all orphaned folders to the archive folder
    $OrphanedProfileFolders | Move-Item -Destination $ProfileArchiveDir -Force
    Write-Host "The folders have been successfully moved to $ProfileArchiveDir" -ForegroundColor Green

}


}



Function Import-Users {

<#
.<help keyword>
<help content>
#>



#Requires -RunAsAdministrator
    
    [cmdletbinding(SupportsShouldProcess=$True)]

    Param(
        [Parameter(Mandatory=$true)]
        [string]$csv,
        
        [Parameter(Mandatory=$true)]
        [ValidateSet('johnd','john.d','jdoe','j.doe','john.doe')]
        [string]$UsernameFormat,
        
        [Parameter(Mandatory=$true)]
        [ValidateSet('Staff','Office','Students')]
        [string]$UserType,
        
        [Parameter(Mandatory=$true)]
        [string]$HomeShare,
        
        [Parameter(Mandatory=$true)]
        [string]$ProfileShare,
        
        [string]$Password,
        
        [string]$LogPath = "$env:USERPROFILE\Desktop"
    )


# Setup logging

# Set Variables
$Date = Get-Date -UFormat "%Y-%m-%d"
$LogFolder = "User Import Logs"
$LogFile = "$Date Import Log.csv"
$Log = "$LogPath\$LogFolder\$LogFile"

# Create Log
New-Item $Log -Force

# Store the data from the CSV in the $Users variable
$Users = Import-csv $csv

# Defines what the CSV headers should be

$CorrectHeaders = @(
    'firstname'
    'lastname'
    'description'
    )

# Assigns the actual headers to a variable

$ImportHeaders = (($Users[0].psobject.properties.name))

# Counts the differencnes

$HeaderDiffs = (Compare-Object $CorrectHeaders $ImportHeaders).count

# Throws an error if the differences are not 0

if ($HeaderDiffs -ne '0') {

    Throw "Check your CSV Headers! Should be 'firstname,lastname,description'"

}

# Set some Variables

$Domain = (Get-ADDomain).name
$FullDomain = (Get-ADDomain).dnsroot
$DomainRoot = (Get-ADDomain).DistinguishedName
$HomePath = "$HomeShare\$UserType"
$ProfilePath = "$ProfileShare\$UserType"
$bar = "*" * 125

# Tests for an "Imported Users" OU at root of domain and if it does not exist then it creates it

$ImportOU = "OU=Imported Users,$DomainRoot"

try {
    Get-ADOrganizationalUnit -Identity $ImportOU | Out-Null
    } catch {
    New-ADOrganizationalUnit -Name "Imported Users" -Path $DomainRoot
    }

# Check Home & Profile paths exist

if (!(Test-Path $HomePath)) {
    Throw "Could not find $HomePath!"
}
    
if (!(Test-Path $ProfilePath)) {
    Throw "Could not find $ProfilePath!"
}

# Loop through each row containing user details in the CSV file

foreach ($User in $Users) {

    # Read user data from each field in each row and assign the data to a variable as below
        
    $Firstname      = $User.firstname 
    $Lastname      = $User.lastname
    $FullName    = "$Firstname $Lastname"
    $Description = $User.description

    # Select username format

    if ($UsernameFormat -eq "johnd") {
        $Username = $Firstname + $Lastname.substring(0,1)
        
    }

    if ($UsernameFormat -eq "john.d") {
        $Username = $Firstname + "." + $Lastname.substring(0,1)
    }

    if ($UsernameFormat -eq "jdoe") {
        $Username = $Firstname.substring(0,1) + $Lastname
    }

    if ($UsernameFormat -eq "j.doe") {
        $Username = $Firstname.substring(0,1) + "." + $Lastname
    }

    if ($UsernameFormat -eq "john.doe") {
        $Username = $Firstname + "." + $Lastname
    }
    
    # change to lower case and remove - and '

    $Username    = $Username.ToLower()
    $Username    = $Username.Replace('-','').replace("'",'')

    # Generate a random password and make the first letter a capital

    if ($Password -eq $null) {
        
        $Password = (Get-Culture).TextInfo.ToTitleCase((Invoke-WebRequest "http://www.dinopass.com/password/simple" -Verbose:$False | Select-Object Content -ExpandProperty Content))

        }

    $PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force

    # Create splat of user params
        
    $UserParams = @{
        SamAccountName = $Username
        UserPrincipalName  = "$Username@$FullDomain"
        Name = $FullName
        GivenName = $Firstname
        Surname = $Lastname
        Enabled = $True
        DisplayName = $FullName
        Path = $ImportOU
        ProfilePath = "$ProfilePath\$Username"
        HomeDrive = "H:"
        HomeDirectory = "$HomePath\$Username"
        Description = $Description
        AccountPassword = $PasswordSecure
        ChangePasswordAtLogon = $true
        }

    # Create an object to make reporting later easier
       
    $UserObject = [PSCustomObject]@{

        FirstName       = $Firstname
        LastName        = $Lastname
        UserName        = $Username
        Description     = $Description
        Password        = $Password

        }

    # Export users to CSV File

    if (!(Test-Path $LogFile)) {

        $UserObject | ConvertTo-Csv -NoTypeInformation | Out-File -FilePath $LogFile -Append -Force
    
        }else{

        # Skip CSV headers if file already exists

        $UserObject | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -FilePath $LogFile -Append -Force
        
        }

    Write-Verbose "Attempting to create $FullName with username $Username and Password $Password"
        
    New-ADUser @UserParams

    Write-Verbose "Creating home directory: $HomePath\$Username"
    # Create users home folder and give them full rights
    New-Item -Name $Username -Path $HomePath -ItemType Directory | Out-Null
        
    Write-Verbose "Setting access rights..."
    $Acl = Get-Acl "$HomePath\$Username"
    $Ar = New-Object  System.Security.AccessControl.FileSystemAccessRule("$Domain\$Username","FullControl","ContainerInherit,ObjectInherit","None","Allow")
    $Acl.SetAccessRule($Ar)
    Set-Acl "$HomePath\$Username" $Acl

    Write-Verbose "Assigning to groups..."
    # Add them to AD groups
    Add-ADGroupMember -Identity $UserType -Members $Username

    # Set password and enable account after group membership (fine grained password policy)
    Write-Verbose "Setting password..."
    Set-ADAccountPassword -Identity $Username -Reset -NewPassword $PasswordSecure
    Set-ADUser -Identity $Username -Enabled $true
    if ($($UserType) -eq "Students") {
        Set-ADUser -Identity $Username -CannotChangePassword $true -ChangePasswordAtLogon $false -PasswordNeverExpires $true
        }

    Write-Verbose "Moving on to next user..."
    Write-Verbose $bar

    }

}
function List-Users {

    param (
        [Parameter(Mandatory=$true)]
        [string]$Group
        )


# Put all members of group in to a variable
$GroupMembers = Get-ADGroupMember -Identity $Group

# Prepare a blank array
$UsersToList = @()

# As Get-ADGroupMember does not return the "description" field we will need to loop through and Get-ADUser on each group member to get all their properties
Foreach ($User in $GroupMembers) {
    
    # Set the current value in the pipe line to $User
    $_ = $User

    # Get the ADUser using their account name
    $User = Get-ADUser -Filter {samaccountname -eq $_.SamAccountName -and enabled -eq $true} -Properties *

    # Add them to the emtpy array created earlier
    $UsersToList += $User

    }


# Do some super magic formatting!
       # Sort by description and then by name
       # Put in a table and group by description
            # If they are a student then change the group heading to "Year Group" from "Description"
            # Else assume they are staff and change the group heading to "Role" from "Description"
       # Change property name (SamAccountName to Username)
# Output to a text file on the desktop
If ($Group -like "Student*") {
    
    $UsersToList |
    Sort-Object @{expression=�Description�;Ascending=$true},
                @{expression=�Name�;Ascending=$true} |
    Format-Table -AutoSize -GroupBy @{Name="Year Group";Expression='Description'} -Property `
    @{Label="Name";Expression={$_.Name}},
    @{Label="Username";Expression={$_.SamAccountName}} |
    Out-File "$HOME\Desktop\$Group User List.txt"

    } else {

    $UsersToList |
    Sort-Object @{expression=�Description�;Ascending=$true},
                @{expression=�Name�;Ascending=$true} |
    Format-Table -AutoSize -GroupBy @{Name="Role";Expression='Description'} -Property `
    @{Label="Name";Expression={$_.Name}},
    @{Label="Username";Expression={$_.SamAccountName}} |
    Out-File "$HOME\Desktop\$Group User List.txt"

    }


}
# This script will find any disabled users located in a _DISABLED OU
# and remove the profile, home folder and also remove their AD Account

# first we will check for the _DISABLED OU

function Remove-DisabledUsers {

$domain = (Get-ADDomain).DistinguishedName
$oucheckname = "_DISABLED"
$oucheck = [adsi]::Exists("LDAP://OU=$oucheckname,$domain")

if ($oucheck -eq $false) {
    Write-Warning "Cannot find a _DISABLED OU, exiting now..."
    exit
    } else {
    $disabledou = (Get-ADOrganizationalUnit -Filter 'Name -Like "*_DISABLED*"').DistinguishedName
    Write-host "I have found a _DISABLED OU at $disabledou" -ForegroundColor Cyan
    }

# Now we will get all disabled users in that OU

$userstodelete = Get-ADUser -Filter {Enabled -eq $false} -Properties * -SearchBase $disabledou

Write-Host "I have found the following users to delete..."

$userstodelete | ft Name,samaccountname,enabled,memberof

# Here is a confirmation that exits unless y is entered

$confirm = Read-Host "Would you like to proceed with the removal? (type yes to continue)"
if ($confirm -ne 'yes') {exit}



foreach ($user in $userstodelete) {
    $homedir = $user.homedirectory
    $profiledir = $user.profilepath
    $name = $user.name

    Write-Host "Removing $name's Home Folder" -ForegroundColor Green
    Remove-Item $homedir -Recurse -Force
    
    Write-Host "Removing $name's Profile" -ForegroundColor Green
    Remove-Item "$profiledir*" -Recurse -Force
    
    Write-Host "Removing $name's Account" -ForegroundColor Green
    Remove-ADUser $user -Confirm:$false -Verbose

    }

}
function Rename-Users {

    param (
    [string]$OU
    )

    # get users in a certain OU
    $allusers = Get-ADUser -Filter * -SearchBase $OU

    # loop through all users found
    foreach($user in $allusers){

    # assign variables
    $firstname = $user.givenname
    $surname = $user.surname
    $olddisplayname =$user.name

    # reassign variables with correct capitalization
    $firstname = $firstname.substring(0,1).ToUpper()+$firstname.substring(1).ToLower()

    $surname = $surname.substring(0,1).ToUpper()+$surname.substring(1).ToLower()

    # create the correct displayname
    $newdisplayname = $firstname + " $surname"

    # perform the rename action
    Set-ADUser -Identity $user -DisplayName $newdisplayname
    Rename-ADObject -Identity $user -NewName $newdisplayname

    Write-Host "Renamed $olddisplayname to $newdisplayname" -ForegroundColor Green

    }
}
Function Reset-Passwords {

 param (

    [Parameter(Mandatory=$true,Position=0)]
    [string]$OU,

    [Parameter(Mandatory=$true,Position=0)]
    [string]$NewPwd,

    [switch]$RequireChange = $true


 )


# Get all the users in the OU
$Users = Get-ADUser -Filter * -Properties * -SearchBase $OU

foreach ($User in $Users) {
    
    # Set the users password
    Set-ADAccountPassword -Identity $User.SamAccountName -NewPassword (ConvertTo-SecureString $NewPwd -AsPlainText -Force) -Reset -Verbose    
    # If require change is true then do so
    if ($RequireChange -eq $true)
        {
        Set-ADUser -Identity $User.SamAccountName -ChangePasswordAtLogon $true
        }
    
    Write-Host "$($User.name)'s password has been updated" -ForegroundColor Green
        
        }
    }