Få tilgang til Exchange Online med PowerShell: Erstatt EWS med Microsoft Graph
EWS avsluttes i Exchange Online 1. oktober 2026. Slik registrerer du en app, autentiserer et PowerShell-skript med sertifikat, begrenser tilgangen til enkelte postbokser og behandler meldinger og vedlegg via Microsoft Graph.
Microsoft avvikler Exchange Web Services (EWS) i Exchange Online 1. oktober 2026. Skript som henter meldinger eller vedlegg fra en postboks, må derfor bytte til Microsoft Graph.
Eksempelet i dette innlegget kjører uten brukerinnlogging: Det laster ned ZIP-vedlegg fra en postboks, pakker dem ut, flytter behandlede meldinger og sender deretter en rapport. Dette krever en appregistrering, et sertifikat og to Graph-tillatelser. Verdier som example.com, tenant-ID og app-ID er plassholdere.
1. Nødvendige PowerShell-moduler
Tre moduler fra Microsoft Graph SDK er tilstrekkelig, ikke hele metamodulen Microsoft.Graph:
Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Mail, Microsoft.Graph.Users.Actions -Scope AllUsers
2. Appregistrering i Entra ID
Et uovervåket skript logger på som en applikasjon med egne rettigheter. Opprett en ny registrering i Entra Admin Center under App registrations, og tildel disse to rettighetene under API permissions → Microsoft Graph → Application permissions:
-
Mail.ReadWrite: lese e-post og flytte den etter behandling -
Mail.Send: sende rapport-e-posten
Gi deretter administratortillatelse, og noter tenant-ID-en og Application (Client) ID-en.
3. Sertifikat i stedet for Client Secret
En app-only-innlogging fungerer med Client Secret eller sertifikat. For planlagte oppgaver er et sertifikat det beste valget: Den private nøkkelen forblir i sertifikatlageret, og skriptet inneholder ikke noe passord. Opprett sertifikatet på serveren som skal kjøre skriptet, og eksporter bare den offentlige delen:
$cert = New-SelfSignedCertificate -Subject "CN=eCall-Graph" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-KeyExportPolicy NonExportable -KeySpec Signature `
-KeyLength 2048 -NotAfter (Get-Date).AddYears(2)
Export-Certificate -Cert $cert -FilePath .\eCall-Graph.cer
$cert.Thumbprint # -> im Skript als Thumbprint verwenden
Last opp den eksporterte .cer-filen i appregistreringen under Certificates & secrets. Kontoen til Scheduled Task trenger lesetilgang til den private nøkkelen (certlm.msc → sertifikat → All Tasks → Manage Private Keys).
4. Begrens tilgang til enkelte postbokser
Application Permissions gjelder først for alle postbokser i tenanten. Begrens derfor appen med en Application Access Policy til en e-postaktivert sikkerhetsgruppe. Dette trinnet utføres én gang i Exchange Online PowerShell:
New-ApplicationAccessPolicy -AppId "<App-ID>" `
-PolicyScopeGroupId "graph-mailboxes@example.com" `
-AccessRight RestrictAccess `
-Description "eCall Graph: nur Log-Postfach"
# Kontroller at policyen gjelder
Test-ApplicationAccessPolicy -AppId "<App-ID>" -Identity "ecall-logs@example.com"
5. Opprett forbindelse
Innloggingen bruker tenant-ID, app-ID og sertifikatets thumbprint, helt uten brukerinteraksjon:
$TenantId = "00000000-0000-0000-0000-000000000000"
$ClientId = "00000000-0000-0000-0000-000000000000"
$Thumbprint = "0000000000000000000000000000000000000000"
$Mailbox = "ecall-logs@example.com"
Import-Module Microsoft.Graph.Authentication, Microsoft.Graph.Mail, Microsoft.Graph.Users.Actions
Connect-MgGraph -TenantId $TenantId -ClientId $ClientId `
-CertificateThumbprint $Thumbprint -NoWelcome
6. Les meldinger og last ned ZIP-vedlegg
Skriptet kan nå gå gjennom innboksen, lagre og pakke ut ZIP-vedlegg samt flytte behandlede meldinger til «Slettede elementer». Nedlastingen skjer via endepunktet /$value og Invoke-MgGraphRequest -OutputFilePath. Dermed havner råinnholdet direkte i en fil uten å holde et stort vedlegg fullt ut i minnet:
Add-Type -AssemblyName System.IO.Compression.FileSystem
$Zielordner = "D:\Import\{0:yyyyMMdd_HHmmss}" -f (Get-Date)
$messages = Get-MgUserMessage -UserId $Mailbox -Top 100 `
-Property id, subject, hasAttachments
foreach ($msg in $messages) {
$ordner = Join-Path $Zielordner $msg.Id
New-Item -Path $ordner -ItemType Directory -Force | Out-Null
$anhaenge = Get-MgUserMessageAttachment -UserId $Mailbox -MessageId $msg.Id |
Where-Object {
$_.AdditionalProperties['@odata.type'] -eq '#microsoft.graph.fileAttachment' -and
$_.Name -like '*.zip'
}
foreach ($att in $anhaenge) {
$zip = Join-Path $ordner $att.Name
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/messages/$($msg.Id)/attachments/$($att.Id)/`$value"
Invoke-MgGraphRequest -Method GET -Uri $uri -OutputFilePath $zip
[System.IO.Compression.ZipFile]::ExtractToDirectory($zip, $ordner)
}
# flytt behandlet e-post til «Slettede elementer»
Move-MgUserMessage -UserId $Mailbox -MessageId $msg.Id -DestinationId "deleteditems" | Out-Null
}
Ved mer enn 100 e-poster, bruk Get-MgUserMessage -All eller paging; for en månedlig kjøring er én batch som regel nok.
7. Send rapport-e-post via Graph
Også Send-MailMessage er utdatert. Via den samme appregistreringen (rettighet Mail.Send) sendes e-posten direkte via Graph, her med en fil som base64-kodet vedlegg:
$pfad = "D:\Reports\report.csv"
$body = @{
message = @{
subject = "eCall Report"
body = @{ contentType = "HTML"; content = "<b>Lauf erfolgreich</b>" }
toRecipients = @(@{ emailAddress = @{ address = "empfaenger@example.com" } })
attachments = @(@{
"@odata.type" = "#microsoft.graph.fileAttachment"
name = Split-Path $pfad -Leaf
contentBytes = [Convert]::ToBase64String([IO.File]::ReadAllBytes($pfad))
})
}
saveToSentItems = $true
}
Send-MgUserMail -UserId "reporting@example.com" -BodyParameter $body
8. Kjør uten tilsyn
Som en planlagt oppgave kjører skriptet uten innlogging, fordi sertifikatet ligger i kontoens store:
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "D:\Scripts\graph-import.ps1"'
$trigger = New-ScheduledTaskTrigger -Daily -At 06:00
Register-ScheduledTask -TaskName "eCall-Graph-Import" -Action $action -Trigger $trigger `
-User "DOMAIN\svc-ecall" -Password (Read-Host "Passwort")
Det komplette eksempelet med logging og feilbehandling finnes på GitHub: pfstr/eCall-Log-Analyzer.
Kommentarer
Kommentarene lastes inn fra GitHub / Giscus.