• Ned. svi 31st, 2026

Oblak Znanja

informatička edukacija i vijesti

Sve što trebate znati o Exchange Online Admin API-ju (ili kako pokrenuti cmdlete bez PowerShell-a) – 2. dio

ByTomšić Damjan

tra 3, 2026

Ovo je nastavak teme o kojoj smo govorili u našem prethodni članaksvakako prvo prijeđite preko toga.

REST cmdleti i dodatne metode

Ako ste dogurali ovako daleko, znate kako pokrenuti bilo koji Exchange Online cmdlet bez potrebe za korištenjem samog modula. Ali Exchange Online Admin API ima više od toga InvokeCommand metoda, kao što znamo iz prisutnosti REST cmdleta. Zapravo, svaki REST cmdlet ima svoju krajnju točku ispod https://outlook.office365.com/adminapi. Na primjer:

$uri = "https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com/Mailbox('user@domain.com')"
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader
($res.Content | ConvertFrom-Json)

odgovara Get-EXOMailbox cmdlet, i tako dalje. Ali to nije sve! Dostupno nam je i mnoštvo drugih metoda koje možemo iskoristiti, a sve su ugniježđene pod istom “roditeljskom” krajnjom točkom. Iako ne postoji javno dokumentiran popis krajnjih točaka, možete ga dobiti jednostavnim pokretanjem GET upita prema https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com:

$uri = "https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com"
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader
$ApiEndpoints = ($res.Content | ConvertFrom-Json).value

Trenutno je vraćen ukupno 51 unos, zajedno sa svojim URL-ovima, kao što je prikazano u nastavku:

$ApiEndpoints | sort Name 

name                                  kind      url
----                                  ----      ---
ActiveSyncDeviceAccessRule            EntitySet ActiveSyncDeviceAccessRule
ActiveSyncDeviceClass                 EntitySet ActiveSyncDeviceClass
ActiveSyncOrganizationSettings        EntitySet ActiveSyncOrganizationSettings
AddressBookPolicy                     EntitySet AddressBookPolicy
AntiPhishPolicyPresentation           EntitySet AntiPhishPolicyPresentation
AntiPhishRule                         EntitySet AntiPhishRule
AtpPolicyForO365Presentation          EntitySet AtpPolicyForO365Presentation
BasicInfo                             EntitySet BasicInfo
CalendarProcessing                    EntitySet CalendarProcessing
CasMailbox                            EntitySet CasMailbox
CmdletInfo                            EntitySet CmdletInfo
ConfigAnalyzerPolicyRecommendation    EntitySet ConfigAnalyzerPolicyRecommendation
DirectMobileDevice                    EntitySet DirectMobileDevice
Divergence                            EntitySet Divergence
DynamicDistributionGroup              EntitySet DynamicDistributionGroup
EligibleDistributionGroup             EntitySet EligibleDistributionGroup
ExchangeManagementScope               EntitySet ExchangeManagementScope
ExchangeRoleGroup                     EntitySet ExchangeRoleGroup
ExchangeRoleGroupMember               EntitySet ExchangeRoleGroupMember
GraphConnectorGroup                   EntitySet GraphConnectorGroup
GraphConnectorGroupMember             EntitySet GraphConnectorGroupMember
HistoricalSearch                      EntitySet HistoricalSearch
HostedContentFilterPolicyPresentation EntitySet HostedContentFilterPolicyPresentation
HostedContentFilterRule               EntitySet HostedContentFilterRule
InboundConnector                      EntitySet InboundConnector
Mailbox                               EntitySet Mailbox
MailboxAutoReplyConfiguration         EntitySet MailboxAutoReplyConfiguration
MailboxPlan                           EntitySet MailboxPlan
MailboxRecoverableItem                EntitySet MailboxRecoverableItem
MalwareFilterPolicy                   EntitySet MalwareFilterPolicy
MalwareFilterRule                     EntitySet MalwareFilterRule
MobileDeviceMailboxPolicy             EntitySet MobileDeviceMailboxPolicy
OutboundConnector                     EntitySet OutboundConnector
Place                                 EntitySet Place
Recipient                             EntitySet Recipient
ReportSchedule                        EntitySet ReportSchedule
RetentionPolicy                       EntitySet RetentionPolicy
RoleAssignmentPolicy                  EntitySet RoleAssignmentPolicy
RoleAssignments                       EntitySet RoleAssignments
RoleDefinitions                       EntitySet RoleDefinitions
SafeAttachmentPolicy                  EntitySet SafeAttachmentPolicy
SafeAttachmentRule                    EntitySet SafeAttachmentRule
SafeLinksPolicyPresentation           EntitySet SafeLinksPolicyPresentation
SafeLinksRule                         EntitySet SafeLinksRule
SecurityPrincipal                     EntitySet SecurityPrincipal
SharingPolicy                         EntitySet SharingPolicy
UnifiedGroup                          EntitySet UnifiedGroup
UnifiedRbacManagementScope            EntitySet UnifiedRbacManagementScope
UnifiedRbacRoleAssignment             EntitySet UnifiedRbacRoleAssignment
UnifiedRbacRoleDefinition             EntitySet UnifiedRbacRoleDefinition
User                                  EntitySet User

Ako pažljivo proučite gornji popis, primijetit ćete da nedostaje nekoliko metoda koje se preslikavaju na neke od postojećih REST cmdleta. Jedan takav primjer je Get-EXOMailboxPermission cmdlet. Dakle, što se događa? Pa, slično Graph API-ju, imamo svojstva navigacije koja nisu odmah vidljiva iz gore navedenog. Međutim, možemo dohvatiti dokument metapodataka da ih izložimo, kao i neke dodatne metode i entitete.

#Fetch the metadata document
$uri = 'https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com/$metadata'
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader
[xml]$metadata = $res.Content #cast to XML

#Explore the metadata
($metadata.Edmx.DataServices.Schema | ? $_.Namespace -eq "Exchange")
Namespace       : Exchange
xmlns           : http://docs.oasis-open.org/odata/ns/edm
ComplexType     : ComplexEntry, ByteArrayType, StringFieldDeltaUpdateData, MailboxRecoverableItemsQuery…
EntityType      : BasicInfo, MailboxPermission, MailboxFolderPermission, MailboxFolder…
EnumType        : ElcFolderType, OofState, ExternalAudience, RecipientAccessRight…
Function        : GetMobileDeviceStatistics, GetMailboxStatistics, GetMailboxStatisticsV2, GetMailboxFolderStatistics…
Action          : UpdateMailboxArchive, GetRecoverableItems, RestoreRecoverableItems, ValidateOutboundConnector…
EntityContainer : EntityContainer

Imajte na umu da i dalje morate biti autentificirani za upit metapodataka, zahtjev neće uspjeti ako ne proslijedite valjani pristupni token! Skup od EntityType objekte s mape metapodataka na gornji popis krajnjih točaka, s njihovim ukupnim brojem 57. Ovaj broj uključuje skup navigacijskih svojstava na koja smo gore spomenuli, a evo kako ih dobiti:

($metadata.Edmx.DataServices.Schema | ? $_.Namespace -eq "Exchange").EntityType | ? $_.Name -eq "Mailbox" | select -ExpandProperty NavigationProperty

Name                         Type                                        ContainsTarget
----                         ----                                        --------------
MailboxPermission            Collection(Exchange.MailboxPermission)      true
MailboxFolder                Collection(Exchange.MailboxFolder)          true
MobileDevice                 Collection(Exchange.MobileDevice)           true
MailboxRecoverableItem       Collection(Exchange.MailboxRecoverableItem) true
MailboxRegionalConfiguration Exchange.MailboxRegionalConfiguration       true

Osim na EntityType set, imamo i set od Akcijski i Funkcija za rad, oba otkrivaju neke metode koje nisu dostupne u cmdlet obliku. Na primjer, imamo sljedeći skup radnji:

($metadata.Edmx.DataServices.Schema | ? $_.Namespace -eq "Exchange").Action

Name                             IsBound Parameter
----                             ------- ---------
UpdateMailboxArchive             true    mailbox, archive
GetRecoverableItems              true    bindingParameter, value
RestoreRecoverableItems          true    bindingParameter, value
ValidateOutboundConnector        true    outboundConnector, recipients
DeleteGroup                      true    Parameter
DeleteGroupMember                true    graphConnectorGroup, graphConnectorGroupMemberId
UpgradeDistributionGroup         true    EligibleDistributionGroup, DlIdentities
ClearMobileDevice                true    mobileId, cancel
SearchMessageTrace                       Parameter
SearchMessageTraceDetail                 Parameter
GetMailDetailTransportRuleReport         Parameter
GetMailTrafficPolicyReport               Parameter
GetMailDetailDlpPolicyReport             Parameter
RbacQuery                                Parameter
Initialize
InitializeLiteFRC
InvokeCommand                            Parameter

kao i sljedeći skup funkcija:

($metadata.Edmx.DataServices.Schema | ? $_.Namespace -eq "Exchange").Function

Name                                IsBound Parameter                                     ReturnType
----                                ------- ---------                                     ----------
GetMobileDeviceStatistics           true    Parameter                                     ReturnType
GetMailboxStatistics                true    Parameter                                     ReturnType
GetMailboxStatisticsV2              true    bindingParameter, mailboxGuid, databaseGuid ReturnType
GetMailboxFolderStatistics          true    mailboxfolder, folderscope                  ReturnType
BySmtpAddress                       true    CasMailbox, SmtpAddress                     ReturnType
BySmtpAddress                       true    Recipient, SmtpAddress                      ReturnType
GetRecipientPermissionByFilters     true    Recipient, identity, trustee, accessRights  ReturnType
GetMobileDeviceStatisticsByIdentity         Parameter                                     ReturnType

Nažalost, dokument s metapodacima ne otkriva mnogo detalja o tome kako točno možemo koristiti bilo što od navedenog. Ali ako ste voljni potrošiti neko vrijeme na to, neke od ovih možete pokrenuti. Na primjer, GetMailDetailTransportRuleReport je krajnja točka za korištenje ako želite dohvatiti (detaljno) izvješće o pravilu prijenosa Exchangea. Ono što nam metapodaci ne govore je kako konstruirati sam upit, ali ja sam vas pokrio! Evo radnog primjera dohvaćanja izvješća o pravilu prijenosa Exchangea s većinom parametara koje ono prihvaća:

#Prepare the request body. Must include QueryTable node
$body = @
    QueryTable = @
        Direction = @("Outbound","Inbound")
        Action = @("SetAuditSeverityHigh","SetAuditSeverityMedium","SetAuditSeverityLow")
        EventType = @("TransportRuleHits")
        StartDate = "2025-11-12T00:00:00.000Z"
        EndDate = "2025-11-18T23:59:59.000Z"
        Page = 1
        PageSize = 30
    


#Fetch the report
$uri = "https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com/GetMailDetailTransportRuleReport"
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader -Method Post -Body ($body | ConvertTo-Json -Depth 5)
($res.Content | ConvertFrom-Json).value

Izlaz bi sada trebao uključivati ​​relevantne pojedinosti iz izvješća Exchange Transport Rule, koje je dostupno unutar EAC-a.

Nekoliko PATCH primjera

Ako ste uspjeli do sada, vrijeme je za veliko otkriće! Iako nam je Microsoft govorio da planira podržati samo REST cmdlete samo za čitanje, temeljne metode podržavaju operacije PATCH, POST i DELETE. Vjerojatno bi trebalo dvaput razmisliti prije pokušaja operacije nečitanja protiv nepodržane i nedokumentirane krajnje točke, ali takve su doista moguće. Na primjer, možemo upotrijebiti kod u nastavku za ažuriranje prilagođenog atributa određenog korisnika poštanskog sandučića:

#Prepare the request body
$body = @
    CustomAttribute1="TestValue"
 | ConvertTo-Json -Depth 5

#PATCH the mailbox object
$uri = "https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com/Mailbox('user@domain.com')"
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader -Method PATCH -Body $body

Uspješno izvršenje gornjeg zahtjeva rezultirat će an 204 Bez sadržaja odgovor. Možete upotrijebiti bilo koju od dostupnih metoda da potvrdite da je promjena doista izvršena! Podrška za PATCH operacije nije ograničena ni na krajnje točke koje odgovaraju REST cmdletima. Neke druge gore navedene metode također podržavaju PATCH-ing. Na primjer, možemo iskoristiti Obrada kalendara metoda za promjenu načina obrade zahtjeva za rezervaciju za dani poštanski sandučić sobe:

#Prepare the request body
$body = @
    AllBookInPolicy=$false
 | ConvertTo-Json -Depth 5

#PATCH the mailbox object
$uri = "https://outlook.office365.com/adminapi/beta/tenant.onmicrosoft.com/CalendarProcessing('room@domain.com')"
$res = Invoke-WebRequest -Uri $uri -Headers $authHeader -Method Patch -Body $body
($res.Content | ConvertFrom-Json)

SCC krajnje točke

Kao što vjerojatno znate, PowerShell cmdleti za sigurnost i usklađenost također koriste isto ponašanje proxyja, pa se većina onoga što smo ispitali iznad odnosi i na njih. Zahtjevi za dopuštenje na strani API-ja također su isti, još uvijek trebate Razmjena.Upravljanje ili Exchange.ManageAsApp opsege, koje morate nadopuniti potrebnim ulogama administratora za Purview za operacije koje planirate izvršiti. Međutim, postoji nekoliko razlika u procesu.

Prvo, resurs (publika) za koji trebate dobiti pristupni token je drugačiji, kao što je predstavljeno sljedećim URI-jem: https://ps.compliance.protection.outlook.com. Nakon što imate valjani pristupni token za spomenuti resurs, možete pripremiti zaglavlje za provjeru autentičnosti i korisni teret tijela baš kao što smo gore opisali. URL zahtjeva mora se u skladu s tim prilagoditi tako da također odgovara URI-ju. Evo cjelovitog primjera:

#Get an access token
$app = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx").WithRedirectUri("http://localhost").Build()

$Scopes = New-Object System.Collections.Generic.List[string]
$Scope = "https://ps.compliance.protection.outlook.com/.default"
$Scopes.Add($Scope)

$token = $app.AcquireTokenInteractive($Scopes).ExecuteAsync().Result

#Set the auth header and routing hint
$authHeader = @
    'Content-Type'='application/json'
    'Authorization'="Bearer $($token.AccessToken)"
    'X-ResponseFormat'= "json"
    'X-AnchorMailbox' = "UPN:user@domain.com"


#Cmdlet payload
$body = @
    CmdletInput = @
        CmdletName="Get-RetentionCompliancePolicy"
    
 | ConvertTo-Json -Depth 5

#Sample Request
$uri = "https://eur02b.ps.compliance.protection.outlook.com/adminapi/beta/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/InvokeCommand"
$res = Invoke-WebRequest -Method POST -Uri $uri -Headers $authHeader -Body $body
($res.Content | ConvertFrom-Json).Value

Možda ste primijetili da koristimo URI specifičan za regiju u gornjem zahtjevu, tj. “eur02b”, ali globalni također radi.

Završne riječi i sažetak

Jedna stvar koju do sada nismo spomenuli je da možete koristiti naizmjenično https://outlook.office.com/adminapi (bez sufiksa “365”) umjesto https://outlook.office365.com/adminapi u svim primjerima koje smo obradili. Slijedimo notaciju koju koriste ugrađeni cmdleti za naše primjere, ali oba bi trebala raditi jednako dobro.

Na sličan način, mogli ste primijetiti da svi primjeri iskorištavaju /beta krajnja točka. To je opet zbog ponašanja ugrađenih cmdlet-a i ne bi trebalo činiti razliku jer ionako ne postoji službeno podržana verzija API-ja. postoji /v1.0 krajnju točku također, s nekim primjetnim razlikama u skupu metoda koje su tamo izložene. Držite se /beta krajnju točku za “puno” iskustvo. S druge strane, nedavno najavljeni dodaci na Exchange Admin API nalaze se pod a /v2.0 verzija krajnje točke. Ovo međutim nema nikakve veze s bilo čim o čemu smo ovdje raspravljali. TL;DR – najbolje koristiti /beta krajnju točku i zaboravite na ostalo.

Još jedno pitanje koje se redovito pojavljuje je ograničavanje dopuštenja, posebno u neinteraktivnom scenariju. Sada kada je RBAC za aplikacije Dostupna je značajka, s principalima usluga možete postupati kao s bilo kojim drugim sigurnosnim principalima u Exchangeu i prema potrebi upravljati dodjelama uloga za njih. Jedina stvar koju trebate učiniti je provjeriti je li objekt glavnog servisa “poznat” Exchangeu, što je nažalost još uvijek ručni zadatak (tj. morate koristiti New-ServicePrincipal osigurati ga). Vrijedno je ponoviti da opseg API-ja ne dopušta nikakav pristup sam po sebi, za to je odgovoran Exchangeov RBAC.

Ukratko, istražili smo skrivenu dubinu iza Exchange Online Admin API-ja. Što se tiče “službeno podržanog” fronta, spomenuti API pokreće skup cmdleta temeljenih na REST-u i igra ulogu proxy usluge za sve klasične cmdlete kao sredstvo za zaobilaženje ovisnosti o WinRM-u. Višestruke druge metode dostupne su pod krajnjom točkom, omogućujući sve vrste korisnih operacija, na nepodržan i nedokumentiran način. Visoki rizik koji dolazi s korištenjem takvih metoda može se nadoknaditi visokom nagradom mogućnosti izvođenja operacija putem RESTful sučelja, bez potrebe za korištenjem PowerShell-a.

Nažalost, do danas Microsoft nije priopćio nikakve planove da sve to premjesti u Graph API ili ih javno izloži na podržani način. Iako možemo napraviti neke paralele s Graphom, na primjer podrška za paginaciju ili $odaberimnoga poboljšanja kvalitete života na koja smo navikli s Graphom nisu dostupna i vjerojatno nikada neće biti. Ipak, postoji mnogo scenarija u kojima postojeće krajnje točke i metode administratorskog API-ja mogu biti korisne, pa se nadamo da će vam ovaj vodič pomoći da počnete s njima.

Web izvor

By Tomšić Damjan

Pozdrav, ja sam Damjan Tomšić, osnivatelj i urednik informatičko edukativnog bloga Oblak Znanja. Za Vas ću se potruditi da dobijete edukativne članke, savjete i recenzije vezane uz osnovno i napredno korištenje računala i interneta. Kontak: Google+, Gmail.