├── Connect-Graph.ps1 ├── Connect_Graph_Password_Grant.ps1 ├── Grant-Types.ps1 ├── Graph_Get_All_CompanyAdmins.ps1 ├── Graph_Get_All_Devices.ps1 ├── Graph_Get_All_Groups.ps1 ├── Graph_Get_All_Groups_Paging.ps1 ├── Graph_Get_All_SharePoint_Sites.ps1 ├── Graph_Get_All_Users.ps1 ├── Graph_Get_All_Users_Sort_DisplayName.ps1 ├── Graph_Get_Calendar_Events_Top5.ps1 ├── Graph_Get_Intune_CompliancePolicies.ps1 ├── Graph_Get_OneDrive_Items.ps1 ├── Graph_Get_Recent_Emails.ps1 ├── Graph_Get_Recent_Security_Alerts.ps1 ├── Graph_Get_Teams_Channel_Messages_Top3.ps1 ├── Graph_Get_Tenant_Domains.ps1 ├── Graph_Get_Tenant_SkuInfo.ps1 ├── Graph_Post_SharePoint_List.ps1 ├── Graph_Post_Teams_Message.ps1 ├── Graph_Upload_OneDrive_File.ps1 ├── Graph_Upload_OneDrive_File2.ps1 ├── MSGraph API.pdf ├── MSGraph API.pptx ├── README.md └── Report.ps1 /Connect-Graph.ps1: -------------------------------------------------------------------------------- 1 | function Connect-Graph 2 | { 3 | $clientId = "" 4 | $redirectUrl = [System.Uri]"urn:ietf:wg:oauth:2.0:oob" # This is the standard Redirect URI for Windows Azure PowerShell 5 | $tenant = "DOMAIN.onmicrosoft.com" 6 | $resource = "https://graph.microsoft.com/"; 7 | $serviceRootURL = "https://graph.microsoft.com//$tenant" 8 | $authUrl = "https://login.microsoftonline.com/$tenant"; 9 | 10 | $postParams = @{ resource = "$resource"; client_id = "$clientId" } 11 | $response = Invoke-RestMethod -Method POST -Uri "$authurl/oauth2/devicecode" -Body $postParams 12 | Write-Host $response.message 13 | #I got tired of manually copying the code, so I did string manipulation and stored the code in a variable and added to the clipboard automatically 14 | $code = ($response.message -split "code " | Select-Object -Last 1) -split " to authenticate." 15 | Set-Clipboard -Value $code 16 | #Start-Process "https://microsoft.com/devicelogin" 17 | Add-Type -AssemblyName System.Windows.Forms 18 | 19 | $form = New-Object -TypeName System.Windows.Forms.Form -Property @{ Width = 440; Height = 640 } 20 | $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{ Width = 440; Height = 600; Url = "https://www.microsoft.com/devicelogin" } 21 | 22 | $web.Add_DocumentCompleted($DocComp) 23 | $web.DocumentText 24 | 25 | $form.Controls.Add($web) 26 | $form.Add_Shown({ $form.Activate() }) 27 | $web.ScriptErrorsSuppressed = $true 28 | 29 | $form.AutoScaleMode = 'Dpi' 30 | $form.text = "Graph API Authentication" 31 | $form.ShowIcon = $False 32 | $form.AutoSizeMode = 'GrowAndShrink' 33 | $Form.StartPosition = 'CenterScreen' 34 | 35 | 36 | $form.ShowDialog() | Out-Null 37 | 38 | 39 | $tokenParams = @{ grant_type = "device_code"; resource = "$resource"; client_id = "$clientId"; code = "$($response.device_code)" } 40 | 41 | $global:tokenResponse = $null 42 | 43 | try 44 | { 45 | $global:tokenResponse = Invoke-RestMethod -Method POST -Uri "$authurl/oauth2/token" -Body $tokenParams 46 | } 47 | catch [System.Net.WebException] 48 | { 49 | if ($_.Exception.Response -eq $null) 50 | { 51 | throw 52 | } 53 | 54 | $result = $_.Exception.Response.GetResponseStream() 55 | $reader = New-Object System.IO.StreamReader($result) 56 | $reader.BaseStream.Position = 0 57 | $errBody = ConvertFrom-Json $reader.ReadToEnd(); 58 | 59 | if ($errBody.Error -ne "authorization_pending") 60 | { 61 | throw 62 | } 63 | } 64 | 65 | If ($null -eq $global:tokenResponse) 66 | { 67 | Write-Warning "Not Connected" 68 | } 69 | Else 70 | { 71 | Write-Host -ForegroundColor Green "Connected" 72 | } 73 | } 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Connect_Graph_Password_Grant.ps1: -------------------------------------------------------------------------------- 1 | Function Get-AuthorizationHeader { 2 | <# 3 | .SYNOPSIS 4 | Gets bearer access token and builds REST method authorization header. 5 | .DESCRIPTION 6 | Uses Office 365 Application ID and Application Secret to generate an authentication header for Microsoft Graph. 7 | .PARAMETER AppId 8 | Microsoft Azure Application ID. 9 | .PARAMETER AppSecret 10 | Microsoft Azure Application secret. 11 | #> 12 | Param ( 13 | [parameter(Mandatory = $true)] 14 | [string]$AppId, 15 | 16 | [parameter(Mandatory = $true)] 17 | [string]$AppSecret, 18 | 19 | [parameter(Mandatory = $true)] 20 | [pscredential]$Credential 21 | ) 22 | 23 | $Uri = "https://login.microsoftonline.com/tenantname/oauth2/v2.0/token" 24 | $Body = @{ 25 | grant_type = 'password' 26 | username = $Credential.UserName 27 | password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)) 28 | client_id = $AppId 29 | client_secret = $AppSecret 30 | scope = 'https://graph.microsoft.com/.default' 31 | redirect_uri = 'https://localhost/' 32 | } 33 | $AuthResult = Invoke-RestMethod -Method Post -Uri $Uri -Body $Body 34 | 35 | #Function output 36 | @{ 37 | 'Authorization' = 'Bearer ' + $AuthResult.access_token 38 | } 39 | } -------------------------------------------------------------------------------- /Grant-Types.ps1: -------------------------------------------------------------------------------- 1 | # Docs for scopes, permissions and consent --> http://bit.ly/2RAGiv7 2 | 3 | # Static Variables 4 | $Client_ID = "" # Azure AD App ID 5 | $Client_Secret = "" # Azure AD App Secret 6 | $tenantID = "" # Tenant ID, readable or gibberish format :) 7 | $Username = "" 8 | $Password = "" 9 | 10 | # My computer's Powershell is throwing some weird cert error so I'm doing this to bypass. YOu can ignore this. 11 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 12 | 13 | <# Client_Credentials Grant type 14 | http://bit.ly/2K0rswY 15 | 16 | Helicopter View: 17 | 1. You send needed information to Token request Endpoint 18 | 2. You get token 19 | 3. You talk to Graph API with your token 20 | 21 | With right permissions and admin grant or user authorization, this is the flow for CLient_Credentials: 22 | 1. YOu send the $reqTokenBody to token request endpoint. What's in the token body are the the basic requirements in Client_Credentials header. 23 | 2. YOu get the access token 24 | 3. You save the access the token in a variable $ReqHeader to proper format it (Bearer pre-fix and "Authorization" value name) 25 | 4. Use $reqheader as the Header for your request to Graph API endpoint 26 | #> 27 | 28 | $ReqTokenBody = @{ 29 | Grant_Type = "client_credentials" 30 | Scope = "https://graph.microsoft.com/.default" 31 | client_Id = $client_ID 32 | Client_Secret = $client_Secret 33 | } 34 | 35 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 36 | 37 | $ReqHeader = @{ 38 | Authorization = "Bearer $($TokReqRes.access_token)" 39 | } 40 | 41 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 42 | 43 | <# Auth Code grant 44 | http://bit.ly/2K4vmVG 45 | 46 | Helicopter View: 47 | 1. You access a URL with necessary parameters 48 | 2. You authenticate in the browser 49 | 3. You get a code upon successfull authentication 50 | 4. You Send the code to token request endpoint with other needed information 51 | 5. You get token 52 | 6. you talk to Graph API with your token 53 | 54 | With right permissions and admin grant or user authorization, this is the flow for Authorization_Coe: 55 | 1. To acquire an Authorization code: 56 | 1.1 using SDKs or by simply going to this URL in a browser (new line for legibility): 57 | https://login.microsoftonline.com/{tenantID}/oauth2 58 | /v2.0/authorize?client_id={clientID} 59 | &redirect_uri={RedirectURI}&scope={Scope} 60 | &response_type=code 61 | 1.2 Upon successul authentication, you will get code in the URL. Like this: https://monosnap.com/file/p8GwA4CciZqFXzICUgQeCEq7J94sZN 62 | 1.3 Extract that code and save it to Variable 63 | 2. With all those other needed information, wrap them in variable to be the header for token request. IN my case its the $reqTokenBody 64 | 3. YOu send the $reqTokenBody to token request endpoint. What's in the token body are the the basic requirements in Authorization_Code header. 65 | 4. YOu get the access token 66 | 5. You save the access the token in a variable $ReqHeader to proper format it (Bearer pre-fix and "AUthorization" value name) 67 | 6. Use $reqheader as the Header for your request to Graph API endpoint 68 | 69 | #> 70 | 71 | $AuthCode = "OAQABAAIAAADCoMpjJXrxTq9VG9te-7FXBF_jU73IqFoHuAZlOcmbg_BV7t8q40qVmz_Ft9j3VpLYQKk_0HOjl63HL1ygPARHwu0QgHmzur-8jN-SenbaHjuoN5kVgfcHuRDILtnUXdBxHIq4UaeiDtap9I1DeH3e1MPZQH8K_V1aYFgHjuOmkTiuCOCTmW6dw5CqEZ81ghgM_-vC37zTPM5S7nEOfSc7lXa9FcGG7toKeB007G5p2Liz4_Cmyhahy8RiyNSNkP8cjmz2b2GYr6UKepBGw5HAwD1HAdDxE_gl0iFPMcFP3czI37Zt6oNve6Y7bjHNIpcr2P_fTY2OTFynMsCrfKh-Mp-ptZtsDG2a0ImZXYqnFHSyQFTDcZw29-Fa5NFq2FbnZgmVA2mhxVrlT23ntLg6zCLwQv3VKbgcrPhJSiK-jwooki3IjgJj78pRkIsscTg_q7rhrNIz009MPRdU02n1OQ6RBthalxkJNQgGZq03eEN2g--RKeBQb1R0F81nAYeVZtSnXm0TaUXngZEbyKUpsdhb7HZ4-PDHNVfqcJ36wcgHZs2pVytzr0oTKJxPNLyJfOfZzNiNnv-Srh4I-HeVjrD-tuunJWv8XU2zFSRmVYuDGCpnJYLg-n1m21g_PslaAnEi01YSYPiXEgdvtahAtsNX6HBxw_k5TqX37w5eceJR5LXFh4xapC2j8FzrlU5SVps-itAgmzomIzpAfsA_IAA" 72 | 73 | $ReqTokenBody = @{ 74 | Grant_Type = "Authorization_Code" 75 | Scope = "https://graph.microsoft.com/Reports.Read.All" 76 | redirect_uri = "http://localhost/" 77 | client_Id = $client_ID 78 | Client_Secret = $client_Secret 79 | code = $AuthCode 80 | } 81 | 82 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 83 | 84 | $ReqHeader = @{ 85 | Authorization = "Bearer $($TokReqRes.access_token)" 86 | } 87 | 88 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 89 | 90 | <# Password Grant 91 | # http://bit.ly/2K4TWFP 92 | 93 | A little similar to client_Credentials but with username and password in the header of the token request. 94 | 95 | Helicopter View: 96 | 1. You send needed information to token request Endpoint (with username and password) 97 | 2. You get token 98 | 3. you talk to Graph API with your token 99 | 100 | With right permissions and admin grant or user authorization, this is the flow for CLient_Credentials: 101 | 1. You send the $reqTokenBody to token request endpoint. What's in the token body are the the basic requirements in Client_Credentials header. 102 | 2. You get the access token 103 | 3. You save the access the token in a variable $ReqHeader to proper format it (Bearer pre-fix and "AUthorization" value name) 104 | 4. Use $reqheader as the Header for your request to Graph API endpoint 105 | 106 | #> 107 | $ReqTokenBody = @{ 108 | Grant_Type = "Password" 109 | client_Id = $client_ID 110 | Client_Secret = $client_Secret 111 | Username = $Username 112 | Password = $Password 113 | Scope = "https://graph.microsoft.com/Reports.Read.All" 114 | } 115 | 116 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 117 | 118 | $ReqHeader = @{ 119 | Authorization = "Bearer $($TokReqRes.access_token)" 120 | } 121 | 122 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 123 | 124 | <# Device Code 125 | http://bit.ly/2Xs06X2 126 | 127 | Helicopter View: 128 | 1. You send needed information to device code endpoint 129 | 2. You get an authentication code for authentication and a device code for token request 130 | 3. you get to a URL (Provided in the message property of the result) on any device and authenticate using 131 | 4. You send needed information to Token request endpoint and you get token if you have authenticated succesfully in step 3. 132 | 5. you talk to Graph API with your token 133 | 134 | With right permissions and admin grant or user authorization, this is the flow for Device_code: 135 | 1. Send $DevReqBody to deviceCode endpoint to request 136 | 2. You will receive a device code, an authentication code, and a URL in which you'll be able to authenticate. 137 | 3. You browse to the URL and provide the authentication code and authenticate. 138 | 4. You grab the Device code from Step 2 and along with the information in $reqTokenBody, send it to Token Request endpoint. 139 | 5. You get the access token 140 | 6. You save the access the token in a variable $ReqHeader to proper format it (Bearer pre-fix and "AUthorization" value name) 141 | 7. Use $reqheader as the Header for your request to Graph API endpoint 142 | #> 143 | 144 | # Request device code for authentication 145 | $DevReqBody = @{ 146 | Client_ID = $Client_ID 147 | Scope = "user.read offline_access Reports.Read.All" 148 | } 149 | $DevReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/devicecode" -Body $DevReqBody 150 | 151 | # Token Request 152 | $ReqTokenBody = @{ 153 | Grant_Type = "Device_Code" 154 | client_Id = $client_ID 155 | Code = $DevReqRes.device_code 156 | } 157 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 158 | 159 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 160 | 161 | <# Refresh_Token Grant 162 | http://bit.ly/2K4vmVG 163 | http://bit.ly/2RzwYYx 164 | 165 | If you add "offline_access" (e.g.g https://graph.microsoft.com/reports.read.all offline_access)in to your scope when requesting a token, 166 | it will add refresh token to your result. 167 | You can use this refresh token to request for another access token. 168 | 169 | 1. request a token and add "offline_acceess" to scope 170 | 2. use the refresh token to request another access token. The logic in your app may include a way to do math in terms of the expiration of the access token. 171 | Know that fresh token expires in xx days (I'm not sure TBH but it says here 90 days http://bit.ly/2REqCHs) - access tokens expire in 1 hour when it was generated. 172 | 3. The access token acquired from the refresh token can be used the same fashion as the rest of the grant types 173 | #> 174 | $ReqTokenBody = @{ 175 | Grant_Type = "Refresh_Token" 176 | client_Id = $client_ID 177 | Client_Secret = $client_Secret 178 | Refresh_TOken = $TokReqRes.refresh_token 179 | } 180 | 181 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 182 | 183 | $ReqHeader = @{ 184 | Authorization = "Bearer $($TokReqRes.access_token)" 185 | } 186 | 187 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 188 | 189 | ## End of Req body samples 190 | 191 | # Requesting a token header and formating 192 | $TokReqRes = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody 193 | 194 | $ReqHeader = @{ 195 | Authorization = "Bearer $($TokReqRes.access_token)" 196 | } 197 | 198 | # End 199 | 200 | # Download from OneDrive 201 | #http://bit.ly/2Ry4OwY 202 | $Params = @{ 203 | URI = "https://graph.microsoft.com/v1.0/users/$username/drive/root:/tasks:/children" 204 | Headers = $ReqHeader 205 | Method = "Get" 206 | } 207 | 208 | $Result = Invoke-RestMethod @params 209 | 210 | $Result.value | 211 | Where-Object { $_.'@microsoft.graph.downloadUrl' -ne $null } | Select-Object name, '@microsoft.graph.downloadUrl' | 212 | ForEach-Object { 213 | 214 | Write-Host "Downloading $($_.name)" 215 | Invoke-WebRequest -Uri $_.'@microsoft.graph.downloadUrl' -OutFile "C:\temp\TestDownload\$($_.name)" -Verbose 216 | 217 | } 218 | 219 | # UPload to Onedrive 220 | # http://bit.ly/2RB27dU 221 | 222 | $ULChildren = Get-ChildItem C:\ODSpeedTest\ULDummyData 223 | foreach ($Child in $ULChildren) { 224 | 225 | while (((get-job -State Running).count) -ge 3) { 226 | sleep -Milliseconds 1 227 | } 228 | 229 | start-job -ScriptBlock { 230 | $URI = "https://graph.microsoft.com/v1.0/users/$username/drive/root:/UploadDummy/$($args[1].Name):/content" 231 | Invoke-RestMethod -Uri $URI -Method PUT -Headers $args[0] -InFile $args[1].FullName 232 | 233 | } -ArgumentList $ReqHeader, $Child 234 | } 235 | 236 | while (((get-job -State Running).count) -gt 0) { 237 | sleep -Milliseconds 1 238 | } 239 | 240 | # REPORTING 241 | # http://bit.ly/2RCxlkR 242 | 243 | (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityCounts(period='D7')" -Method Get -Headers $ReqHeader) -replace "\xEF\xBB\xBF" | ConvertFrom-Csv 244 | 245 | # ALL USERS 246 | # http://bit.ly/2RzL77W 247 | $ReqResult = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users?" -Method Get -Headers $ReqHeader 248 | 249 | $Allusers = @() 250 | $NextFlag = 1 251 | $page = 1 252 | while ($NextFlag -eq 1) { 253 | 254 | Write-Host "Querying page $page" 255 | $Allusers += $ReqResult.value 256 | 257 | if ($ReqResult.psobject.properties.name -contains '@odata.nextlink') { 258 | 259 | $ReqResult = Invoke-RestMethod -Uri $ReqResult.'@odata.nextLink' -Method GET -Headers $ReqHeader 260 | } 261 | else { 262 | $NextFlag = 0 263 | } 264 | $page++ 265 | } 266 | 267 | $Allusers 268 | # Count 269 | $Allusers | Measure-Object 270 | 271 | # ALL GROUPS 272 | # Also doing pagination 273 | $ReqResult = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups?`$select=mailNickname,displayName,securityEnabled,mailEnabled,mail,resourceProvisioningOptions" -Method Get -Headers $ReqHeader 274 | 275 | $AllGroups = @() 276 | $NextFlag = 1 277 | $page = 1 278 | while ($NextFlag -eq 1) { 279 | 280 | Write-Host "Querying page $page" 281 | $AllGroups += $ReqResult.value 282 | 283 | if ($ReqResult.psobject.properties.name -contains '@odata.nextlink') { 284 | 285 | $ReqResult = Invoke-RestMethod -Uri $ReqResult.'@odata.nextLink' -Method GET -Headers $ReqHeader 286 | } 287 | else { 288 | $NextFlag = 0 289 | } 290 | $page++ 291 | } 292 | 293 | $AllGroups | Sort-Object mailNickname 294 | 295 | # ALL TEAMS 296 | $AllGroups | ? { $_.resourceProvisioningOptions -contains "team" } 297 | 298 | # ALL SECURITY 299 | $AllGroups | ? { $_.securityEnabled -eq $true } 300 | 301 | # ALL DISTRO 302 | $AllGroups | ? { $_.mailEnabled -eq $true } 303 | 304 | # Batch Processing 305 | 306 | $BatchReqHeader = @{ 307 | Authorization = "Bearer $($TokReqRes.access_token)" 308 | "Content-Type" = "Application/JSON" 309 | } 310 | 311 | $BatchBody = @" 312 | { 313 | "requests": [ 314 | { 315 | "id": "1", 316 | "method": "GET", 317 | "url": "/users/$username/drive/root:/tasks/" 318 | }, 319 | { 320 | "id": "2", 321 | "method": "GET", 322 | "url": "/users" 323 | } 324 | ] 325 | } 326 | "@ 327 | 328 | $BatchRes = Invoke-RestMethod -Method POST -Uri "https://graph.microsoft.com/v1.0/`$batch" -Headers $BatchReqHeader -Body $BatchBody 329 | 330 | 331 | 332 | 333 | 334 | 335 | -------------------------------------------------------------------------------- /Graph_Get_All_CompanyAdmins.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All 2 | 3 | #Get all members in the Company Administrators role 4 | 5 | #Get the id of the role 6 | $apiUrl = 'https://graph.microsoft.com/v1.0/directoryRoles/' 7 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 8 | $CompanyAdminID = ($Data | Select-Object Value).Value | Where-Object {$_.displayName -eq "Company Administrator"} | Select-Object id 9 | 10 | $apiUrl = "https://graph.microsoft.com/v1.0/directoryRoles/$($CompanyAdminID.id)/members" 11 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 12 | $Members = ($Data | select-object Value).Value 13 | 14 | 15 | $Members | Format-Table DisplayName, userPrincipalName -AutoSize -------------------------------------------------------------------------------- /Graph_Get_All_Devices.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All 2 | 3 | #Get all Devices in Azure AD 4 | 5 | 6 | $apiUrl = 'https://graph.microsoft.com/v1.0/devices/' 7 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 8 | $Computers = ($Data | select-object Value).Value 9 | 10 | 11 | $Computers | Format-Table DisplayName, trustType, operatingSystem -AutoSize -------------------------------------------------------------------------------- /Graph_Get_All_Groups.ps1: -------------------------------------------------------------------------------- 1 | #Get all groups in Azure AD 2 | 3 | 4 | $apiUrl = 'https://graph.microsoft.com/v1.0/Groups/' 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Groups = ($Data | select-object Value).Value 7 | 8 | 9 | $Groups | Format-Table DisplayName, Description -AutoSize -------------------------------------------------------------------------------- /Graph_Get_All_Groups_Paging.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: Group.Read.All, Directory.Read.All, Group.ReadWrite.All, Directory.ReadWrite.All, Directory.AccessAsUser.All 2 | 3 | #https://docs.microsoft.com/en-us/graph/paging 4 | 5 | # ALL Groups, only grab one at a time to show paging 6 | [system.string]$apiUrl = "https://graph.microsoft.com/v1.0/groups?`$top=1" 7 | 8 | [pscustomobject]$ReqResult = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 9 | 10 | #Create an array 11 | [array]$AllGroups = @() 12 | 13 | [int]$NextFlag = 1 14 | [int]$Page = 0 15 | 16 | 17 | while ($NextFlag -eq 1) 18 | { 19 | $AllGroups += $ReqResult.value 20 | 21 | if ($ReqResult.psobject.properties.name -contains '@odata.nextlink') 22 | { 23 | $Page++ 24 | Write-Host "Querying page $page" 25 | $ReqResult = Invoke-RestMethod -Uri $ReqResult.'@odata.nextLink' -Method GET -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } 26 | 27 | } 28 | 29 | else 30 | { 31 | 32 | $NextFlag = 0 33 | 34 | } 35 | } 36 | 37 | 38 | $AllGroups | Select-Object displayName, mail 39 | 40 | -------------------------------------------------------------------------------- /Graph_Get_All_SharePoint_Sites.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed, Sites.Read.All; Sites.ReadWrite.All 2 | 3 | #Get all SharePoint Sites 4 | $apiUrl = "https://graph.microsoft.com/v1.0/sites?search=* " 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Sites = ($Data | Select-Object Value).Value 7 | 8 | 9 | $Sites | Select-Object DisplayName, webUrl -------------------------------------------------------------------------------- /Graph_Get_All_Users.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All 2 | 3 | #Get all Azure AD Users 4 | 5 | $apiUrl = 'https://graph.microsoft.com/v1.0/users/' 6 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 7 | $Users = ($Data | select-object Value).Value 8 | 9 | 10 | $Users | Format-Table displayName, UserPrincipalName -AutoSize -------------------------------------------------------------------------------- /Graph_Get_All_Users_Sort_DisplayName.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All 2 | 3 | #https://docs.microsoft.com/en-us/graph/query-parameters#format-parameter 4 | 5 | #Get all users, sort by displayName 6 | $apiUrl = 'https://graph.microsoft.com/v1.0/users?$orderby=displayName' 7 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 8 | $Users = ($Data | Select-Object Value).Value 9 | 10 | 11 | $Users | Select-Object DisplayName, userPrincipalName -------------------------------------------------------------------------------- /Graph_Get_Calendar_Events_Top5.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: Calendars.Read, Calendars.ReadWrite 2 | 3 | 4 | #Getting all Cal Events 5 | $apiUrl = "https://graph.microsoft.com/v1.0/me/events?`$top=5" 6 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 7 | $Events = ($Data | Select-Object Value).Value 8 | 9 | $Events | Select-Object subject, importance, showas, @{Name = 'Organizer'; Expression = {((($_).organizer).emailaddress).name}}, @{Name = 'Location'; Expression = {(($_).locations).displayname}} 10 | 11 | -------------------------------------------------------------------------------- /Graph_Get_Intune_CompliancePolicies.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: DeviceManagementConfiguration.ReadWrite.All, DeviceManagementConfiguration.Read.All 2 | 3 | 4 | #Getting all device compliance policies 5 | $apiUrl = "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies" 6 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 7 | $CompliancePolicies = ($Data | Select-Object Value).Value 8 | 9 | $CompliancePolicies 10 | 11 | -------------------------------------------------------------------------------- /Graph_Get_OneDrive_Items.ps1: -------------------------------------------------------------------------------- 1 | #Permissions Files.Read, Files.ReadWrite, Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All 2 | 3 | $apiUrl = 'https://graph.microsoft.com/v1.0/me/drive/root/children' 4 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 5 | $DriveItems = ($Data | Select-Object Value).Value 6 | 7 | $DriveItems | Select-Object name, size 8 | -------------------------------------------------------------------------------- /Graph_Get_Recent_Emails.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed, Mail.Read 2 | 3 | #Get my recent emails 4 | $apiUrl = "https://graph.microsoft.com/v1.0/me/messages?`$top=10" 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Emails = ($Data | Select-Object Value).Value 7 | 8 | 9 | 10 | $Emails | Select-Object @{Name = 'From'; Expression = {(($_.sender).emailaddress).name}}, @{Name = 'To'; Expression = {(($_.toRecipients).emailaddress).name}}, subject, hasattachments -------------------------------------------------------------------------------- /Graph_Get_Recent_Security_Alerts.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed, SecurityEvents.Read.All, SecurityEvents.ReadWrite.All 2 | 3 | #Get my recent security alerts 4 | $apiUrl = "https://graph.microsoft.com/v1.0/security/alerts/" 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Alerts = ($Data | Select-Object Value).Value 7 | 8 | 9 | $Alerts | Select-Object Status, category, severity, description, @{Name = 'Affected User'; Expression = {($_.userstates).userPrincipalName}} -------------------------------------------------------------------------------- /Graph_Get_Teams_Channel_Messages_Top3.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: Group.Read.All,Group.ReadWrite.All 2 | 3 | 4 | #Getting all Groups 5 | $apiUrl = "https://graph.microsoft.com/beta/groups/" 6 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 7 | $Groups = ($Data | Select-Object Value).Value 8 | 9 | #Get ID of management team group 10 | $ManagementTeamID = ($Groups | Where-Object {$_.displayname -eq "Management"}).id 11 | 12 | #List the channels in the group, grab the ID for the General chat 13 | $apiUrl = "https://graph.microsoft.com/beta/groups/$ManagementTeamID/Channels" 14 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 15 | $Channels = ($Data | Select-Object Value).Value | Where-Object {$_.displayName -eq "General"} 16 | $ChannelID = ($Channels).ID 17 | 18 | #Grab newest 3 messages from channel 19 | $apiUrl = "https://graph.microsoft.com/beta/teams/$ManagementTeamID/channels/$ChannelID/messages?`$top=3" 20 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 21 | $Messages = ($Data | Select-Object Value).Value 22 | $Messages | Select-Object @{Name = 'Message'; Expression = {(($_).body).content}}, @{Name = 'From'; Expression = {((($_).from).user).displayName}} | Format-List 23 | -------------------------------------------------------------------------------- /Graph_Get_Tenant_Domains.ps1: -------------------------------------------------------------------------------- 1 | #Get all tenant sku information 2 | 3 | #Get tenant sku information 4 | $apiUrl = 'https://graph.microsoft.com/v1.0/domains/' 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Domains = ($Data | Select-Object Value).Value 7 | 8 | 9 | $Domains | Select-Object id, supportedServices 10 | 11 | 12 | -------------------------------------------------------------------------------- /Graph_Get_Tenant_SkuInfo.ps1: -------------------------------------------------------------------------------- 1 | #Get all tenant sku information 2 | 3 | #Get tenant sku information 4 | $apiUrl = 'https://graph.microsoft.com/v1.0/subscribedSkus/' 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $LicInfo = ($Data | Select-Object Value).Value 7 | 8 | 9 | 10 | $LicInfo | Select-Object consumedunits, skuPartNumber, @{Name = 'Services'; Expression = {(($_).serviceplans).serviceplanname}}, appliesto -ExpandProperty prepaidUnits | fl 11 | 12 | -------------------------------------------------------------------------------- /Graph_Post_SharePoint_List.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed, Sites.Read.All; Sites.ReadWrite.All 2 | 3 | #Get all SharePoint Sites 4 | $apiUrl = "https://graph.microsoft.com/v1.0/sites?search=* " 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 6 | $Sites = ($Data | Select-Object Value).Value 7 | 8 | #Find my site named "Management" and get the ID 9 | $CommunitySiteID = ($Sites | Where-Object {$_.name -eq "Management"}).id 10 | #https://bwya77.sharepoint.com/sites/Management 11 | 12 | $apiUrl = "https://graph.microsoft.com/v1.0/sites/$CommunitySiteID/lists" 13 | 14 | $body = @" 15 | { 16 | "displayName": "Books", 17 | "columns": [ 18 | { 19 | "name": "Author", 20 | "text": { } 21 | }, 22 | { 23 | "name": "PageCount", 24 | "number": { } 25 | } 26 | ], 27 | "list": { 28 | "template": "genericList" 29 | } 30 | } 31 | "@ 32 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Post -Body $body -ContentType 'application/json' 33 | 34 | 35 | #https://bwya77.sharepoint.com/sites/Management/Lists/Books 36 | 37 | -------------------------------------------------------------------------------- /Graph_Post_Teams_Message.ps1: -------------------------------------------------------------------------------- 1 | #Permissions needed: Group.ReadWrite.All 2 | 3 | 4 | #Getting all Groups 5 | $apiUrl = "https://graph.microsoft.com/beta/groups/" 6 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 7 | $Groups = ($Data | Select-Object Value).Value 8 | 9 | #Get ID of management team group 10 | $ManagementTeamID = ($Groups | Where-Object {$_.displayname -eq "Management"}).id 11 | 12 | #List the channels in the group, grab the ID 13 | $apiUrl = "https://graph.microsoft.com/beta/groups/$ManagementTeamID/Channels" 14 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 15 | $Channels = ($Data | Select-Object Value).Value | Where-Object {$_.displayName -eq "General"} 16 | $ChannelID = ($Channels).ID 17 | 18 | $apiUrl = "https://graph.microsoft.com/beta/teams/$ManagementTeamID/channels/$ChannelID/messages" 19 | $body = @" 20 | { 21 | "body": { 22 | "content": "Hello World" 23 | } 24 | } 25 | "@ 26 | 27 | Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Body $Body -Method Post -ContentType 'application/json' 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Graph_Upload_OneDrive_File.ps1: -------------------------------------------------------------------------------- 1 | #Permissions Files.Read, Files.ReadWrite, Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All 2 | 3 | $apiUrl = 'https://graph.microsoft.com/v1.0/me/drive/root:/FileB.txt:/content' 4 | $body = "test" 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Put -Body 'test' -ContentType "text/plain" 6 | 7 | -------------------------------------------------------------------------------- /Graph_Upload_OneDrive_File2.ps1: -------------------------------------------------------------------------------- 1 | #Permissions Files.Read, Files.ReadWrite, Files.Read.All, Files.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All 2 | 3 | $apiUrl = 'https://graph.microsoft.com/v1.0/me/drive/root:/test.txt:/content' 4 | $body = "test" 5 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Put -InFile "C:\graph\test.txt" -ContentType "text/plain" 6 | 7 | -------------------------------------------------------------------------------- /MSGraph API.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwya77/GraphAPI/115b330bf2943d340b392c0e5d23944002b13037/MSGraph API.pdf -------------------------------------------------------------------------------- /MSGraph API.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwya77/GraphAPI/115b330bf2943d340b392c0e5d23944002b13037/MSGraph API.pptx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphAPI -------------------------------------------------------------------------------- /Report.ps1: -------------------------------------------------------------------------------- 1 | $ReportSavePath = "C:\Graph\" 2 | $rightlogo = "https://www.psmpartners.com/wp-content/themes/psm/images/psm-logo.png" 3 | 4 | 5 | $Table = New-Object 'System.Collections.Generic.List[System.Object]' 6 | $UserTable = New-Object 'System.Collections.Generic.List[System.Object]' 7 | $GroupTable = New-Object 'System.Collections.Generic.List[System.Object]' 8 | $DevicesTable = New-Object 'System.Collections.Generic.List[System.Object]' 9 | $LicenseTable = New-Object 'System.Collections.Generic.List[System.Object]' 10 | $SitesTable = New-Object 'System.Collections.Generic.List[System.Object]' 11 | $SecurityAlerts = New-Object 'System.Collections.Generic.List[System.Object]' 12 | 13 | Write-Host "Getting Company Admins" 14 | #Company Admins 15 | 16 | $apiUrl = 'https://graph.microsoft.com/v1.0/directoryRoles/' 17 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 18 | $CompanyAdminID = ($Data | Select-Object Value).Value | Where-Object { $_.displayName -eq "Company Administrator" } | Select-Object id 19 | 20 | $apiUrl = "https://graph.microsoft.com/v1.0/directoryRoles/$($CompanyAdminID.id)/members" 21 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 22 | $Members = ($Data | select-object Value).Value 23 | 24 | $Members | ForEach-Object { 25 | 26 | $obj = [PSCustomObject]@{ 27 | 'Name' = $_.DisplayName 28 | 'UserPrincipalName' = $_.userPrincipalName 29 | } 30 | 31 | $Table.add($obj) 32 | } 33 | Write-Host "Done!" -ForegroundColor Green 34 | 35 | Write-Host "Getting Security Alerts" 36 | #Get my recent security alerts 37 | $apiUrl = "https://graph.microsoft.com/v1.0/security/alerts/" 38 | $Data = Invoke-RestMethod -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get 39 | $Alerts = ($Data | Select-Object Value).Value 40 | $Alerts | ForEach-Object { 41 | 42 | $obj = [PSCustomObject]@{ 43 | 'Status' = $_.Status 44 | 'Category' = $_.Category 45 | 'Severity' = $_.Severity 46 | 'Name' = ($_.userstates).userPrincipalName 47 | 'Description' = $_.Description 48 | } 49 | 50 | $SecurityAlerts.add($obj) 51 | } 52 | Write-Host "Done!" -ForegroundColor Green 53 | 54 | Write-Host "Getting Users" 55 | #Get all users, sort by displayName 56 | 57 | 58 | $apiUrl = 'https://graph.microsoft.com/v1.0/users?$orderby=displayName' 59 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 60 | $Users = ($Data | Select-Object Value).Value 61 | 62 | 63 | $Users | ForEach-Object { 64 | $obj = [PSCustomObject]@{ 65 | 'Name' = $_.DisplayName 66 | 'UserPrincipalName' = $_.userPrincipalName 67 | } 68 | 69 | $UserTable.add($obj) 70 | } 71 | Write-Host "Done!" -ForegroundColor Green 72 | 73 | Write-Host "Getting Groups" 74 | #Get all Azure AD Groups 75 | # ALL Groups, only grab one at a time to show paging 76 | [system.string]$apiUrl = "https://graph.microsoft.com/v1.0/groups?`$top=1" 77 | 78 | [pscustomobject]$ReqResult = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 79 | 80 | #Create an array 81 | [array]$AllGroups = @() 82 | 83 | [int]$NextFlag = 1 84 | 85 | 86 | 87 | while ($NextFlag -eq 1) 88 | { 89 | $AllGroups += $ReqResult.value 90 | 91 | if ($ReqResult.psobject.properties.name -contains '@odata.nextlink') 92 | { 93 | $ReqResult = Invoke-RestMethod -Uri $ReqResult.'@odata.nextLink' -Method GET -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } 94 | } 95 | 96 | else 97 | { 98 | $NextFlag = 0 99 | } 100 | } 101 | $AllGroups | ForEach-Object { 102 | $obj = [PSCustomObject]@{ 103 | 'Name' = $_.DisplayName 104 | 'E-Mail' = $_.mail 105 | } 106 | 107 | $GroupTable.add($obj) 108 | } 109 | Write-Host "Done!" -ForegroundColor Green 110 | 111 | Write-Host "Getting Devices" 112 | #Get all Azure AD Devices 113 | $apiUrl = 'https://graph.microsoft.com/v1.0/devices/' 114 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 115 | $Computers = ($Data | select-object Value).Value 116 | 117 | $Computers | ForEach-Object { 118 | $obj = [PSCustomObject]@{ 119 | 'Name' = $_.DisplayName 120 | 'Trust Type' = $_.trustType 121 | 'Operating System' = $_.operatingSystem 122 | } 123 | 124 | $DevicesTable.add($obj) 125 | } 126 | Write-Host "Done!" -ForegroundColor Green 127 | 128 | 129 | #Licenses 130 | $apiUrl = 'https://graph.microsoft.com/v1.0/subscribedSkus/' 131 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 132 | $LicInfo = ($Data | Select-Object Value).Value 133 | $LicInfo | ForEach-Object { 134 | $service = ($_.serviceplans).serviceplanname 135 | $list = $service -join ", " 136 | 137 | $obj = [PSCustomObject]@{ 138 | 'Name' = $_.skuPartNumber 139 | 'Services' = $list 140 | } 141 | 142 | $LicenseTable.add($obj) 143 | 144 | } 145 | 146 | #SharePoint Sites 147 | #Get all SharePoint Sites 148 | Write-Host "Getting all SharePoint Sites" 149 | $apiUrl = "https://graph.microsoft.com/v1.0/sites?search=* " 150 | $Data = Invoke-RestMethod -Headers @{ Authorization = "Bearer $($Tokenresponse.access_token)" } -Uri $apiUrl -Method Get 151 | $Sites = ($Data | Select-Object Value).Value 152 | $Sites | ForEach-Object { 153 | $obj = [PSCustomObject]@{ 154 | 'Name' = $_.Displayname 155 | 'URL' = $_.webUrl 156 | } 157 | 158 | $SitesTable.add($obj) 159 | 160 | } 161 | Write-Host "Done!" -ForegroundColor Green 162 | 163 | Write-Host "Generating HTML Report..." -ForegroundColor Yellow 164 | Write-Host "Creating Tab array" 165 | $tabarray = @('Dashboard', 'SharePoint') 166 | Write-Host "Creating report object" 167 | $rpt = New-Object 'System.Collections.Generic.List[System.Object]' 168 | #C:\Program Files\WindowsPowerShell\Modules\ReportHTML\1.4.1.2 169 | $rpt += get-htmlopenpage -TitleText 'Enviornment Report' -CSSName "psm" -RightLogoString $rightlogo 170 | 171 | $rpt += Get-HTMLTabHeader -TabNames $tabarray 172 | $rpt += get-htmltabcontentopen -TabName $tabarray[0] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)) 173 | Write-Host "Creating Dashboard Page" 174 | $rpt+= Get-HtmlContentOpen -HeaderText "Dashboard" 175 | Write-Host "Creating Permission Report" 176 | $rpt += Get-HTMLContentOpen -HeaderText "Permissions - Company Administrators" 177 | $rpt += Get-HtmlContentTable $Table 178 | $rpt += Get-HTMLContentClose 179 | $rpt += Get-HTMLContentOpen -HeaderText "Security Alerts" 180 | Write-Host "Creating Security Alerts Report" 181 | $rpt += Get-HtmlContentTable $SecurityAlerts 182 | $rpt += Get-HTMLContentClose 183 | 184 | $rpt+= get-HtmlColumn1of2 185 | $rpt+= Get-HtmlContentOpen -BackgroundShade 1 -HeaderText 'Users' 186 | Write-Host "Creating User Report" 187 | $rpt+= get-htmlcontentdatatable $UserTable -HideFooter 188 | $rpt+= Get-HtmlContentClose 189 | $rpt+= get-htmlColumnClose 190 | $rpt+= get-htmlColumn2of2 191 | Write-Host "Creating Computer Report" 192 | $rpt+= Get-HtmlContentOpen -HeaderText 'Computers' 193 | $rpt+= get-htmlcontentdatatable $DevicesTable -HideFooter 194 | $rpt+= Get-HtmlContentClose 195 | $rpt+= get-htmlColumnClose 196 | Write-Host "Creating License Report" 197 | $rpt += Get-HTMLContentOpen -HeaderText "Licenses" 198 | $rpt += Get-HtmlContentTable $LicenseTable 199 | $rpt += Get-HTMLContentClose 200 | 201 | $rpt+= Get-HtmlContentClose 202 | $rpt += get-htmltabcontentclose 203 | 204 | $rpt += get-htmltabcontentopen -TabName $tabarray[1] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)) 205 | $rpt+= Get-HtmlContentOpen -HeaderText "SharePoint" 206 | $rpt += Get-HTMLContentOpen -HeaderText "SharePoint Sites" 207 | $rpt += get-htmlcontentdatatable $SitesTable -HideFooter 208 | $rpt += Get-HTMLContentClose 209 | $rpt += Get-HTMLContentClose 210 | $rpt += get-htmltabcontentclose 211 | 212 | $rpt += Get-HTMLClosePage 213 | 214 | $Day = (Get-Date).Day 215 | $Month = (Get-Date).Month 216 | $Year = (Get-Date).Year 217 | Write-Host "Compiling Report" 218 | $ReportName = ( "$Month" + "-" + "$Day" + "-" + "$Year" + "-" + "O365 Tenant Report") 219 | Save-HTMLReport -ReportContent $rpt -ShowReport -ReportName $ReportName -ReportPath $ReportSavePath --------------------------------------------------------------------------------