How to delete X days old email

General discussion about Zimbra Desktop.
bhairavdhanwade
Posts: 1
Joined: Wed Jul 29, 2015 8:06 am

How to delete X days old email

Post by bhairavdhanwade »

    ## This is the Fully automated script to check and delete one year older  mails. ##        

#!/bin/bash

ZIMBRA_BIN=/opt/zimbra/bin

THEDATE=$(date -d "-365 day" +"%m/%d/%y")
OneYearAgo=THEDATE
echo "One year ago : $THEDATE"
TODAY=$( date +"%m/%d/%y")
## Get E-mail Address List
/opt/zimbra/bin/zmprov -l gaa | grep "@domain.com" | sort > /usr/local/src/script/domain_email_id.txt
/opt/zimbra/bin/zmprov -l gaa | grep "@domain1.com" | sort > /usr/local/src/script/domain1_email_id.txt
cat /usr/local/src/script/domain_email_id.txt /usr/local/src/script/domain1_email_id.txt > /usr/local/src/script/e-mail-id.txt

while read THEACCOUNT
do
echo "Searching mail from $THEDATE to $TODAY for $THEACCOUNT:"
LOGF=`echo $THEACCOUNT | awk -F "@" '{print $1}'`
for i in `$ZIMBRA_BIN/zmmailbox -z -m $THEACCOUNT search -l 1000 "(before:$THEDATE)" | grep conv | sed -e "s/^ss*//" | sed -e "s/ss*/ /g" | cut -d" " -f2`
do
if [[ $i =~ [-]{1} ]]
then
MESSAGEID=${i#-}
echo "deleteMessage $MESSAGEID" >> /tmp/$LOGF.txt
else
echo "deleteConversation $i" >> /tmp/$LOGF.txt
fi
done

$ZIMBRA_BIN/zmmailbox -z -m $THEACCOUNT < /tmp/$LOGF.txt >> /tmp/process.log
rm -f /tmp/$LOGF.txt

done < /usr/local/src/script/e-mail-id.txt


User avatar
manfred.gipp
Advanced member
Advanced member
Posts: 51
Joined: Tue Feb 03, 2015 7:08 am
Location: Germany
ZCS/ZD Version: Zimbra 8.8.6_GA_1906 (build 2017113
Contact:

How to delete X days old email

Post by manfred.gipp »

I try to use nearly the same script to move automatically Mails from Inbox-Folder to another folder.

I use "moveMessage" and "moveConversation".

But this works not as expected.

In your case "deleteConversation" deletes all Mails concerning to this conversation.

This means for your script, that it could be that newer Mails are deleted.
polmstead
Posts: 1
Joined: Wed Dec 16, 2015 3:49 pm

How to delete X days old email

Post by polmstead »

Thank you for this post. I'm new to scripting and was wondering if this could be modified to target specific folders. What I'm trying to accomplish is to target the trash and sent items folder and delete anything over 15 months old. Could you suggest how I could do this? Any help is appreciated. Thank you.
Erik-NA
Posts: 27
Joined: Wed Dec 14, 2016 1:06 pm
Location: Sweden
ZCS/ZD Version: Zimbra Collaboration 9.0.0

Re: How to delete X days old email

Post by Erik-NA »

Hello
Modified the script a bit:
  • Can run as a cron job
  • Can now handle spaces in folder name
  • Using DeleteItem instead of DeleteMessage in zmmailbox since I got errors when trying to delete some messages using DeleteMessage
Todo: Better error handling from zmmailbox

Run as user zimbra.

Modify according to your needs :)

Code: Select all

#!/bin/bash
#
ZIMBRA_BIN=/opt/zimbra/bin

#Params: account folder days
#Account name
#Folder name
#Number of days for which older emails will be deleted
doPurge ()
{
    local _account="$1"
    local _folder="$2"
    local _days=$(eval "date --date='$3 days ago' +%m/%d/%y")
    local _rows=0
    local _totalRows=0
         
    rm -f /tmp/deleteOldMessagesList.txt
    rm -f /tmp/process.log
    while true; do
        _rows=0
        touch /tmp/deleteOldMessagesList.txt
        for messageId in $(eval "$ZIMBRA_BIN/zmmailbox -z -m $_account search -l 1000 'in:\"$_folder\" (before:$_days)' | grep conv | sed -e 's/^[ \t]*//' | tr -s ' ' | cut -d ' ' -f 2")
        do
            if [[ ! -z "$messageId" ]]; then 
                echo "deleteMessage $messageId" >> /tmp/deleteOldMessagesList.txt
                _rows=$[$_rows+1]
            fi
        done
        
        if [ $_rows -gt 0 ]; then
            $ZIMBRA_BIN/zmmailbox -z -m $_account < /tmp/deleteOldMessagesList.txt >> /tmp/process.log
            rm -f /tmp/deleteOldMessagesList.txt
            _totalRows=$[$_totalRows + $_rows]
        else
            break
        fi
    done
    echo $_totalRows
}

for account in $(eval "$ZIMBRA_BIN/zmprov -l gaa")
do 
    echo "Purging Emails for account $account"
    rows=$(doPurge "$account" "Activity Stream" "90")
    echo "Deleted $rows rows for account $account"
done
exit
herbi
Posts: 1
Joined: Thu Mar 05, 2020 11:32 am

Re: How to delete X days old email

Post by herbi »

Hello,

Thanks for the script, it's going well. I modified it slightly to suit my needs.

Code: Select all

####### Start
#!/bin/bash
for users in `cat /var/zimbra/users.txt`
do
## We list the emails in the inbox of the user dating before January 03, 2017 and we extract the message ID
	for i in `/opt/zimbra/bin/zmmailbox -z -m $users search -l 1000 "in:/inbox (before:01/03/17)" | grep conv | awk '{print$2}' | sed -e 's/^-*//'`
	do
	MESSAGEID=${i}
## Put the "deleteMessage" option followed by the mail ID in the /tmp/deleteOldMessagesList.txt file.
	echo "deleteMessage $MESSAGEID" >> /tmp/deleteOldMessagesList.txt
	echo -n "#" >> /tmp/deletemails.log
## Put the "deleteConversation" option followed by the mail ID in the /tmp/deleteOldMessagesList.txt file.
	echo "deleteConversation $i" >> /tmp/deleteOldMessagesList.txt
	echo -n "*" >> /tmp/deletemails.log
## We're deleting the emails
	/opt/zimbra/bin/zmmailbox -z -m $users < /tmp/deleteOldMessagesList.txt >> /tmp/process.log
## Delete the temporary file used to set the deleteMessage and deleteConversation options. The file will be recreated for the following user
	rm -f /tmp/deleteOldMessagesList.txt
	echo " $users completed " >> /tmp/deletemails.log
	done
done
######## End
You must first list the users in a file, in my case /var/zimbra/users.txt.
If you want to apply the deletion on all mails you can do zmprov -l gaa | sort >> /var/zimbra/users.txt .

Thanks
tinging
Posts: 2
Joined: Sat Jul 25, 2020 7:07 am

Re: How to delete X days old email

Post by tinging »

It's very easy to use.
I added that each message folder can be retrieved for clearing

for all_folder in $(eval "$ZIMBRA_BIN/zmmailbox -z -m $_account gaf | grep /|grep mess| sed -e 's/^[ \t]*//' | tr -s ' ' | cut -d ' ' -f 5")
for messageId................................................
................................................
done
if [ $_rows -gt 0 ]; then

Erik-NA wrote:Hello
Modified the script a bit:
  • Can run as a cron job
  • Can now handle spaces in folder name
  • Using DeleteItem instead of DeleteMessage in zmmailbox since I got errors when trying to delete some messages using DeleteMessage
Todo: Better error handling from zmmailbox

Run as user zimbra.

Modify according to your needs :)

Code: Select all

#!/bin/bash
#
ZIMBRA_BIN=/opt/zimbra/bin

#Params: account folder days
#Account name
#Folder name
#Number of days for which older emails will be deleted
doPurge ()
{
    local _account="$1"
    local _folder="$2"
    local _days=$(eval "date --date='$3 days ago' +%m/%d/%y")
    local _rows=0
    local _totalRows=0
         
    rm -f /tmp/deleteOldMessagesList.txt
    rm -f /tmp/process.log
    while true; do
        _rows=0
        touch /tmp/deleteOldMessagesList.txt
        for messageId in $(eval "$ZIMBRA_BIN/zmmailbox -z -m $_account search -l 1000 'in:\"$_folder\" (before:$_days)' | grep conv | sed -e 's/^[ \t]*//' | tr -s ' ' | cut -d ' ' -f 2")
        do
            if [[ ! -z "$messageId" ]]; then 
                echo "deleteMessage $messageId" >> /tmp/deleteOldMessagesList.txt
                _rows=$[$_rows+1]
            fi
        done
        
        if [ $_rows -gt 0 ]; then
            $ZIMBRA_BIN/zmmailbox -z -m $_account < /tmp/deleteOldMessagesList.txt >> /tmp/process.log
            rm -f /tmp/deleteOldMessagesList.txt
            _totalRows=$[$_totalRows + $_rows]
        else
            break
        fi
    done
    echo $_totalRows
}

for account in $(eval "$ZIMBRA_BIN/zmprov -l gaa")
do 
    echo "Purging Emails for account $account"
    rows=$(doPurge "$account" "Activity Stream" "90")
    echo "Deleted $rows rows for account $account"
done
exit
Post Reply