Maintain control of your Microsoft 365 data
Post Reply
GTL
Novice
Posts: 4
Liked: 1 time
Joined: Apr 05, 2018 4:47 pm
Full Name: GL
Contact:

Export all mailboxes to individual .pst powershell

Post by GTL »

Hi everyone!! I have called veeam support and was told they cannot help me with these powershell commands.

I am testing exporting all backed up mailboxes to individual psts. I am aware that there is no GUI function to do so. You can only export individually.

However, i found these veeam instructions:

https://helpcenter.veeam.com/docs/vbo36 ... tml?ver=15
Example 2 will allow me to whip up a .bat file that will kick off a full export to pst for individual mailboxes, but i can't get past line 2:

1) $session = Get-VBOExchangeItemRestoreSession
this works fine
2) $database = Get-VEXDatabase -Session $session
gives me this error message:

Code: Select all

Get-VEXDatabase : Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:1 char:38
+ $database = Get-VEXDatabase -Session $session
+                                      ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-VEXDatabase], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Veeam.Exchange.PowerShell.Cmdlets.Items.GetVEXDatabase

Any ideas? I dont really get that far and it already comes back with an error.

Thank you!
veremin
Product Manager
Posts: 20419
Liked: 2306 times
Joined: Oct 26, 2012 3:28 pm
Full Name: Vladimir Eremin
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by veremin »

Is there a running restore session? Does a session variable return anything? Thanks.
GTL
Novice
Posts: 4
Liked: 1 time
Joined: Apr 05, 2018 4:47 pm
Full Name: GL
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by GTL » 1 person likes this post

I have found the answer, run the following commands from a powershell that has been "right click" run as administrator.

$organization = Get-VBOOrganization -Name "ThisIsTheOrganizationNameThatShowsUpUnderOrganizations"
Start-VBOExchangeItemRestoreSession -LatestState -Organization $organization
$session = Get-VBOExchangeItemRestoreSession
$database = Get-VEXDatabase -Session $session

Now this part has the export

$mailbox = Get-VEXMailbox -Database $database -Name "ThisIsTheMailboxDisplayName"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\NameOfThePSTFile.pst"

I whipped up some notepad and excel magic and created the following .ps1 file (its a .bat file that you run in powershell using .\filenameyouused.ps1)

As an example, here are the contents of the .ps1 file i created


$organization = Get-VBOOrganization -Name "BlahBlahBlah.onmicrosoft.com"
Start-VBOExchangeItemRestoreSession -LatestState -Organization $organization
$session = Get-VBOExchangeItemRestoreSession
$database = Get-VEXDatabase -Session $session
$mailbox = Get-VEXMailbox -Database $database -Name "AC Forms"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\AC Forms.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Accounts Payable - Email"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Accounts Payable - Email.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Accounts Receivable"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Accounts Receivable.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Admin"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Admin.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Annie Herrera"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Annie Herrera.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Angela Arme"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Angela Arme.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Anne Flam"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Anne Flam.pst"
$mailbox = Get-VEXMailbox -Database $database -Name "Anthony Buinn"
Export-VEXItem -Mailbox $mailbox -To "E:\Office365 Backups\Full PST Export\Anthony Buinn.pst"


etc etc etc
you get the idea

Here are the links i figured it out from:
https://helpcenter.veeam.com/docs/vbo36 ... tml?ver=15
(i used example2)
and
https://helpcenter.veeam.com/docs/vbo36 ... tml?ver=15
GTL
Novice
Posts: 4
Liked: 1 time
Joined: Apr 05, 2018 4:47 pm
Full Name: GL
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by GTL »

NOTE!

I have noticed some failures during the export but was unable to see which mailbox it failed on because the error message were to long and got chopped off.

I have tried adding -ResultSize Unlimited but it seems the Export-VexItem command doesnt recognize it.

I suggest changing your export directory to something very very short so you can read which mailbox failed. Example: E:\V\Blahblah.pst
jedduff
Novice
Posts: 3
Liked: 2 times
Joined: Jan 05, 2017 1:55 pm
Full Name: Jeremie Dufault
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by jedduff » 2 people like this post

Hi! I use your script, but I created a csv file with a ForEach to extract the pst file.

This is the script I made

$mailbox = Get-VEXMailbox -Database $database -Name "YOURORGANIZATIONNAME"
$users = Import-Csv c:\temp\users.csv
ForEach ($user in $users) {
$mailbox = Get-VEXMailbox -Database $database -Name "$($user.accountname)"
Export-VEXItem -Mailbox $mailbox -To "d:\pst\$($user.accountname).pst"
}

Image
Symbiot78
Influencer
Posts: 19
Liked: 1 time
Joined: Mar 27, 2019 8:24 am
Full Name: Martin Rask Thomsen
Contact:

[MERGED]periodic export to <some drive option> ?

Post by Symbiot78 »

Hi

my org has a requirement to export all mailboxes to an external drive for safekeeping offline. Say.. monthly.. or quarterly.

anyway I can achieve this in the veeam console? or is there a scripting option?
Egor Yakovlev
Product Manager
Posts: 2581
Liked: 709 times
Joined: Jun 14, 2013 9:30 am
Full Name: Egor Yakovlev
Location: Prague, Czech Republic
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Egor Yakovlev »

Hi Martin,
Merged your post with existing thread. Check answers above.
Scripted Export-VEXItem should do the trick.
/Cheers!
Symbiot78
Influencer
Posts: 19
Liked: 1 time
Joined: Mar 27, 2019 8:24 am
Full Name: Martin Rask Thomsen
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Symbiot78 »

Hi

Thx for the merge.

I've created the following script based on content in this thread:

Code: Select all

$organization = Get-VBOOrganization -Name "ORG_NAME_IN_VO365"
Start-VBOExchangeItemRestoreSession -LatestState -Organization $organization
$session = Get-VBOExchangeItemRestoreSession
$database = Get-VEXDatabase -Session $session




$mailboxes = Get-VEXMailbox -Database $database

foreach ($user in $mailboxes)
{

$mailbox = Get-VEXMailbox -Database $database -name $user
Export-VEXItem -Mailbox $mailbox -To "Z:\test_export\$($user.Email).pst"
}

Ti360
Novice
Posts: 8
Liked: never
Joined: Sep 04, 2014 1:02 pm
Full Name: Sebastien Boivin
Contact:

[MERGED] Backup export with powershell example

Post by Ti360 »

Hello everyone,

I recently discover what we could do with powershell, and I was wondering if anyone use powershell to manage their backups.
I think it would would be possible to backup a shared mailbox, export its content to PST and Zip file for OneDrive then delete the user data from the backup in a single script file?

What would be the easiest way to accomplish that.

thanks for your comment..
Natalia Lupacheva
Veteran
Posts: 1143
Liked: 302 times
Joined: Apr 27, 2020 12:46 pm
Full Name: Natalia Lupacheva
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Natalia Lupacheva »

Hi Sebastien,

moved your post to the existing thread, here you can find how to export data.
You can extend these scripts for you needs, adding Start-VBOJob to run the backup job.

As foe deleting, not sure if you mean Remove-VBOEntityData or something else.

Thanks!
EskBackupGuy23
Influencer
Posts: 19
Liked: 1 time
Joined: Jan 24, 2023 7:43 pm
Full Name: Crypto Ron
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by EskBackupGuy23 »

How would I modify the script to include a specific date range for the emails I would like to export to .pst file?

Thank you in advance!

GTL wrote: Apr 05, 2018 4:54 pm Hi everyone!! I have called veeam support and was told they cannot help me with these powershell commands.

I am testing exporting all backed up mailboxes to individual psts. I am aware that there is no GUI function to do so. You can only export individually.

However, i found these veeam instructions:

https://helpcenter.veeam.com/docs/vbo36 ... tml?ver=15
Example 2 will allow me to whip up a .bat file that will kick off a full export to pst for individual mailboxes, but i can't get past line 2:

1) $session = Get-VBOExchangeItemRestoreSession
this works fine
2) $database = Get-VEXDatabase -Session $session
gives me this error message:

Code: Select all

Get-VEXDatabase : Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:1 char:38
+ $database = Get-VEXDatabase -Session $session
+                                      ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-VEXDatabase], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Veeam.Exchange.PowerShell.Cmdlets.Items.GetVEXDatabase

Any ideas? I dont really get that far and it already comes back with an error.

Thank you!
EskBackupGuy23
Influencer
Posts: 19
Liked: 1 time
Joined: Jan 24, 2023 7:43 pm
Full Name: Crypto Ron
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by EskBackupGuy23 »

How would one incorporate the following date range into the script below?

received:>=8/3/21 AND received:<=12/8/22

Looking everywhere trying to figure this one out :)

quote=Symbiot78 post_id=359408 time=1582015867 user_id=88339]
Hi

Thx for the merge.

I've created the following script based on content in this thread:

Code: Select all

$organization = Get-VBOOrganization -Name "ORG_NAME_IN_VO365"
Start-VBOExchangeItemRestoreSession -LatestState -Organization $organization
$session = Get-VBOExchangeItemRestoreSession
$database = Get-VEXDatabase -Session $session




$mailboxes = Get-VEXMailbox -Database $database

foreach ($user in $mailboxes)
{

$mailbox = Get-VEXMailbox -Database $database -name $user
Export-VEXItem -Mailbox $mailbox -To "Z:\test_export\$($user.Email).pst"
}

[/quote]
EskBackupGuy23
Influencer
Posts: 19
Liked: 1 time
Joined: Jan 24, 2023 7:43 pm
Full Name: Crypto Ron
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by EskBackupGuy23 »

Would like to add some logic to skip mailboxes it has already done.. PST files already exist. The VBO commands just do not seem that friendly. Anyone else have any ideas on how to incorporate that into this script below?
Symbiot78 wrote: Feb 18, 2020 8:51 am Hi

Thx for the merge.

I've created the following script based on content in this thread:

Code: Select all

$organization = Get-VBOOrganization -Name "ORG_NAME_IN_VO365"
Start-VBOExchangeItemRestoreSession -LatestState -Organization $organization
$session = Get-VBOExchangeItemRestoreSession
$database = Get-VEXDatabase -Session $session




$mailboxes = Get-VEXMailbox -Database $database

foreach ($user in $mailboxes)
{

$mailbox = Get-VEXMailbox -Database $database -name $user
Export-VEXItem -Mailbox $mailbox -To "Z:\test_export\$($user.Email).pst"
}

Mike Resseler
Product Manager
Posts: 8191
Liked: 1322 times
Joined: Feb 08, 2013 3:08 pm
Full Name: Mike Resseler
Location: Belgium
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Mike Resseler »

Hey,

Not sure how you get mailboxes that it already has done. Did you need to restart the script?
Regnor
VeeaMVP
Posts: 1008
Liked: 314 times
Joined: Jan 31, 2011 11:17 am
Full Name: Max
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Regnor » 1 person likes this post

With test-path you can check if a file exists:
If(!(test-path "Z:\test_export\$($user.Email).pst")){ }

However this won't check if the PST actually contains data or if it's export was successfull.

Edit: Added the !(), as you want to run the export when the PST doesn't exist.
EskBackupGuy23
Influencer
Posts: 19
Liked: 1 time
Joined: Jan 24, 2023 7:43 pm
Full Name: Crypto Ron
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by EskBackupGuy23 »

The script was interrupted due to a restart of the server that was hosting the O365 mailbox backup store :(
Mike Resseler wrote: Feb 10, 2023 7:58 pm Hey,

Not sure how you get mailboxes that it already has done. Did you need to restart the script?
EskBackupGuy23
Influencer
Posts: 19
Liked: 1 time
Joined: Jan 24, 2023 7:43 pm
Full Name: Crypto Ron
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by EskBackupGuy23 »

Hi Regnor -

Thank you!

So in the script line I should be able to insert this line before the Export-VEXItem ?

If(!(test-path "Z:\test_export\$($user.Email).pst")){ }
Export-VEXItem -Mailbox $mailbox -To "Z:\test_export\$($user.Email).pst"

Thank you for your time!

Much appreciated!
Regnor wrote: Feb 11, 2023 3:29 pm With test-path you can check if a file exists:
If(!(test-path "Z:\test_export\$($user.Email).pst")){ }

However this won't check if the PST actually contains data or if it's export was successfull.

Edit: Added the !(), as you want to run the export when the PST doesn't exist.
dasfliege
Service Provider
Posts: 277
Liked: 61 times
Joined: Nov 17, 2014 1:48 pm
Full Name: Florin
Location: Switzerland
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by dasfliege » 2 people like this post

As it may be of use for someone, i can share the scripts that we've created to export all mailboxes, onendrives and teams of a specific tenant. It has some logic already to check which items already exists in case you have to restart it for some reason, but i think i have not implemented it for all the restore types yet. However, it may help the one or the other of you.

We use the script to export backups for our customers on a yearly base. So there is a logic as well to find the latest available restore point for a given date and export only that one. It creates a subfolder for each user.

- Mailboxes are exported as PST
- Onedrive and Teams Files are compressed as ZIP

Code: Select all

#requires -Version 3.0
#Requires -RunAsAdministrator

# Specify Veeam Organisation for Export
$VeeamOrganization = "xxxxxxxx.onmicrosoft.com"

# Define Export Path
$ExportPath = "c:\restore" # ->> Without "\" on the end

# Specify Restore Point Date
$RestoreDate = "12-31" # Format -> MM-dd

# Specify Elements to restore
# 1 = yes / 0 = no
$RestoreMailbox = 1
$RestoreOneDrive = 1
$RestoreTeams = 1



# ********* STOP EDITING HERE ********* #

$veeamInstallPath = $(Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication" -Name CorePath).CorePath
if (Test-Path "$($veeamInstallPath)Initialize-VeeamToolkit.ps1")
{
    Try
    {
        . "$($veeamInstallPath)Initialize-VeeamToolkit.ps1"
    }
    catch
    {
        Write-Host "Unable to load Veeam Module." -ForegroundColor Red
        break
    }
}

# Define VB Organization
$organization = Get-VBOOrganization -Name $VeeamOrganization

# Define RestoreDate
$ThisYear = Get-Date
$RestoreDateTime = [DateTime]"$(Get-Date $ThisYear -Format "yyyy")-$($RestoreDate)"
if((Get-Date) -lt $RestoreDateTime)
{
    # Defined $RestoreDate is in the future -> Setting one Year back
    $LastYear = (Get-Date).AddYears(-1)
    $RestoreDateTime = [DateTime]"$(Get-Date $LastYear -Format "yyyy")-$($RestoreDate)"
}

# Define RestorePoint
$RestorePointAll = Get-VBORestorePoint -Organization $organization | Where-Object {
    "$(Get-Date $_.BackupTime -Format "dd.MM.yyyy")" -eq "$(Get-Date $RestoreDateTime -Format "dd.MM.yyyy")"
} 



# Stop if no restore Points was found on given Date
if($RestorePointAll.Count -eq 0)
{
    Write-Host "Unable to find a Restore Point at Date $(Get-Date $RestoreDateTime -Format "dd.MM.yyyy")." -ForegroundColor Red
    break
} else {
        Write-Host "Found the following Restore Point(s) for: " $RestoreDateTime -ForegroundColor green
        $RestorePointAll
       }
            




#####################
### Exchange Part ###
#####################

if($RestoreMailbox -eq 1)
{
    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsExchange -eq "True"      
    }    
    
    Write-Host "Starting restore of Mailboxes using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    Start-VBOExchangeItemRestoreSession -RestorePoint $RestorePoint -Organization $organization
    $exSession = Get-VBOExchangeItemRestoreSession
    $database = Get-VEXDatabase -Session $exSession

    $allMailboxes = Get-VEXMailbox -Database $database
    $allMailboxes | Foreach-Object {
        $userExportPath = "$ExportPath\$($_.Name)\Mailbox"
        if (-not(Test-Path -Path $userExportPath))
        {
            New-Item -ItemType Directory -Force -Path $userExportPath
        }
        Export-VEXItem -Mailbox $_ -To "$userExportPath\Mailbox_$($_.Name).pst"
    }

    # Stop the Restore Session(s)
    if($exSession)
    {
        $exSession | foreach-object {
            Stop-VBOExchangeItemRestoreSession -Session $_
        }
    }
}


#####################
### OneDrive Part ###
#####################

if($RestoreOnedrive -eq 1)
{

    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsOneDrive -eq "True"      
    }    
    
    Write-Host "Starting restore of OneDrives using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    Start-VEODRestoreSession -RestorePoint $RestorePoint -Organization $organization
    $odSession = Get-VEODRestoreSession

    $allODUser = Get-VEODUser -Session $odSession
    $allODUser | Foreach-Object {
        $userExportPath = "$ExportPath\$($_.Name)\OneDrive"
        if (-not(Test-Path -Path $userExportPath))
        {
            New-Item -ItemType Directory -Force -Path $userExportPath
        }
        if (-not(Test-Path -Path $userExportPath\OneDrive_$($_.Name).zip))
        {
        Write-Host "Saving item OneDrive_$($_.Name).zip" -ForegroundColor green
        Save-VEODDocument -User $_ -Path "$userExportPath\OneDrive_$($_.Name).zip" -AsZip
        }
        else {
            Write-Host "Item OneDrive_$($_.Name).zip already exists" -ForegroundColor green
            }
    }

    # Stop the Restore Session(s)
    if($odSession)
    {
        $odSession | foreach-object {
            Stop-VEODRestoreSession -Session $_
        }
    }
}


#####################
### MSTeams Part  ###
#####################

if($RestoreTeams -eq 1)
{

    
    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsTeams -eq "True"      
    }    
    
    Write-Host "Starting restore of Teams using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    $MSTSessError = $false
    try {
        Start-VBOTeamsItemRestoreSession -RestorePoint $RestorePoint -Organization $organization
    }
    catch {
        Write-Host "Unable to find a Restore Point at Date $(Get-Date $RestoreDateTime -Format "dd.MM.yyyy") for MSTeams:" -ForegroundColor Red
        Write-Host $_ -ForegroundColor Red
        $MSTSessError = $true
    }

    if(!$MSTSessError)
    {
        $mstSession = Get-VBOTeamsItemRestoreSession
        $mstOrganization = Get-VETOrganization -Session $mstSession
        $allTeams = Get-VETTeam -Organization $mstOrganization
        $allTeams | Foreach-Object {
            $mstExportPath = "$ExportPath\_TeamsExport\$($_.DisplayName)"
            if (-not(Test-Path -Path $mstExportPath))
            {
                New-Item -ItemType Directory -Force -Path $mstExportPath
            }else
            {
                # If Folder exists (Duplicate), then add _(+1) behind the Name (Max 10 Times possible)
                for ($i=1; $i -le 10; $i++)
                {
                    $ExportPathNew = "$($mstExportPath)_$($i)"
                    Write-host $ExportPathNew
                    if (-not(Test-Path -Path $ExportPathNew))
                    {
                        New-Item -ItemType Directory -Force -Path $ExportPathNew
                        $mstExportPath = $ExportPathNew
                        break
                    }
                }
            }

            $allChannels = Get-VETChannel -Team $_
            $allChannels | Foreach-Object {
                $channelExportPath = "$mstExportPath\$($_.DisplayName)"
                if (-not(Test-Path -Path "$channelExportPath\Posts"))
                {
                    New-Item -ItemType Directory -Force -Path "$channelExportPath\Posts"
                }
                $datefrom = [datetime]"1/1/2000 00:00 AM"
                $dateto = $RestoreDateTime
                Export-VETPost -Channel $_ -Path "$channelExportPath\Posts\posts.html" -From $datefrom -To $dateto

                if (-not(Test-Path -Path "$channelExportPath\Files"))
                {
                    New-Item -ItemType Directory -Force -Path "$channelExportPath\Files"
                }
                $channelFile = Get-VETFile -Channel $_
                if(-not([string]::IsNullOrEmpty($channelFile)))
                {
                    Save-VETItem -File $channelFile -Path "$channelExportPath\Files\Files.zip" -AsZip
                }
            }
        }
    }

    # Stop the Restore Session(s)
    if($mstSession)
    {
        $mstSession | foreach-object {
            Stop-VBOTeamsItemRestoreSession -Session $_
        }
    }
}

azlanmatt
Certified Trainer
Posts: 3
Liked: 1 time
Joined: Dec 17, 2014 7:47 pm
Full Name: Matt Carver
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by azlanmatt » 1 person likes this post

Hi dasfliege,

Your script is excellent, thanks for sharing.

Do you have a version of your script that also exports SharePoint Online data? It would be really useful for offboarding tenants.

Thanks
Ctek
Service Provider
Posts: 84
Liked: 13 times
Joined: Nov 11, 2015 3:50 pm
Location: Canada
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Ctek » 1 person likes this post

dasfliege wrote: Feb 14, 2023 11:13 pm As it may be of use for someone, i can share the scripts that we've created to export all mailboxes, onendrives and teams of a specific tenant. It has some logic already to check which items already exists in case you have to restart it for some reason, but i think i have not implemented it for all the restore types yet. However, it may help the one or the other of you.

We use the script to export backups for our customers on a yearly base. So there is a logic as well to find the latest available restore point for a given date and export only that one. It creates a subfolder for each user.

- Mailboxes are exported as PST
- Onedrive and Teams Files are compressed as ZIP
Wow, exactly what I need today, i'll test this and report back, many thanks.
VMCE
dasfliege
Service Provider
Posts: 277
Liked: 61 times
Joined: Nov 17, 2014 1:48 pm
Full Name: Florin
Location: Switzerland
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by dasfliege »

azlanmatt wrote: Feb 16, 2023 12:39 pm Hi dasfliege,

Your script is excellent, thanks for sharing.

Do you have a version of your script that also exports SharePoint Online data? It would be really useful for offboarding tenants.

Thanks
No i don't. I don't have much knowledge of sharepoint, but i think the only things that are exportable in a way that makes sense, are the files within sharepoint?
I'm sure that we have to find a solution for that pretty soon as well, as our customer base is growing from day to day :-)
alexanderbrix
Lurker
Posts: 2
Liked: never
Joined: Jul 26, 2023 12:34 pm
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by alexanderbrix »

dasfliege wrote: Feb 14, 2023 11:13 pm As it may be of use for someone, i can share the scripts that we've created to export all mailboxes, onendrives and teams of a specific tenant. It has some logic already to check which items already exists in case you have to restart it for some reason, but i think i have not implemented it for all the restore types yet. However, it may help the one or the other of you.

We use the script to export backups for our customers on a yearly base. So there is a logic as well to find the latest available restore point for a given date and export only that one. It creates a subfolder for each user.

- Mailboxes are exported as PST
- Onedrive and Teams Files are compressed as ZIP

Code: Select all

#requires -Version 3.0
#Requires -RunAsAdministrator

# Specify Veeam Organisation for Export
$VeeamOrganization = "xxxxxxxx.onmicrosoft.com"

# Define Export Path
$ExportPath = "c:\restore" # ->> Without "\" on the end

# Specify Restore Point Date
$RestoreDate = "12-31" # Format -> MM-dd

# Specify Elements to restore
# 1 = yes / 0 = no
$RestoreMailbox = 1
$RestoreOneDrive = 1
$RestoreTeams = 1



# ********* STOP EDITING HERE ********* #

$veeamInstallPath = $(Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication" -Name CorePath).CorePath
if (Test-Path "$($veeamInstallPath)Initialize-VeeamToolkit.ps1")
{
    Try
    {
        . "$($veeamInstallPath)Initialize-VeeamToolkit.ps1"
    }
    catch
    {
        Write-Host "Unable to load Veeam Module." -ForegroundColor Red
        break
    }
}

# Define VB Organization
$organization = Get-VBOOrganization -Name $VeeamOrganization

# Define RestoreDate
$ThisYear = Get-Date
$RestoreDateTime = [DateTime]"$(Get-Date $ThisYear -Format "yyyy")-$($RestoreDate)"
if((Get-Date) -lt $RestoreDateTime)
{
    # Defined $RestoreDate is in the future -> Setting one Year back
    $LastYear = (Get-Date).AddYears(-1)
    $RestoreDateTime = [DateTime]"$(Get-Date $LastYear -Format "yyyy")-$($RestoreDate)"
}

# Define RestorePoint
$RestorePointAll = Get-VBORestorePoint -Organization $organization | Where-Object {
    "$(Get-Date $_.BackupTime -Format "dd.MM.yyyy")" -eq "$(Get-Date $RestoreDateTime -Format "dd.MM.yyyy")"
} 



# Stop if no restore Points was found on given Date
if($RestorePointAll.Count -eq 0)
{
    Write-Host "Unable to find a Restore Point at Date $(Get-Date $RestoreDateTime -Format "dd.MM.yyyy")." -ForegroundColor Red
    break
} else {
        Write-Host "Found the following Restore Point(s) for: " $RestoreDateTime -ForegroundColor green
        $RestorePointAll
       }
            




#####################
### Exchange Part ###
#####################

if($RestoreMailbox -eq 1)
{
    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsExchange -eq "True"      
    }    
    
    Write-Host "Starting restore of Mailboxes using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    Start-VBOExchangeItemRestoreSession -RestorePoint $RestorePoint -Organization $organization
    $exSession = Get-VBOExchangeItemRestoreSession
    $database = Get-VEXDatabase -Session $exSession

    $allMailboxes = Get-VEXMailbox -Database $database
    $allMailboxes | Foreach-Object {
        $userExportPath = "$ExportPath\$($_.Name)\Mailbox"
        if (-not(Test-Path -Path $userExportPath))
        {
            New-Item -ItemType Directory -Force -Path $userExportPath
        }
        Export-VEXItem -Mailbox $_ -To "$userExportPath\Mailbox_$($_.Name).pst"
    }

    # Stop the Restore Session(s)
    if($exSession)
    {
        $exSession | foreach-object {
            Stop-VBOExchangeItemRestoreSession -Session $_
        }
    }
}


#####################
### OneDrive Part ###
#####################

if($RestoreOnedrive -eq 1)
{

    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsOneDrive -eq "True"      
    }    
    
    Write-Host "Starting restore of OneDrives using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    Start-VEODRestoreSession -RestorePoint $RestorePoint -Organization $organization
    $odSession = Get-VEODRestoreSession

    $allODUser = Get-VEODUser -Session $odSession
    $allODUser | Foreach-Object {
        $userExportPath = "$ExportPath\$($_.Name)\OneDrive"
        if (-not(Test-Path -Path $userExportPath))
        {
            New-Item -ItemType Directory -Force -Path $userExportPath
        }
        if (-not(Test-Path -Path $userExportPath\OneDrive_$($_.Name).zip))
        {
        Write-Host "Saving item OneDrive_$($_.Name).zip" -ForegroundColor green
        Save-VEODDocument -User $_ -Path "$userExportPath\OneDrive_$($_.Name).zip" -AsZip
        }
        else {
            Write-Host "Item OneDrive_$($_.Name).zip already exists" -ForegroundColor green
            }
    }

    # Stop the Restore Session(s)
    if($odSession)
    {
        $odSession | foreach-object {
            Stop-VEODRestoreSession -Session $_
        }
    }
}


#####################
### MSTeams Part  ###
#####################

if($RestoreTeams -eq 1)
{

    
    # Define RestorePoint
    $RestorePoint = Get-VBORestorePoint -Organization $organization | Where-Object {
        ((Get-Date $_.BackupTime -Format "dd.MM.yyyy") -eq (Get-Date $RestoreDateTime -Format "dd.MM.yyyy")) -and $_.IsTeams -eq "True"      
    }    
    
    Write-Host "Starting restore of Teams using restore point: " -ForegroundColor Green
    $RestorePoint

    # Start a Restore Session
    $MSTSessError = $false
    try {
        Start-VBOTeamsItemRestoreSession -RestorePoint $RestorePoint -Organization $organization
    }
    catch {
        Write-Host "Unable to find a Restore Point at Date $(Get-Date $RestoreDateTime -Format "dd.MM.yyyy") for MSTeams:" -ForegroundColor Red
        Write-Host $_ -ForegroundColor Red
        $MSTSessError = $true
    }

    if(!$MSTSessError)
    {
        $mstSession = Get-VBOTeamsItemRestoreSession
        $mstOrganization = Get-VETOrganization -Session $mstSession
        $allTeams = Get-VETTeam -Organization $mstOrganization
        $allTeams | Foreach-Object {
            $mstExportPath = "$ExportPath\_TeamsExport\$($_.DisplayName)"
            if (-not(Test-Path -Path $mstExportPath))
            {
                New-Item -ItemType Directory -Force -Path $mstExportPath
            }else
            {
                # If Folder exists (Duplicate), then add _(+1) behind the Name (Max 10 Times possible)
                for ($i=1; $i -le 10; $i++)
                {
                    $ExportPathNew = "$($mstExportPath)_$($i)"
                    Write-host $ExportPathNew
                    if (-not(Test-Path -Path $ExportPathNew))
                    {
                        New-Item -ItemType Directory -Force -Path $ExportPathNew
                        $mstExportPath = $ExportPathNew
                        break
                    }
                }
            }

            $allChannels = Get-VETChannel -Team $_
            $allChannels | Foreach-Object {
                $channelExportPath = "$mstExportPath\$($_.DisplayName)"
                if (-not(Test-Path -Path "$channelExportPath\Posts"))
                {
                    New-Item -ItemType Directory -Force -Path "$channelExportPath\Posts"
                }
                $datefrom = [datetime]"1/1/2000 00:00 AM"
                $dateto = $RestoreDateTime
                Export-VETPost -Channel $_ -Path "$channelExportPath\Posts\posts.html" -From $datefrom -To $dateto

                if (-not(Test-Path -Path "$channelExportPath\Files"))
                {
                    New-Item -ItemType Directory -Force -Path "$channelExportPath\Files"
                }
                $channelFile = Get-VETFile -Channel $_
                if(-not([string]::IsNullOrEmpty($channelFile)))
                {
                    Save-VETItem -File $channelFile -Path "$channelExportPath\Files\Files.zip" -AsZip
                }
            }
        }
    }

    # Stop the Restore Session(s)
    if($mstSession)
    {
        $mstSession | foreach-object {
            Stop-VBOTeamsItemRestoreSession -Session $_
        }
    }
}

Hello,
I just used your script and modified it so it suites for us. Big big thanks for the script!
We only want to backup our Exchange (on prem, not O365) and we want to export all Mailboxes into seperate PST-files. It really workes great, but it also back ups all HealthMailboxes and In-Situ-Archiv - HealthMailbox, which cointains over 1 mil items...
Can anyone help me to exclude these mailboxes or can tell me how to empty or delete them on the exchange server directly?
Thank you!
Ardjan
Lurker
Posts: 1
Liked: never
Joined: Sep 29, 2023 2:44 pm
Full Name: Ardjan
Contact:

Re: Export all mailboxes to individual .pst powershell

Post by Ardjan »

dasfliege wrote: Feb 14, 2023 11:13 pm As it may be of use for someone, i can share the scripts that we've created to export all mailboxes, onendrives and teams of a specific tenant.
[...]
- Mailboxes are exported as PST
- Onedrive and Teams Files are compressed as ZIP
Thanks, it looks great!
Sorry for waking up this thread, but we need something similar, and my PowerShell knowledge is not quite up to par...

We would need to export the mailbox and Onedrive content of people who are leaving. Twice a year we have up to 30 trainees who leave our organisation.

Can someone add 1-2 lines to select only users from a certain OU (OU=export;OU=users;...) or with a certain string in their description (Get-ADUser -Filter { Description -like "*export*" })?

Thanks in advance!
Post Reply

Who is online

Users browsing this forum: No registered users and 20 guests