web-dev-qa-db-fra.com

comment sauvegarder / exporter des e-mails Office 365 vers pst dans un environnement hybride d'échange?

Nous avons un environnement hybride d'échange . (certains utilisateurs sont en échange sur site et certains utilisateurs sont Office 365.)

Lorsque nous voulons exporter des e-mails depuis onpremis , nous utilisons la commande ci-dessous pour exporter la boîte aux lettres et l'archivage.

 New-MailboxExportRequest -Mailbox "user" -FilePath \\mysrv\l$\PST\Mailbox-user.pst; New-MailboxExportRequest -Mailbox "user" -IsArchive  -FilePath \\mysrv\l$\PST\Mailbox-user-archive.pst -confirm:$false

New-MailboxExportRequest fonctionne bien pour les utilisateurs onpremis et non pour Office 365. existe-t-il un moyen d'exporter la boîte aux lettres des utilisateurs Office 365 vers pst à l'aide de powershell?

Ce que j'ai essayé jusqu'à présent:

Je me suis connecté à Office 365

$UserCredential = Get-Credential
Import-Module MSOnline

Connect-MsolService -Credential $UserCredential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://Outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication  Basic -AllowRedirection

Import-PSSession $Session

et essayé New-MailboxExportRequest

Mais cela génère une erreur. apparemment Office 365 ne connaît pas cette commande

PS C:\Users\pp> New-MailboxExportRequest
New-MailboxExportRequest : The term 'New-MailboxExportRequest' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is
correct and try again.
At line:1 char:1
+ New-MailboxExportRequest
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (New-MailboxExportRequest:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Aussi Get-Command *Export* les résultats sont les suivants

enter image description here

Googlé essayé, mais n'a pas pu trouver une option viable. quelqu'un peut-il me guider s'il vous plaît? Quelle est la commande compatible dans l'environnement de bureau pour ce faire?

PS: J'ai essayé https://www.codetwo.com/admins-blog/how-to-export-office-365-mailboxes-to-pst-using-ediscovery/ avec la licence E5 et cela fonctionne parfaitement dans l'interface graphique. mais ma préoccupation est même avec e-discovery, et avoir une licence toute possibilité de le faire avec PowerShell? je veux script/automatiser via PowerShell?

4
user879

Vous ne pouvez pas exporter la boîte aux lettres Exchange Online directement vers PST via PowerShell avec des outils intégrés. New-MailboxExportRequest requis n'existe pas en ligne (ou n'est pas exposé à nous, mortels).

Vous pouvez:

  • eDiscovery, qui semble être uniquement GUI.
  • Décharger/migrer la boîte aux lettres vers Exchange sur site et exécuter New-MailboxExportRequest sur site (et migrer vers Exchange Online si nécessaire)
  • Utilisez divers outils tiers qui effectuent l'exportation via EWS ou MAPI
  • Accès complet à la délégation de script, liaison Outlook à la boîte aux lettres déléguée et exportation vers PST. Techniquement très probablement possible, mais je n'ai jamais vu personne le faire. Je n'ai pas approfondi la découverte électronique, mais je pense que c'est à peu près ainsi que la découverte électronique exporte vers PST (Old Exchanges était également utilisé pour se lier à Outlook pour l'exportation PST). Mais sans expérience MAPI significative, le modèle COM d'Outlook est assez complexe à utiliser (j'ai fait quelques scripts Outlook mais l'émulation de l'exportation PST est pour le moins difficile).

Je suis aussi frustré que toi. L'exportation de boîtes aux lettres pour les utilisateurs sortants pour un stockage à long terme est inutilement ennuyeuse. Si nous pouvions simplement exporter vers Azure Blob comme pour l'importation, ce serait un bon début.

5
Don Zoomik

Ce n'est pas une réponse à la question: je n'ai pas encore essayé d'exporter directement d'Exchange Online vers PST.

Il s'agit d'un complément au dernier point de la réponse @DonZoomiks. Un peu de Powershell, Frankensteined de diverses sources obscures et qui tire le courrier d'Exchange Online. Personnalisez au besoin.

Le produit est un objet personnalisé contenant du courrier récupéré. Peut-être que quelqu'un peut travailler et partager comment aller de là à PST sans passer par Outlook ?

Une exigence est Exchange Web Services (EWS) Managed API 2.2

Donc 2 premières fonctions:

function Enter-ExchangeOnlineSession {
  <#
      .Synopsis
      Sets up a user session with ExchangeOnline, typically to fetch mail.
      .DESCRIPTION
      Sets up a user session with ExchangeOnline, typically to fetch mail.
      .EXAMPLE
      $CredMail = Get-Credential -UserName [email protected]
      $Service = Enter-ExchangeOnlineSession -Credential $CredMail -MailDomain domain.com
      .INPUTS
      Inputs to this cmdlet (if any)
      .OUTPUTS
      Output from this cmdlet (if any)
      .NOTES
      General notes
      .COMPONENT
      The component this cmdlet belongs to
      .ROLE
      The role this cmdlet belongs to
      .FUNCTIONALITY
      The functionality that best describes this cmdlet
  #>
  Param(
    [Parameter(ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true,
        Position=0)]
    [ValidateNotNullOrEmpty()]
    [string]$EWSAssemblyPath = 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll',

    # Parameter Credential
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=1)]
    [System.Management.Automation.CredentialAttribute()]
    $Credential,

    # Parameter Maildomain
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=2)]
    [string]$MailDomain,

    # Parameter Maildomain
    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=3)]
    [string]$AutoDiscoverCallbackUrl = 'https://autodiscover-s.Outlook.com/autodiscover/autodiscover.xml'

  )

  # Set the path to your copy of EWS Managed API and load the Assembly.
  [void][Reflection.Assembly]::LoadFile($EWSAssemblyPath) 

  # Establish the session and return the service connection object.
  $service =  New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
  $Service.Credentials = New-Object System.Net.NetworkCredential($Credential.UserName, $Credential.GetNetworkCredential().Password, $MailDomain)

  $TestUrlCallback = {
    param ([string] $url)
    if ($url -eq $AutoDiscoverCallbackUrl) {$true} else {$false}
  }
  $service.AutodiscoverUrl($Credential.UserName, $TestUrlCallback)

  return $Service
}

et

function Get-ExchangeOnlineMailContent {
  <#
      .Synopsis
      Fetches content from an Exchange Online user session, typically mail.
      .DESCRIPTION
      Fetches content from an Exchange Online user session, typically mail.
      .EXAMPLE
      $Service = Enter-ExchangeOnlineSession -Credential $CredMail -MailDomain example.com
      Get-ExchangeOnlineMailContent -ServiceObject $Service -PageSize 5 -Offset 0 -PageIndexLimit 15 -WellKnownFolderName Inbox
      .INPUTS
      Inputs to this cmdlet (if any)
      .OUTPUTS
      Output from this cmdlet (if any)
      .NOTES
      General notes
      .COMPONENT
      The component this cmdlet belongs to
      .ROLE
      The role this cmdlet belongs to
      .FUNCTIONALITY
      The functionality that best describes this cmdlet
  #>

  Param(
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=0)]
    $ServiceObject,

    # Define paging as described in https://msdn.Microsoft.com/en-us/library/office/dn592093(v=exchg.150).aspx
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=1)]
    [int]$PageSize,

    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=2)]
    [int]$Offset,

    #Translates into multiples of $PageSize
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=3)]
    [int]$PageIndexLimit,

    # WellKnownFolderNames doc https://msdn.Microsoft.com/en-us/library/Microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx
    [Parameter(Mandatory=$true, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=4)]
    [ValidateSet('Calendar',
                'Contacts',
                'DeletedItems',
                'Drafts',
                'Inbox',
                'Journal',
                'Notes',
                'Outbox',
                'SentItems',
                'Tasks',
                'MsgFolderRoot',
                'PublicFoldersRoot',
                'Root',
                'JunkEmail',
                'SearchFolders',
                'VoiceMail',
                'RecoverableItemsRoot',
                'RecoverableItemsDeletions',
                'RecoverableItemsVersions',
                'RecoverableItemsPurges',
                'ArchiveRoot',
                'ArchiveMsgFolderRoot',
                'ArchiveDeletedItems',
                'ArchiveRecoverableItemsRoot',
                'ArchiveRecoverableItemsDeletions',
                'ArchiveRecoverableItemsVersions',
                'ArchiveRecoverableItemsPurges',
                'SyncIssues',
                'Conflicts',
                'LocalFailures',
                'ServerFailures',
                'RecipientCache',
                'QuickContacts',
                'ConversationHistory',  
                'ToDoSearch')]
    [string]$WellKnownFolderName,

    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=5)]
    [switch]$ParseOriginalRecipient,

    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=6)]
    [switch]$OriginalRecipientAddressOnly,

    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=7)]
    [datetime]$MailFromDate,

    [Parameter(Mandatory=$false, 
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true, 
        ValueFromRemainingArguments=$false, 
        Position=8)]
    [switch]$ConsoleOutput
  )

  # Create Property Set to include body and header, set body to text.
  $PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
  $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text

  if ($ParseOriginalRecipient)
  {
    $PR_TRANSPORT_MESSAGE_HEADERS = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x007D,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
    $PropertySet.add($PR_TRANSPORT_MESSAGE_HEADERS)
  }

  $PageIndex = 0

  # Page through folder.
  do 
  { 
    # Limit the view to $pagesize number of email starting at $Offset.
    $PageView = New-Object Microsoft.Exchange.WebServices.Data.ItemView($PageSize,$PageIndex,$Offset)

    # Get folder data.
    $FindResults = $ServiceObject.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::$WellKnownFolderName,$PageView) 
    foreach ($MailItem in $FindResults.Items)
    {
      # Load extended properties.
      $MailItem.Load($propertySet)

      if ($ParseOriginalRecipient)
      {
        # Extended properties are one string, split by linebreak then find the line beginning with 'To:', containing original recipient address before exchange aliasing replaces it.
        $OriginalRecipientStringRaw = ($MailItem.ExtendedProperties.value.split([Environment]::NewLine) | Where-Object {$_ -match '^To:'}).trimstart('To:').trim()

        $MailItem | Add-Member -NotePropertyName ExtendedHeader -NotePropertyValue $OriginalRecipientStringRaw

        if ($OriginalRecipientAddressOnly)
        {
          # Removes everything but the address '[email protected]' when string has form of e.g. '"My Name" <[email protected]>'
          $MailItem | Add-Member -NotePropertyName OriginalRecipient -NotePropertyValue ($OriginalRecipientStringRaw | ForEach-Object {($_.ToString() -creplace '^[^<]*<', '').trimend('>')})
        }
        else
        {
          $MailItem | Add-Member -NotePropertyName OriginalRecipient -NotePropertyValue $OriginalRecipientStringRaw
        }
        if ($ConsoleOutput) {write-Host -ForegroundColor Cyan "$($MailItem.DateTimeReceived) | $($MailItem.OriginalRecipient) | $($MailItem.Sender)"}
      }

      # Output result.
      $MailItem | Select-Object -Property *
    } 

    # Increment $index to next page.
    $PageIndex += $PageSize
  } while (($FindResults.MoreAvailable) `
            -and ($PageIndex -lt $PageIndexLimit) `
            -and ($MailItem.DateTimeReceived -gt $MailFromDate)) # Do/While there are more emails to retrieve and pagelimit is not exceeded and datetimereceived is later than date.
}

alors on peut:

$Cred = Get-Credential #Example user: [email protected]
$domain = 'example.com'

# Set how many emails we want to read at a time
$PageSizeNumOfEmails = 10
$OffSet = 0
$PageIndexLimit = 2000
$MailFolder = 'Inbox'
$DeltaTimeStamp = (Get-Date).AddDays(-30) #Go how many days back?

try
{
  $Session = Enter-ExchangeOnlineSession -Credential $Cred -MailDomain $domain
}
catch
{
  $Message = $_.exception.message
  Write-Host -ForegroundColor Yellow $Message
}

$Mails = Get-ExchangeOnlineMailContent -ServiceObject $Session `
                                        -PageSize $PageSizeNumOfEmails `
                                        -Offset $OffSet `
                                        -PageIndexLimit $PageIndexLimit `
                                        -WellKnownFolderName $MailFolder `
                                        -ParseOriginalRecipient `
                                        -OriginalRecipientAddressOnly `
                                        -MailFromDate $DeltaTimeStamp | Where-Object {$_.DateTimeReceived -gt $DeltaTimeStamp} | select *

et enfin traiter $Mails comme tu le feras.

0
ErikE