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\User Import Logs" ) # Setup logging $Log = "$LogPath\$(Get-Date -UFormat %Y-%m-%d) Import Log.csv" $FailLog = "$LogPath\$(Get-Date -UFormat %Y-%m-%d) FAILED Import Log.csv" if (!(Test-Path $Log)) { New-Item $Log, $FailLog -Force Set-Content -Path $Log -Value '"Full Name","UserName","Description","Password"' Set-Content -Path $FailLog -Value '"Full Name","UserName"' } # 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]@{ Name = $Fullname UserName = $Username Description = $Description Password = $Password } try { New-ADUser @UserParams Write-Verbose "Successfully created $FullName with username $Username and Password $Password" $UserObject | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -FilePath $Log -Append -encoding ASCII } catch { $_ | Out-File -FilePath $FailLog -Append -encoding ASCII $UserObject | Select Name,Username | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -FilePath $FailLog -Append -encoding ASCII $bar | Out-File -FilePath $FailLog -Append -encoding ASCII Write-Verbose "Unable to create $FullName, moving on to next user..." continue } 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 } else { Set-ADUser -Identity $Username -CannotChangePassword $false -ChangePasswordAtLogon $true -PasswordNeverExpires $true } 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 } } |