Skip to content

Instantly share code, notes, and snippets.

@RobinBeismann
Created July 5, 2022 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobinBeismann/cc9e4ee342b769433a6f2bfa8d94252a to your computer and use it in GitHub Desktop.
Save RobinBeismann/cc9e4ee342b769433a6f2bfa8d94252a to your computer and use it in GitHub Desktop.
# General Settings
$exportDir = "$env:workspace\uploadArtifacts\"
$exportFile = "AbsenceExport.csv"
$exportPath = "$exportDir\$exportFile"
# AAD Credentials
$ClientSecret = $env:aadSecret
$ClientId = $env:aadId
$TenantId = $env:tenantId
$groupName = $env:aadGroup
#region Azure AD (Graph) Authentication
$Body = @{
'tenant' = $TenantId
'client_id' = $ClientId
'scope' = 'https://graph.microsoft.com/.default'
'client_secret' = $ClientSecret
'grant_type' = 'client_credentials'
}
$Params = @{
'Uri' = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
'Method' = 'Post'
'Body' = $Body
'ContentType' = 'application/x-www-form-urlencoded'
}
$AuthResponse = Invoke-RestMethod @Params
$Headers = @{
'Authorization' = "Bearer $($AuthResponse.access_token)"
}
#endregion
function Get-GraphApiResult {
param (
[parameter(Mandatory = $true)]
$ClientID,
[parameter(Mandatory = $true)]
$ClientSecret,
[parameter(Mandatory = $true)]
$TenantName,
[parameter(Mandatory = $true)]
$Uri
)
# Graph API URLs.
$LoginUrl = "https://login.microsoft.com"
$resourceUrl = "https://graph.microsoft.com"
# Compose REST request.
$Body = @{ grant_type = "client_credentials"; resource = $resourceUrl; client_id = $ClientID; client_secret = $ClientSecret }
$OAuth = Invoke-RestMethod -Method Post -Uri $LoginUrl/$TenantName/oauth2/token?api-version=1.0 -Body $Body
# Check if authentication was successfull.
if ($OAuth.access_token) {
# Format headers.
$HeaderParams = @{
'Content-Type' = "application\json"
'Authorization' = "$($OAuth.token_type) $($OAuth.access_token)"
}
# Create an empty array to store the result.
$QueryResults = @()
# Invoke REST method and fetch data until there are no pages left.
do {
$Results = Invoke-RestMethod -Headers $HeaderParams -Uri $Uri -UseBasicParsing -Method "GET" -ContentType "application/json"
if ($Results.value) {
$QueryResults += $Results.value
}
else {
$QueryResults += $Results
}
$uri = $Results.'@odata.nextlink'
} until (!($uri))
# Return the result.
$QueryResults
}
else {
Write-Error "No Access Token"
}
}
#region Get Azure AD Group
$groupId = Get-GraphApiResult -ClientID $ClientId -ClientSecret $ClientSecret -TenantName $TenantId -Uri "https://graph.microsoft.com/v1.0/groups?`$filter=displayname+eq+'$groupName'&`$select=id,displayname" | Select-Object -ExpandProperty Id
#endregion
if(!$groupId){
Write-Error("[$(Get-Date)] Safety Check: groupId not found, breaking!")
exit 1;
}
#endregion
$funcDef = ${function:Get-GraphApiResult}.ToString()
if($members = Get-GraphApiResult -ClientID $ClientId -ClientSecret $ClientSecret -TenantName $TenantId -Uri "https://graph.microsoft.com/v1.0/groups/$groupId/members?`$select=onPremisesSamAccountName,userPrincipalName,id"){
$entries = $members | ForEach-Object -ThrottleLimit 15 -Parallel {
$user = $_
try{
${function:Get-GraphApiResult} = $using:funcDef
$res = Get-GraphApiResult -ClientID $using:ClientId -ClientSecret $using:ClientSecret -TenantName $using:TenantId -Uri "https://graph.microsoft.com/v1.0/users/$($user.id)/mailboxSettings/automaticRepliesSetting" -ErrorAction Stop
if(
$res -and
$res.status -ne "disabled"
){
[PSCustomObject]@{
userPrincipalName = $user.UserPrincipalName
sAMAccountName = $user.onPremisesSamAccountName
AzureADID = $user.id
Status = $res.Status
StartTime = ($res.scheduledStartDateTime.dateTime | Get-Date -Format "yyyy\/MM\/dd HH:mm:ss")
StartTimeTimeZone = $res.scheduledStartDateTime.timeZone
EndTime = ($res.scheduledEndDateTime.dateTime | Get-Date -Format "yyyy\/MM\/dd HH:mm:ss")
EndTimeTimeZone = $res.scheduledEndDateTime.timeZone
}
}
}catch{
if($_.ErrorDetails.Message -and $_.ErrorDetails.Message.Contains("REST API is not yet supported for this mailbox")){
Write-Host($user.userPrincipalName + ": Not a cloud mailbox user (REST API is not yet supported for this mailbox).")
}elseif($_.Exception -and $_.Exception.Message -and $_.Exception.Message.Contains("404")){
Write-Host($user.userPrincipalName + ": Not a cloud mailbox user (404).")
}else{
Write-Error("[$(Get-Date)] Could not get recipient details for $($user.userPrincipalName), error: $_")
}
}
}
if(
$entries -and
$entries.Count -gt 10
){
if(Test-Path -Path $exportPath -ErrorAction SilentlyContinue){
Write-Host("[$(Get-Date)] Removing Export at `"$exportPath`"..")
Remove-Item -Path $exportPath -Confirm:$false
}
if(Test-Path -Path $exportDir -ErrorAction SilentlyContinue){
Write-Host("[$(Get-Date)] Removing Directory at `"$exportDir`"..")
Remove-item -Path $exportDir -Recurse -Confirm:$false
}
$null = New-Item -Path $exportDir -ItemType 'Directory' -Force
Write-Host("[$(Get-Date)] Exporting Results to `"$exportPath`"..")
$entries | Export-Csv -Path $exportPath -Encoding 'UTF8' -NoClobber -NoTypeInformation
}
}else{
Write-Error("[$(Get-Date)] Safety Check: Group members empty, breaking!")
exit 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment