Powershell Send an email if success or if error - powershell

I have a script that looks at a CSV, filters the email address and performs some tasks:
foreach($aduser in (import-csv "C:\Temp\users.csv")){
Get-ADUser -filter "emailaddress -eq '$($aduser.emailaddress)'"|
Set-ADobject -ProtectedFromAccidentalDeletion $false
Get-ADUser -filter "emailaddress -eq '$($aduser.emailaddress)'" |
Set-ADUser -Enabled $false
Get-ADUser -filter "emailaddress -eq '$($aduser.emailaddress)'" |Move-ADObject -TargetPath "OU=Sep 20,OU=Disabled User Accounts,DC=Mydomain,DC=Domain,DC=uk" -PassThru | Disable-ADAccout}
If ($Error){
$FailMailParams = #{
To = 'Example#Gmail.com'
From = 'Example#Gmail.com'
SmtpServer = 'My.smtp.server'
Subject = 'Script Errors Out'
Body = 'There was an error with the script!!'
}
Send-MailMessage #FailMailParams
} else {
$SuccessMailParams = #{
To = 'Example#Gmail.com'
From = 'Example#gmail.com'
SmtpServer = 'My.smtp.server'
Subject = 'Success'
Body = 'The script ran successfully'
}
Send-MailMessage #SuccessMailParams
}
The problem I am facing is that even if the script runs successfully I still get the error email. If I change the code to if ($error -eq 1) and the code errors out I get the successful email. I think it's the If ($error) Variable causing the issue but I don't know what to use?

Error control can be handled in different ways. In your code, you have nothing that is indicating $error that should be set to 1.
I suggest you to find some examples of how to use the Try-Catch structure, as you will have to use it a lot in Powershell.
Find an example below which should be easy to adopt for your already made code:
try
{
# Code that performs the work intended
}
catch
{
# What to do in case any error is raised from above Try section
$error = 1
}
finally
{
# Here you post code that will be executed no matter errors happened or not,
# for example your email definition and execution.
}
Said this, your code has more room for improvement, but if you are starting with it, let's not focus on that part still.

Related

Powershell Active Directory Get Expired Users

this is my first time on Stack Overflow so please have mercy :)
Im trying to create a Powershell GUI to do a search request on our Active directory that shows me all expired and soon expiring User Accounts. I tried it with the following function.
I get an syntax error in my request (Get-ADUser)...
Error Message in Powershell ISE
$ShowExpiring.Add_Click({
$ADUserSearch.Visible = $False
$CheckDisabled.Visible = $False
$ShowExpiring.Visible = $False
$Back.Visible = $True
$Results.Visible = $True
$Results.Clear()
$Results.ScrollBars = "Vertical"
Import-Module ActiveDirectory
$CurrentDate = Get-Date
$ExpiringPasswords = Get-ADUser -Filter '((PasswordExpired -eq $True) -or (PasswordLastSet -le ((get-date).AddDays(-((get-addefaultdomainpolicy).MaxPasswordAge.Days)))))' -Properties Name,PasswordLastSet
if($ExpiringPasswords) {
$ExpiringPasswords = $ExpiringPasswords | sort PasswordLastSet
foreach ($User in $ExpiringPasswords) {
if ($User.PasswordLastSet -lt (Get-Date).AddDays(-((Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days))) {
$Results.SelectionColor = "Red"
else {
$Results.SelectionColor = "Orange"
}
$Results.AppendText("Username: $($User.Name) Expiration Date: $($User.PasswordLastSet)`n")
}
else {
$Results.AppendText("No passwords expiring or already expired.")
}
})
I also tried it with this code which gives me no error message but also no result from disabled users:
$ShowExpiring.Add_Click({
$ADUserSearch.Visible = $False
$CheckDisabled.Visible = $False
$ShowExpiring.Visible = $False
$Back.Visible = $True
$Results.Visible = $True
$Results.Clear()
$Results.ScrollBars = "Vertical"
Import-Module ActiveDirectory
$CurrentDate = Get-Date
$ExpiringPasswords = (Search-ADAccount -AccountExpired -UsersOnly | select Name, #{n='ExpirationDate';e={[datetime]::FromFileTime($_.AccountExpirationDate)}}) + (Search-ADAccount -AccountExpiring -TimeSpan (New-TimeSpan -Days 10) -UsersOnly | select Name, #{n='ExpirationDate';e={[datetime]::FromFileTime($_.AccountExpirationDate)}})
if($ExpiringPasswords) {
$ExpiringPasswords = $ExpiringPasswords | sort ExpirationDate
foreach ($User in $ExpiringPasswords) {
if ($User.ExpirationDate -lt $CurrentDate) {
$Results.SelectionColor = "Red"
else {
$Results.SelectionColor = "Orange"
}
$Results.AppendText("Username: $($User.Name) Expiration Date: $($User.ExpirationDate)`n")
}
else {
$Results.AppendText("No passwords expiring or already expired.")
}
})
Thank you for helping me.
The reason for your syntax error is likely the fact that you are trying to use
Get-ADDefaultDomainPolicy
...which does not exist. What you're looking for is
Get-ADDefaultDomainPasswordPolicy
Here is some code that you should substitute in the appropriate place in your first example. I broke things down a little bit to make the code/filter easier to understand, but you can recombine it if you are so inclined to do so.
$MaxPasswordAgeDays = $(Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days
$OldestAcceptablePasswordLastSetDate = $(Get-Date).AddDays(-$MaxPasswordAgeDays)
$ExpiringPasswords = Get-ADUser -Filter {PasswordExpired -eq $True -or PasswordLastSet -le $OldestAcceptablePasswordLastSetDate} -Properties Name,PasswordLastSet
I would suggest using { } instead of single quotes ' ' so that your Powershell editor can help you with intellisense and syntax highlighting rather than the single quotes in your example. Aside from that, if you ever encounter syntax errors, I would recommend trying to break it down as I did above to help you understand which part of your code (in this case, your filter) is failing. I discovered rather quickly that you were trying to use a non-existent cmdlet by doing so.

Unable to catch the error using try..catch in powershell

I am trying to catch the error if DL is not found. I have written the below code
try
{
Get-DistributionGroup -Identity "#AB-TestDL"|select ManagedBy -ErrorAction Stop
}
catch
{
if($Error[0] -match "couldn't be found on")
{
Write-Host "DL not found"
}
}
But when i run the code, it throws an error as "#AB-TestDL" couldn't be found on ...
Please help me capture this error. Thanks..
Try using the -ErrorAction Stop parameter on the Get-DistributionGroup -Identity "#AB-TestDL" CmdLet instead of Select-Object.
Select-Object can be used to create a new object but it isn't a error for the CmdLet when a property does not exist.
C:\> [PSCustomObject]#{ Test = 123 } | Select Test2 -ErrorAction Stop
Test2
-----
You can however make it work different (while i still suggest moving -ErrorAction Stop to the first CmdLet):
Set-StrictMode -Version 3
$Object = [PSCustomObject] #{
Test = 123
}
try {
$null = $Object.Test2
} catch {
throw "I don't extist and catch because of strictmode version 3"
}
Just an idea which came into my head. I actually never used strictmode this way.

handle ADIdentityNotFoundException without stopping the program

I have to loop for each object in an input file, doing a Get-ADUser on each object, and I want to handle the ADIdentityNotFoundException error without stopping the loop. Is there a better way I can accomplish this (simplified for example's sake):
Import-Csv $input | Foreach-Object {
$manager = "BLANK"
if ($user = Get-ADUser $_."samaccountname" -properties * ) {
# I don't think I need this in an IF{} since the line below won't work
# so $manager will be equal to the last value set, "BLANK", but
# this makes it easier to understand what I want to happen
$manager = $user."manager"
# I need more properties (thus -properties *) but again just an example
}
}
In essence, if the Get-ADUser lookup is successful, set $manager = $user."manager"
If it is not successful, do not stop the loop, do not copy the value of the previous user, have $manager = "BLANK"(or whatever). The issue I have with the try/catch solutions, is that ADIdentityNotFoundException doesn't trigger the catch unless I add -ErrorAction Stop, which will cause the undesired result of the program terminating.
I'm not sure why your program would be terminating. Using the below sample code loops through all the users in the array. I have purposely entered an incorrect username into the second value of the array (position [1]):
$users = "username1", "username2", "username3" #username2 is purposely incorrect
foreach ($i in $users){
try{
$user = Get-ADUser -Identity $i -Properties * -ErrorAction Stop
Write-Host "Found"
}catch{
Write-Host "Not found"
}
}
my output is
found
not found
found

Throw message not being shown

I'm trying to print my own error messages using throw. Consider this example:
$computerName = $env:COMPUTERNAME
$adsi = [adsi]("WinNT://$computerName")
if (!($adsi.Children.Find($userGroup, 'group')))
{
throw "User group not found."
}
If the user group is incorrect, this error message is shown:
Exception calling "Find" with "2" argument(s): The group name could not be found.
Is there a way to show my throw message, rather than the generic exception?
try this:
$computerName = $env:COMPUTERNAME
$adsi = [adsi]("WinNT://$computerName")
try {
$adsi.Children.Find($userGroup, 'group')
}
catch{
throw "User group not found."
}
[adsi] has a habit of throwing terminating errors. This happens with Get-ADUser as well. This is why capturing the error in a try/catch (like in whatever's answer) is necessary.
As an alternative you can check if the group exists by querying all local groups first and see if yours exists.
$computerName = $env:COMPUTERNAME
$adsi = [adsi]("WinNT://$computerName")
$localGroups = $adsi.children | Where-Object{$_.SchemaClassName -eq "Group"}
If($userGroup -notin $localGroups.Name){
throw "Your group is in another castle."
}
or a variant
if(-not ($adsi.children | Where-Object{$_.SchemaClassName -eq "Group" -and $_.Name -eq $userGroup})){
throw "Your group is in another castle."
}
Depending on where you are continuing with this code it might be advantageous to store this information once.

PowerShell - TRUE or FALSE returned If username exists in ActiveDirectory

I am wanting to check if an AD username exists, when I run the below condition I receive an error 'Get-ADUser : Cannot find and object with identity' This is obviously due to the specific username not existing, however if the condition is false then I want to echo a response to the user.
$username_value = "JSmith"
IF (Get-AdUser $username_value) {
Run script.....
}
ELSE {
Write-Host "The username does not exist."
}
EDIT: The answer below is correct for nearly every PowerShell cmdlet, but not Get-ADUser which somehow ignores -ErrorAction. I'll leave it here for future reference. In the meantime, you can use the following instead:
$user = Get-ADUser -filter {sAMAccountName -eq $username_value}
if (!$user) {
Write-Error "This username does not exist"
exit # or return, whatever is appropriate
}
You can just suppress the error using the -ErrorAction parameter. The return value from the cmdlet should be $null in that case and thus coerce nicely to $false.
$user = Get-ADUser -ErrorAction SilentlyContinue $username_value
if (!$user) {
Write-Error "This username does not exist"
exit # or return, whatever is appropriate
}
# run script ...