Leaver Script Help

Hello!

I’m fairly new to PowerShell and I thought, first of all, I would try to amend a current leavers script that we have. It currently imports a CSV file and finds each AD user in the CSV, disables their AD account, changes their password, moves them to a leavers OU and then disables the remote mailbox on our local exchange. I am stuck on getting the script to continue when an error is found in the CSV file. Currently, it finds the error and just stops the whole script. I’d like it to continue even after an error but record the failed user somewhere. Any help would be appreciated.

Write-Host -ForegroundColor Yellow "Enter your Office 365 details"

$CloudCredential = Get-Credential


$ulist = Import-Csv C:\Operations\Starters-Leavers\leavers.csv
$LeaversOU = 'OU=LeaversPending,OU=Azure,DC=domain,DC=domain'
$PermLeaversOU = 'OU=Leavers,OU=Others,DC=domain,DC=domain'


# Connect to Office 365 / Outlook Live
$CloudSessionParameters = @{
ConfigurationName = 'Microsoft.Exchange'
ConnectionUri = 'https://outlook.office365.com/Powershell'
Credential = $CloudCredential
Authentication = 'Basic'
AllowRedirection = $true
WarningAction = 'SilentlyContinue'
}
$CloudSession = New-PSSession @CloudSessionParameters
Import-PSSession $CloudSession -Prefix Cloud

#Connect to local Exchange
$LocalExchangeSessionParameters = @{ 
ConfigurationName = 'Microsoft.Exchange'
ConnectionUri = 'http://server/Powershell/'
Authentication = 'Kerberos'
}

$LocalExchangeSession = New-PSSession @LocalExchangeSessionParameters
Import-PSSession $LocalExchangeSession

###### PART 1 ######
####################

$ulist | ForEach-Object {

try {
# ErrorAction is important to catch the error
$adacct = Get-ADUser $_.user -Properties Name, SamAccountname, UserPrincipalName, CanonicalName, Enabled, EmailAddress, PasswordExpired, Modified -ErrorAction Stop
} catch {
Write-Error "User $($_.user) does not exist, cannot disable"
Add-Content -Path C:\Operations\Starters-Leavers\UsersNotProcessed.log -Value $_.user
# Skips to the next user in $ulist, does not disable anything
continue
}


$body = Get-CloudMailbox -Identity $adacct.UserPrincipalName | Select-Object Name, Alias, EmailAddresses -ExpandProperty EmailAddresses

Write-Host -ForegroundColor Yellow "Disabling user account on AD and moving to Azure\LeaversPending OU"
Disable-ADAccount -Identity $adacct.SamAccountName
Move-ADObject -Identity $adacct.DistinguishedName -TargetPath $LeaversOU

Write-Host -ForegroundColor Yellow "Changing AD Password to Random Password"
$Pwd = -join ((48..122) | Get-Random -Count 16 | ForEach-Object { [char]$_ })
$PwdSecStr = ConvertTo-SecureString $pwd -AsPlainText -Force
Set-ADAccountPassword -Identity $adacct.SamAccountName -NewPassword $PwdSecStr -Reset
Write-Host -ForegroundColor Yellow "Password changed for $($adacct.Name)"

###### PART 2 ######
####################

### Get AD user details again as the user has moved OU
$adacct = Get-ADUser $_.user
$ticket = $_.ticket

### Disable mailbox, move user to Leavers OU (domain/Leavers)

Write-Host -ForegroundColor Yellow "Disabling Mailbox"
Disable-RemoteMailbox -Identity $adacct.SamAccountName -Confirm:$false
Write-Host "Mailbox disabled now moving user to Leavers AD OU"
Move-ADObject -Identity $adacct.DistinguishedName -TargetPath $PermLeaversOU

Write-Host -ForegroundColor Yellow "Generating and sending user status report directly into ticket"

$report = $adacct | Select-Object Name, SamAccountname, UserPrincipalName, CanonicalName, Enabled, EmailAddress, PasswordExpired, Modified | Out-String

#Sends SMTP email via o365 smtp relay
$sendMailMessageSplat = @{
Subject = "[# $($_.ticket) + ]"
From = 'LeaverPSScriptreport@domain.com'
To = 'support@domain.com'
SmtpServer = '365relay'
Body = $report + $body
}
Send-MailMessage @sendMailMessageSplat

}

You don’t need to use continue statement in catch block, it anyways goes to next item in the list.

Hi kvprasoon

It does go through the script but it also attempts to start part 2 for the failed user(s). Then, when this fails the script sends an email containing the email address of every mailbox we have. Is there a way to make it restart the loop at part 1 when it fails, rather than go to part 2?

Thanks for your help.

Have part 1 and part 2 as two functions and call part 2 on success. When using try catch it’ll look like below.

Function part1 {
# you function definition here with erroraction stop
}
try{
part1
part2 # this executes only if part 1 succeeds else it'll jump to catch block.
}
catch{
#Custom message or error handling here
}

There are multiple ways to do this even with out using any try catch block. But let you have this working in your current logic first.

Hi kvprasoon

Apologies for the late reply. I’m trying to learn PowerShell and, at the moment, I’m not exactly sure how to incorporate your solution into my script. Could you give any pointers please?

Thanks

Simon