как сделать резервную копию / экспортировать электронную почту Office 365 в pst в гибридной среде обмена?

У нас есть гибридная среда обмена . (некоторые пользователи находятся в локальной системе обмена, а некоторые - в офисе 365.)

Когда мы хотим экспортировать электронные письма из onpremis , мы используем команду ниже для экспорта почтового ящика и архива.

 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 отлично работает для пользователей onpremis, а не для Office 365. Есть ли способ экспортировать почтовый ящик пользователя Office 365 в pst с помощью PowerShell?

То, что я пробовал до сих пор:

Я зашел в офис 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

и попробовал New-MailboxExportRequest

, но он выдает ошибку. очевидно, офис 365 не знает эту команду

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

Также Get-Command * Export * результаты следующие

enter image description here

Пробовал поискать в Google, но не смог найти приемлемый вариант. может кто-нибудь направить меня, пожалуйста? Какая команда совместима в офисной среде для этого?

PS: Я пробовал https://www.codetwo.com/admins-blog/how-to-export-office-365-mailboxes-to-pst-using-ediscovery/ с лицензией E5, и он работает в графический интерфейс отлично. Но меня беспокоит даже электронное обнаружение, и есть ли у меня возможность делать это с помощью PowerShell? я имею в виду сценарий / автоматизацию с помощью PowerShell?

4
задан 11 May 2018 в 13:20
2 ответа

Вы не можете экспортировать почтовый ящик Exchange Online напрямую в PST через PowerShell с помощью встроенных инструментов. Обязательный New-MailboxExportRequest не существует в сети (или не доступен для нас, смертных).

Вы можете:

  • eDiscovery, похоже, только с графическим интерфейсом.
  • Выгрузить / перенести почтовый ящик на локальный Exchange и запустите New-MailboxExportRequest локально (и при необходимости вернитесь к Exchange Online)
  • Используйте различные сторонние инструменты, которые выполняют экспорт через EWS или MAPI
  • . Полный доступ к делегированию сценария, привязка Outlook к делегированному почтовому ящику и экспорт в ТИХООКЕАНСКОЕ СТАНДАРТНОЕ ВРЕМЯ. Технически очень вероятно, но я никогда не видел, чтобы кто-то делал это. Я не углублялся в eDiscovery, но считаю, что это более-менее то, как eDiscovery экспортирует в PST (старые биржи также использовались для привязки к Outlook для экспорта PST). Но без значительного опыта работы с MAPI модель Outlook COM довольно сложна в использовании (я написал несколько сценариев для Outlook, но эмулировать экспорт PST, мягко говоря, сложно)

Я разочарован не меньше вас. Экспорт почтовых ящиков уходящих пользователей на длительное хранение излишне утомляет. Если бы мы могли просто экспортировать в Azure Blob так же, как и импорт, это было бы хорошим началом.

5
ответ дан 3 December 2019 в 03:15

זו לא תשובה לשאלה: טרם ניסיתי לייצא ישירות מ- Exchange Online ל- PST.

הכוונה היא כהשלמה לנקודה האחרונה בתשובת @ DonZoomiks. קצת Powershell, פרנקנשטיינה ממקורות לא ברורים שונים ושואב דואר מ- Exchange Online. התאם אישית לפי הצורך.

המוצר הוא אובייקט מותאם אישית המכיל דואר שאוחזר. אולי מישהו יכול להתאמן ולשתף כיצד לעבור משם ל- PST מבלי לעבור את Outlook ?

דרישה היא Exchange Web (EWS) Managed API 2.2

אז שתי פונקציות ראשונות:

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 user@domain.com
      $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
}

ו-

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 'my.name@example.com' when string has form of e.g. '"My Name" <my.name@example.com>'
          $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.
}

אז אפשר:

$Cred = Get-Credential #Example user: user@example.com
$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 *

ולבסוף לעבד $ Mails כפי שתרצה.

0
ответ дан 3 December 2019 в 03:15

Теги

Похожие вопросы