У нас есть обмен гибридной средой. (некоторые пользователи используют обмен onpremises, а некоторые - Office 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*
результаты следующие
Пытался погуглить, но не нашел подходящего варианта. может кто-нибудь направить меня, пожалуйста? Какая команда совместима с офисной средой для этого?
PS: я пытался https://www.codetwo.com/admins-blog/how-to-export-office-365-mailboxes-to-pst-using-ediscovery/
с лицензией E5 и отлично работает в графическом интерфейсе. Но меня беспокоит даже электронное обнаружение, и есть ли у меня возможность делать это с помощью PowerShell? я имею в виду сценарий / автоматизацию через PowerShell?
Вы не можете экспортировать почтовый ящик Exchange Online напрямую в PST через PowerShell с помощью встроенных инструментов. Обязательный New-MailboxExportRequest не существует в сети (или не доступен для нас, смертных).
Ты можешь:
Я расстроен так же, как и ты. Экспорт почтовых ящиков уходящих пользователей для длительного хранения бесполезно раздражает. Если бы мы могли просто экспортировать в Azure Blob так же, как и импорт, это было бы хорошим началом.
Это не ответ на вопрос: я еще не пробовал экспортировать напрямую из Exchange Online в PST.
Это сделано в качестве дополнения к последнему пункту ответа @DonZoomiks. Немного Powershell, взятый Франкенштейном из разных малоизвестных источников и извлекающий почту из Exchange Online. При необходимости настройте.
Продукт представляет собой настраиваемый объект, содержащий полученную почту. Возможно, кто-то сможет потренироваться и поделится, как пройти оттуда в PST без передачи Outlook?
Требование Управляемый API 2.2 веб-служб Exchange (EWS)
Итак, первые 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
как хочешь.