OSSEC Rule Examples

Direct copy from the blog https://akmalhisyam.my/blog/ossec-creating-custom-rules for my reference – thanks Akmal!

When parsing log, OSSEC will look at level 0 first, and then highest level -> lowest levelOSSEC will not produce alert for rules with level 0It is best to put custom rules in local_rules.xml or other file to avoid being overwritten during upgradeossec-logtest is a very useful tool to test your rules & decoder

Example

Silencing certain rules

<rule id="100030" level="0">
  <if_sid>503,502</if_sid>
  <description>List of rules to be ignored.</description>
</rule>

OSSEC will not produce any alert when rule 502 and 503 is triggered


Ignore alert if rules triggered by certain IP

<rule id="100225" level="0">
  <if_sid>40101</if_sid>
  <srcip>127.0.0.1</srcip>
  <description>Ignore this</description>
</rule>

If rule 40101 triggered by 127.0.0.1, dont produce any alert


Ignore alert if contains certain strings

<rule id="100223" level="0">
  <if_sid>1002</if_sid>
  <match>terrorist|terror|femmefatale|heart-attack</match>
  <description>Ignore 1002 false positive</description>
</rule>

OSSEC is using OS_match/sregex syntax in <match>


Ignore alert if contains certain strings (using regex)

<rule id="100207" level="4">
  <if_sid>1002,1003</if_sid>
  <regex>^WordPress database error You have an error in your SQL syntax(\.*)functionName$</regex>
  <description>Unescaped SQL query, known issue</description>
</rule>

OSSEC is using OS_regex/regex syntax in <regex>


Trigger custom rule when certain field match certain value in cdb list

<rule id="100215" level="5">
  <if_sid>31101</if_sid>
  <list lookup="match_key" field="url">rules/badurl</list>
  <description>URL is in badurl</description>
</rule>

Trigger custom rule when certain rules is fired x time within n second from same srcip

<rule id="100216" level="10" frequency="4" timeframe="90">
  <if_matched_sid>100215</if_matched_sid>
  <same_source_ip />
  <description>Multiple badurl access </description>
  <description>from same source ip.</description>
  <group>web_scan,recon,</group>
</rule>

Overriding rules

<rule id="1003" level="13" overwrite="yes" maxsize="2000">
  <description>Non standard syslog message (size too large).</description>
</rule>

Original rule 1003 have 10245 as its maxsize. Using overwrite=”yes” will make OSSEC overwrite certain field in original rule


Custom rule group

<group name="app_error">
  <rule id="100207" level="4">
    <if_sid>1002,1003</if_sid>
    <regex>^WordPress database error You have an error in your SQL syntax(\.*)functionName$</regex>
    <description>Unescaped SQL query, known issue</description>
  </rule>

  <rule id="100218" level="0">
    <if_sid>1003</if_sid>
    <match>WUID | WTB</match>
    <description>ignorance is bliss</description>
  </rule>
</group>

RHEL Subscription Manager Useful Commands

The following was copied from <https://access.redhat.com/discussions/3312101?tour=8> and provides a method of cleaning all subscription manager configuration and re-subscribing – you’ll need an active account with Red Hat to complete this though they do offer free developer accounts (use your account name and not your email address as the username!)

sudo subscription-manager remove --all
sudo subscription-manager unregister
sudo subscription-manager clean

sudo subscription-manager register
sudo subscription-manager refresh
sudo subscription-manager attach --auto

Linux Ubuntu Kernel Management

To revert to the latest recommended kernel:

sudo apt-get install --install-recommends linux-generic-hwe-18.04

To maintain the kernel and cleanse the unused:

You should check partially removed kernels with

dpkg -l linux-image-\* | grep ^rc

and remove them with for example sudo apt-get purge linux-image-4.4.0-101-generic.

Purging will remove initramfs generation rules from /var/lib/initramfs-tools/.

If it does not help, you can remove them manually from initramfs list:

sudo rm /var/lib/initramfs-tools/3.13.0-39-generic
sudo rm /var/lib/initramfs-tools/4.4.0-101-generic
sudo rm /var/lib/initramfs-tools/4.4.0-103-generic
sudo rm /var/lib/initramfs-tools/4.4.0-38-generic
sudo rm /var/lib/initramfs-tools/4.4.0-45-generic
sudo rm /var/lib/initramfs-tools/4.4.0-59-generic
sudo rm /var/lib/initramfs-tools/4.4.0-77-generic
sudo rm /var/lib/initramfs-tools/4.4.0-78-generic
sudo rm /var/lib/initramfs-tools/4.4.0-81-generic

Usually I run purge-old-kernels followed by sudo apt-get autoremove to have only 2 recent kernels.

You can reinstall installed kernels with their initramfses:

sudo apt-get install --reinstall \
$(dpkg -l linux-image-\* | grep ^ii | awk '{print $2}')

ref: https://askubuntu.com/questions/1001285/why-are-old-initrd-files-of-uninstalled-kernels-filling-up-boot-partition

PowerShell get-help update-help

Troubleshooting update-help in Powershell can be simplified using the -Force and -Ea 0 commands to continue past errors along with the to “-Ev what” to record the errors in a verbose manner to the $what variable.

The $what variable can then be reviewed more closely and the cause of the failure (hopefully) identified.

Update-Help  -Force -Ea 0 -Ev what
$what.Exception

Creds to https://social.technet.microsoft.com/Forums/ie/en-US/0e09330a-ddb8-440e-b54c-312c99af90e4/failed-to-update-help-for-the-modules-microsoftpowershelloperationvalidation-with-ui?forum=winserverpowershell

Powershell : Move Enabled Computers to Holding OU

Introduction

This script loops through the $SourceOUs (a list of OUs from AD), identifies any enabled computers therein and moves them to the defined $TargetOU . It then emails $emailTo with a list of all affected computers and asks that the relevant IT teams are informed.

The reason for this action is to ensure that all bound and active computers fall under the scope of SCCM control which currently only affects machines within the prescribed OU structure.

This is far from ideal but it’s a temporary fix.

Input

None

Output

An email is generated where a local SMTP server is available to route the email request

Logging

Currently the logging is managed from within the script and will need to have the related variables customized to the script’s location.

$LOGTIME is s timestamp in the format “yyyy-MM-dd_hh-mm-ss”

Log call within the script:
“$LOGTIME <<TEXT TO LOG>>” | Out-File $LOG -Append -Force

The script is then contained with a try{} catch{} parameter with logging output for all exception messages and items.

I’ve also tried to log throughout each action within the script so both SUCCESS and ERRORs are logged which provides a debugging method (at least I should know where it falls over!).

Usage Examples

Call the script, no parameters defined.

Dependancies

emailer.psm1

The Script

# Name      : computerObjectManage
# Author    : Dave 
# Created   : 31/05/2019
# UPDATED   : 04/07/2019
# Version   : v2.0
# Ticket#   : XXXX
# Scope     : AD Computer Objects which are enabled and located in the AD OUs
# Input(s)  : None
# Output(s) : Log file of actions taken and an email to $emailTo if any computer objects were moved, including the account which bound them to the domain.
  
  
####################################################
# This script is designed to be located on [REDACTED] at  [REDACTED]  and run with user rights to move computer objects from the  [REDACTED] 
# It will be called nightly via a Scheduled Task defined on the server.
#
# 1. Identify all computer objects in AD which are enabled and which exist in either the OU
# 2. Parse the event logs on all Domain Controllers for Event ID 4741 and record the computername and username of the binder
# 3. Log those computer names, distinguished names, descriptions and username of the binder to a log file
# 4. Move those computer objects to the $TargetOU
# 5. Email $emailTo with a list of the computers moved, the username who bound them, the computer's distinguished names and their descriptions.
####################################################
  
# Variables:
# Files
$LOGFILEDIR = "<<INPUTE LOGFILE DIR HERE>>" # the full path of the log file for the script to output to
$LOGFILENAME =  "computerObjectManage.ps1.log" # the full name of the log file for the script to output to
$LOG = ($LOGFILEDIR + "\" + $LOGFILENAME)
$LOGTIME = Get-Date -Format "yyyy-MM-dd_hh-mm-ss"
  
# Text Strings
$SourceOUs =  [REDACTED] 
$TargetOU =  [REDACTED] 
$emailer = "<<FULL PATH OF emailer.psm1 HERE>>"
 
# eventlog querying variables
$domain = "you.domain.com"
$dcou =  [REDACTED] 
$dcs = get-adcomputer -filter * -properties name -searchbase $dcou | select name
# set the hashtable variable to record the eventlog results from the domain controllers
$domainBindEvents = @{}
  
# Email settings
$emailTo = "your@email.com"
$emailFrom = "yourscript@email.com"
  
# Email subject and the first section of the body
$subject_output =  [REDACTED] 
  
Import-Module -Name $emailer #-Verbose
  
# Prepare the logging
##################################################################################
# Check for the $LOGFILEDIR & $LOGFILENAME and create them if they don't exist
# NOTE: No logging until this happens except to STDOUT (Screen)
# Test for the folder and create if it doesn't exist:
##################################################################################
  
Try
    {
      
        if(! (Test-Path -Path $LOGFILEDIR )){
                New-Item -ItemType directory -Path $LOGFILEDIR
            }
        if(! (Test-Path $LOGFILEDIR\$LOGFILENAME  )){
            New-Item -ItemType file -Path $LOGFILEDIR\$LOGFILENAME
        }
          
    }
Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
    }
  
"$LOGTIME BEGIN STARTING SCRIPT" | Out-File $LOG -Append -Force
  
  
##################################################################################
# Main
##################################################################################
  
Try
    {
        # Using the list of $SourceOUs (defined at the start of this script) loop through each OU and add any computers' distinguished names and which are ENABLED to the $targetcomps array.
        $targetcomps = foreach ($OU in $SourceOUs) { get-adcomputer -filter {enabled -eq "True"} -properties Name, DistinguishedName, Description -SearchBase "$OU" | select DistinguishedName, Name, Description}
        # test to see if there were any computers discovered and added to the $targetcomps array by inspecting it's length.
        # If computers were discovered then continue, else log that there weren't and exit the script.
          
        if ($targetcomps.length -eq 0) {
            "$LOGTIME COMPLETED No computers were discovered in $($SourceOUs)" | Out-File $LOG -Append -Force
            exit
            #write-host "no targetcomps"
        }
        else {
            # If there were computers in the default OUs:
             
            # Check the event logs on all DC's for the event ID 4741 in the Security eventlog and
            # add any entries' computer name and account which bound it to the the hashtable $domainBindEvents
            try {
             
                foreach ($dc in $dcs){
                 
                    # Loop through each DC in the $dcou OU and for each one:
                    # Set the FQDN to $dcfqdn
                    $dcfqdn = $dc.name + $domain
                     
                    try{
                     
                        # Add all events matching 4741 from the Security event log to the $dc4741events hashtable
                        "$LOGTIME INFO querying $($dcfqdn) for 4741 events..." | Out-File $LOG -Append -Force
                        $dc4741events += get-winevent -computername $dcfqdn -FilterHashtable @{logname='security';id=4741}
                    }
                    catch
                    {
                        # if there were no events continue to the next DC
                        $ErrorMessage = $_.Exception.Message
                        $FailedItem = $_.Exception.ItemName
                        "$LOGTIME ERROR $($ErrorMessage) $($FailedItem)" | Out-File $LOG -Append -Force #LOGACTION
                        continue
                    }
                     
                    # If events were found then:
                    if ($dc4741events) {
                     
                        foreach ($event in $dc4741events){
                                         
                            # expand the event and assign the 8th item to $computername and the 4th to $userwhobound
                            $computername = $event.Properties[8]
                            $userwhobound = $event.Properties[4]
                             
                            # Update the hashtable $domainBindEvents with the new values
                            $domainBindEvents[$computername.value.SubString(0,$computername.value.Length-1)] = $userwhobound.value
                            "$LOGTIME INFO Events Found on $($computername.value.SubString(0,$computername.value.Length-1)) bound by $($userwhobound.value) " | Out-File $LOG -Append -Force
                        }
                    }
                }
 
            }
            catch
            {
                $ErrorMessage = $_.Exception.Message
                $FailedItem = $_.Exception.ItemName
                "$LOGTIME ERROR $($ErrorMessage) $($FailedItem)" | Out-File $LOG -Append -Force #LOGACTION
            }
             
            # Loop through the list of computers which were discovered in a default OU
            foreach ($comp in $targetcomps) {
             
                # Loop through the $boundcompevents.keys
                foreach ($boundcompevent in $domainBindEvents.keys){
                    #write-host "$($boundcompevent)"
                    # Compare the $comp with the key values of the $domainBindEvents to see if there's a match:
                    #write-host "DOES $($boundcompevent) EQUAL $($comp.Name.tolower())?  "
                    if ($boundcompevent.tolower() -eq $comp.Name.tolower()){
                        #write-host true
                        # If there is a match then:
                        # Assign the username of the account which bound the matching computer to the domain and break out of this sub-forloop
                        $usernamebinder = $domainBindEvents.$boundcompevent
                        break
                    }
                    else
                    {
                        #write-host false
                        # If no matching computer was identified in the event log IDs 4741 assign the fixed string to the $usernamebinder requesting the receiver of the email alert investigate.
                        $usernamebinder = "UNKNOWN, could not identify a user from the 4741 event ID's on the DCs - manual identification required"
                        #Log the
                        "$LOGTIME INFO No matching event log for binding $($comp.name.tolower()) - it didn't match $($boundcompevent.tolower())"| Out-File $LOG -Append -Force
                    }
                }
                 
                # Move the Computer Object to the $TargetOU
                move-adobject -identity $comp.DistinguishedName  -targetpath $TargetOU  
                  
                #Log the move computer object action
                "$LOGTIME INFO $($comp.Name) LOCATED AT $($comp.DistinguishedName) WAS MOVED TO THE _WindowsClients\WindowsClientsNeedOURelocation OU"| Out-File $LOG -Append -Force
                 
                # Add the computer name, distinguishedName, Description and the username of the person who bound the computer to the domain to the email body
                $body_output_complist += "`n" + "COMPUTER_NAME = " + $comp.Name +  "    USERNAME_THAT_BOUND_COMPUTER = " + $usernamebinder +  "    COMPUTER_DESCRIPTION = " + $comp.Description +  "    COMPUTER_DISTINGUISHED_NAME=" + $comp.DistinguishedName + "`n"
            }
                          
        #Email the results
        $body = $body_output + " " + $body_output_complist
        "$LOGTIME INFO Sending email to $($emailTo) reporting the computers that were discovered and moved ....  "| Out-File $LOG -Append -Force
        emailer $emailTo $emailFrom $subject_output $body
        "$LOGTIME SUCCESS Email sent  "| Out-File $LOG -Append -Force         
        "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
         
        }
    }
Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        "$LOGTIME ERROR $($ErrorMessage) $($FailedItem)" | Out-File $LOG -Append -Force #LOGACTION
        exit
    }

Powershell : Module – Emailer

Introduction

A small emailer module which can be used to send emails using a locally available SMTP server.

Input

None

Output

An email is generated where a local SMTP server is available to route the email request

Logging

None

Usage Examples

Import the module to your script and then call it as per the example in the script

Dependancies

None

The Script

# Name      : Powershell Emailer when local SMPT available
# Author    : Dave 
# Date      : 
# Ticket#   : NONE
# Scope     : Power Shell Module, to the called by scripts
# Input(s)  : $emailFrom > [STR] > the sender's email address,
#             $emailTo   > [STR] > the target email addres,
#             $subject   > [STR] > the subject of the email 
#             $body  > [STR] > the email body
# Output(s) : An email is sent to the address specified.
#
# Example call:
# emailer "to@something.com" "from@somewhere.com" "email subject" "email body"
####################################################
 
# Notes:
########################
 
Function emailer ($emailTo, $emailFrom, $emailSubject, $emailBody)
<# This is a simple function that that sends an smtp email using the variables to define the email
i.e. "Function emailer ($emailFrom, $emailTo, $subject, $body) "
 
#>
 
{
$emailSmtpServer = "smtp.SOME.AVAILABLE.DOMAIN.COM"
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Body $emailBody -SmtpServer $emailSmtpServer
}

PowerShell : DHCP Log Backup Script

Introduction

This script is designed to backup DHCP logs from a Windows DHCP Server to another location.

Input

InputsType
A text file with a list of target computer names, one per line. Variable assignment within the script

Output

outputsTypeItemDescription
Copy of DHCP Logs File(s)Logdefined by the script

Logging

Logging is basic for now, a log file is defined within the script by the controlling variables at the top and it logs all errors and successes from each command within the script.

Usage Examples

To call this script:

  1. Ensure the variables under the heading “Set the variables” are configured for
    1. A valid scriptlog directory
    2. A valid input file listing the target DHCP servers, one per line
  2. Ensure the target DHCP servers’s dhcp log directory is available to the calling security principal

Dependancies

emailer.psm1 module : https://www.oxfordshirecomputing.co.uk/powershell-module-emailer/

The Script

# Name      : Windows DHCP Log Backup
# Last Edit : 
# Author    : Dave 
# Date      : 
# Ticket#   :
# Scope     : All Windows DHCP Servers
# Inputs    : none
# Output(s) : Log of script actions in csv to $LOGFILE, targeted log files moved from the host server to the TARGET SERVER server.
 
####################################################
# This script is designed to take a list of DHCP server names or IP addresses as an input from an external text file via the
# $Computers variable and copy the previous day's DHCP logs from that server to the target backup server
# \\SERVER\Windows\DHCP\, creating a sub directory within that share in the DNS name or IP address of the DHCP server,
# leaving the original logs in place at source.
####################################################
 
# Notes:
########################
# To call this script:
# 1. Ensure the variables under the heading "Set the variables" are configured for
#    - A valid scriptlog directory
#    - A valid input file listing the target DHCP servers, one per line
# 2. Ensure the local dhcp folder is shared with read permissions for the calling principal (account) and has read file permissions enabled for that account.
# 3. Call the script via powershell, no arguments required.
 
# Set the variables
########################
# Log file variables
$LOGFILEDIR = "C:\scripts\Powershell\PSScriptLogs" # the full path of the log file for the script to output to
$LOGFILENAME =  "dhcplogbackup.ps1.log" # the full name of the log file for the script to output to
$LOG = ($LOGFILEDIR + "\" + $LOGFILENAME)
$LOGTIME = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
 
# Script variables
$Computers = Get-Content -Path "C:\scripts\Powershell\PSScriptInputs\dhcpservers.txt" # list of target computers
$dateYesterday = get-date -date $(get-date).adddays(-1) -format "MM/dd/yyyy"
$filedate =  get-date -date $(get-date).adddays(-1) -format "yyyy-MM-dd"
$today = get-date -format "MM/dd/yyyy"
$logdir = "Windows\System32\dhcp" #define the target log directory to be backed up / moved
# variables for the current computer -- > See below
 
 
# Email settings
$emailer = "C:\scripts\Powershell\Modules\emailer.psm1"
$emailTo = "it-alerts@something.com"
$emailFrom = "DHCPLogBackup@something.com"
# Email subject and the first section of the body
$subject_output = "DHCP Log Copy Script"
$body = "Ref: SOMEREF `n`nThe DHCP Log File backup script encountered an error. `n`nPlease complete the following actions:
`n`n
1. Log a ticket to record this alert and your response
`n
2. Visit the script execution server and examine the C:\Logs\dhcplogbackup.ps1.log file for clues
`n
3. Either correct the fault and re-run the script or manually copy the target DHCP logs which failed from \Windows\System32\Logs\DHCP\ to \\SERVER\Windows\DHCP\<SERVERNAME>\ and await the overnight scheduled re-run of the script
`n`n
This script runs to ensure we can retain a 90 day log of DHCP lease activity for our domain, it is critical in that regard until a centralised logging system has been established.
`n`n
Thanks.`n`n Dave
"
 
# Imported modules
Import-Module -Name $emailer #-Verbose
 
# Prepare the logging
##########################
# Check for the $LOGFILEDIR & $LOGFILENAME and create them if they don't exist
# NOTE: No logging until this happens except to STDOUT (Screen)
# Test for the folder and create if it doesn't exist
Try
    {
     
        if(! (Test-Path -Path $LOGFILEDIR )){
                New-Item -ItemType directory -Path $LOGFILEDIR
            }
    }
Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        emailer $emailTo $emailFrom $subject_output "DHCP LOG BACKUP SCRIPT FAILED TO CREATE LOCAL SCRIPT LOGFILE!"
    }
     
# test for the file and create if it doesn't exist
Try
    {
        if(! (Test-Path $LOGFILEDIR\$LOGFILENAME  )){
            New-Item -ItemType file -Path $LOGFILEDIR\$LOGFILENAME
        }
    }
Catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        emailer $emailTo $emailFrom $subject_output "DHCP LOG BACKUP SCRIPT FAILED TO CREATE LOCAL SCRIPT LOGFILE!"
    }
     
"$LOGTIME BEGIN STARTING SCRIPT" | Out-File $LOG -Append -Force
 
# BODY
##########################
# Loop through the list of computers
$Computers | Foreach-Object {
     
    # Log the computer name in question
    "$LOGTIME START $($_)" | Out-File $LOG -Append -Force
     
    # variables for the current computer
    $hostname = $($_) # The current server's hostname
    $sourceLogs = "\\$hostname\dhcp" # the location of the DHCP logs ($logdir) on the current computer
    $targetdir = "\\SERVER FQDN\Windows\DHCP\$($hostname)" # Target dir on some server for current server
    $targetparent = split-path $targetdir # Parent dir of the target dir on some server for current server
     
    #Test access to the sourceLogs directory, if this fails log the failure and exit (the script can't copy from non-existent targets)
    try {
        if (test-path $sourceLogs -isvalid) {
            Try {
                # collect all filenames into the $files variable which begin with "Dhcp" and end with ".log" and which have a LastAccessTime value for yesterday
                $files = get-childitem $sourceLogs | where-object {($_.name -like "Dhcp*.log") -and ($_.LastAccessTime -ge $dateYesterday) -and ($_.LastAccessTime -lt $today)} | select name
            }
            catch{
                $ErrorMessage = $_.Exception.Message
                $FailedItem = $_.Exception.ItemName
                "$LOGTIME ERROR $($_) Unable to get-childitem for $($sourceLogs) $($ErrorMessage) $($FailedItem) " | Out-File $LOG -Append -Force
                emailer $emailTo $emailFrom $subject_output $body
                "$LOGTIME SUCCESS Email Alert Sent"| Out-File $LOG -Append -Force        
                "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
            }
             
            # check that files were found, if not generate an email alert for review of this script
            if (!($files)) {
                "$LOGTIME ERROR No files were located by the script : $($files) Review the logfile $($LOG) for clues - ensure the backup is completed!" | Out-File $LOG -Append -Force
                emailer $emailTo $emailFrom $subject_output $body
                "$LOGTIME FAIL Email Alert Sent"| Out-File $LOG -Append -Force        
                "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
            }
            }
             
             
            #Check the path \\SERVER\Windows\ contains a folder using this server's hostname, if not then create one.
            If (!(test-path $targetdir)) {
                Try {
                    New-Item -Path $targetparent -Name $hostname -ItemType "directory"
                }
                Catch {
                    $ErrorMessage = $_.Exception.Message
                    $FailedItem = $_.Exception.ItemName
                    "$LOGTIME ERROR $($_) Creating $($targetparent)\$($hostname) $($ErrorMessage) $($FailedItem)" | Out-File $LOG -Append -Force
                    emailer $emailTo $emailFrom $subject_output $body
                    "$LOGTIME FAIL Email Alert Sent"| Out-File $LOG -Append -Force        
                    "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
                }
            }
             
            #Copy the yesterday's DHCP log file into the target directory, prefixing the date to the filename
            Foreach ($file in $files) {
                try {
                    $fileName = $file.name
                    #write-host $fileName
                    copy-item $sourceLogs\$fileName -destination $targetdir\$filedate"-"$fileName
                }
                Catch {
                    $ErrorMessage = $_.Exception.Message
                    $FailedItem = $_.Exception.ItemName
                    "$LOGTIME ERROR $($_) executing copy-item or remove-item against $($sourceLogs)\$($fileName) : $($ErrorMessage) $($FailedItem)" | Out-File $LOG -Append -Force                 
                    emailer $emailTo $emailFrom $subject_output $body
                    "$LOGTIME FAIL Email Alert Sent"| Out-File $LOG -Append -Force        
                    "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
                }          
            }
        }  
        Catch {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        "$LOGTIME ERROR $($_) the $($sourceLogs) path was not found - no action taken, exiting..." | Out-File $LOG -Append -Force
        emailer $emailTo $emailFrom $subject_output $body
        "$LOGTIME FAIL Email Alert Sent"| Out-File $LOG -Append -Force        
        "$LOGTIME FINISH The script has completed  "| Out-File $LOG -Append -Force
    }
}