NN.MSGraph.psm1
#Region '.\Private\Get-MgAccessToken.ps1' 0 function Get-MgAccessToken { param ( $accessTokenPath = "$env:USERPROFILE\.creds\MSGraph\msgraphAccessToken.xml" ) #Conditions to refresh access token if (Test-Path $accessTokenPath) { [datetime]$accessTokenExpiryDate = (Import-Clixml $accessTokenPath | ConvertFrom-SecureString -AsPlainText | ConvertFrom-Json).expiry_date #Refresh access token if there's less than 5 minutes till token expiry if (($accessTokenExpiryDate.AddMinutes(-5)) -lt (Get-Date)) { #Request new access token New-MgAccessToken } } else { #Request new access token New-MgAccessToken } #Import the access token (Import-Clixml $accessTokenPath | ConvertFrom-SecureString -AsPlainText | ConvertFrom-Json).access_token } #EndRegion '.\Private\Get-MgAccessToken.ps1' 22 #Region '.\Private\Get-MgSecret.ps1' 0 function Get-MgSecret { param ( $secretPath = "$env:USERPROFILE\.creds\MSGraph\msgraphSecret.xml" ) #Check if secret file exists if (Test-Path $secretPath) { [datetime]$dateTomorrow = (Get-Date).AddDays(1) $secretExpiryDate = (Import-Clixml $secretPath | ConvertFrom-SecureString -AsPlainText | ConvertFrom-Json).endDateTime #Refresh secret if there's less than 1 day till secret expiry if ($dateTomorrow -gt $secretExpiryDate) { New-MgSecret } } else { #Refresh secret if the secret file doesn't exist New-MgSecret } #Import the secret key (Import-Clixml $secretPath | ConvertFrom-SecureString -AsPlainText | ConvertFrom-Json).secretText } #EndRegion '.\Private\Get-MgSecret.ps1' 23 #Region '.\Public\Get-MgApiUser.ps1' 0 function Get-MgApiUser { param ( [Parameter(Mandatory)]$identifier ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/users/$identifier" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgApiUser.ps1' 14 #Region '.\Public\Get-MgAuthenticationMetod.ps1' 0 function Get-MgAuthenticationMethod { param ( [Parameter(Mandatory)][string]$UPN ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/beta/users/$UPN/authentication/phoneMethods" "Headers" = @{ "Authorization" = "Bearer $(Get-GraphAccessToken)" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgAuthenticationMetod.ps1' 14 #Region '.\Public\Get-MgDirectReportsList.ps1' 0 function Get-MgDirectReportsList { param ( [Parameter(Mandatory)][string]$identifier ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/users/$identifier/directReports" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgDirectReportsList.ps1' 13 #Region '.\Public\Get-MgManager.ps1' 0 function Get-MgManager { param ( [Parameter(Mandatory)][string]$identifier ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/users/$identifier/manager" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgManager.ps1' 13 #Region '.\Public\Get-MgShift.ps1' 0 function Get-MgShift { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, [Parameter(Mandatory)]$shiftId ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/shifts/$shiftId" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgShift.ps1' 19 #Region '.\Public\Get-MgShiftList.ps1' 0 function Get-MgShiftList { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, #Timespan to fetch shifts from [Parameter(Mandatory)][datetime]$dateFrom, [datetime]$dateTo = $dateFrom.AddDays(1) ) #Convert to "ISO 8601" date format, which is supported in json queries $convertedDateFrom = [Xml.XmlConvert]::ToString($dateFrom,[Xml.XmlDateTimeSerializationMode]::Utc) $convertedDateTo = [Xml.XmlConvert]::ToString($dateTo,[Xml.XmlDateTimeSerializationMode]::Utc) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/shifts" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } "Body" = @{ '$filter' = "sharedShift/startDateTime ge $convertedDateFrom and sharedShift/endDateTime le $convertedDateTo" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgShiftList.ps1' 28 #Region '.\Public\Get-MgShiftSchedulingGroupList.ps1' 0 function Get-MgShiftSchedulingGroupList { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/schedulingGroups" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgShiftSchedulingGroupList.ps1' 18 #Region '.\Public\Get-MgShiftTimeOff.ps1' 0 function Get-MgShiftTimeOff { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, [Parameter(Mandatory)]$timeOffId ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/timesOff/$timeOffId" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgShiftTimeOff.ps1' 19 #Region '.\Public\Get-MgShiftTimeOffList.ps1' 0 function Get-MgShiftTimeOffList { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, #Timespan to fetch shifts from [Parameter(Mandatory)][datetime]$dateFrom, [datetime]$dateTo = $dateFrom.AddDays(1) ) #Convert to "ISO 8601" date format, which is supported in json queries $convertedDateFrom = [Xml.XmlConvert]::ToString($dateFrom,[Xml.XmlDateTimeSerializationMode]::Utc) $convertedDateTo = [Xml.XmlConvert]::ToString($dateTo,[Xml.XmlDateTimeSerializationMode]::Utc) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/timesOff" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } "Body" = @{ '$filter' = "sharedTimeOff/startDateTime ge $convertedDateFrom and sharedTimeOff/endDateTime le $convertedDateTo" } } Invoke-RestMethod @splat } #EndRegion '.\Public\Get-MgShiftTimeOffList.ps1' 28 #Region '.\Public\Get-MgShiftTimeOffReasonList.ps1' 0 function Get-MgShiftTimeOffReasonList { param ( #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID ) $splat = @{ "Method" = "GET" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/timeOffReasons" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "MS-APP-ACTS-AS" = $actAsUID } } $result = Invoke-RestMethod @splat $result.value } #EndRegion '.\Public\Get-MgShiftTimeOffReasonList.ps1' 19 #Region '.\Public\New-MgAccessToken.ps1' 0 function New-MgAccessToken { param ( #Azure tenantID $tenantIdPath = "$env:USERPROFILE\.creds\MSGraph\msgraphTenantId.xml", #AppID of the Azure app $appIdPath = "$env:USERPROFILE\.creds\MSGraph\msgraphAppId.xml", $accessTokenPath = "$env:USERPROFILE\.creds\MSGraph\msgraphAccessToken.xml" ) #Create folder to store credentials $accessTokenDir = $accessTokenPath.Substring(0, $accessTokenPath.lastIndexOf('\')) if (!(Test-Path $accessTokenDir)) { $null = New-Item -ItemType Directory $accessTokenDir } #Get tenantId if (Test-Path $tenantIdPath) { $tenantId = Import-Clixml $tenantIdPath | ConvertFrom-SecureString -AsPlainText } else { #Create tenantId file $tenantId = Read-Host "Enter MSGraph tenantId" $tenantId | ConvertTo-SecureString -AsPlainText | Export-Clixml $tenantIdPath } #Get appId if (Test-Path $appIdPath) { $appId = Import-Clixml $appIdPath | ConvertFrom-SecureString -AsPlainText } else { #Create appId file $appId = Read-Host "Enter MSGraph appId" $appId | ConvertTo-SecureString -AsPlainText | Export-Clixml $appIdPath } $splat = @{ "Method" = "POST" "Uri" = "https://login.microsoftonline.com/$tenantId/oauth2/token" "Body" = @{ "resource" = "https://graph.microsoft.com" "client_id" = $appId "client_secret" = Get-MgSecret "grant_type" = "client_credentials" "scope" = "openid" } } $result = Invoke-RestMethod @splat #Adds access token and expiry date to access token file [PSCustomObject]@{ access_token = $result.access_token expiry_date = (Get-Date).AddSeconds($result.expires_in) } | ConvertTo-Json | ConvertTo-SecureString -AsPlainText | Export-Clixml -Path $accessTokenPath -Force } #EndRegion '.\Public\New-MgAccessToken.ps1' 52 #Region '.\Public\New-MgSecret.ps1' 0 function New-MgSecret { param ( #ObjectId of the Azure application $objectIdPath = "$env:USERPROFILE\.creds\MSGraph\msgraphObjectId.xml", $secretPath = "$env:USERPROFILE\.creds\MSGraph\msgraphSecret.xml" ) #Create folder to store credentials $secretDir = $secretPath.Substring(0, $secretPath.lastIndexOf('\')) if (!(Test-Path $secretDir)) { $null = New-Item -ItemType Directory $secretDir } #Create objectId file if (Test-Path $objectIdPath) { $objectId = Import-Clixml $objectIdPath | ConvertFrom-SecureString -AsPlainText } else { $objectId = Read-Host "Enter MSGraph objectId" $objectId | ConvertTo-SecureString -AsPlainText | Export-Clixml $objectIdPath } #Install required modules $requiredModules = @("Az.Accounts","Az.Resources") $requiredModules.ForEach({ if (Get-InstalledModule $_) { Import-Module $_ -Force } else { Install-Module $_ -Force } }) #Connect to the Azure account $null = Connect-AzAccount #Create a new secret $result = New-AzADAppCredential -ObjectId $objectId -CustomKeyIdentifier "TeamBrukeropplevelse" #Export secret to the secret file $result | ConvertTo-SecureString -AsPlainText | Export-Clixml $secretPath -Force #Output the eol date of the secret Write-Output "MSGraph secret expires $($result.endDateTime.ToString("dd/MM/yyyy hh:mm"))" } #EndRegion '.\Public\New-MgSecret.ps1' 40 #Region '.\Public\New-MgShift.ps1' 0 function New-MgShift { param ( [Parameter(Mandatory)]$userId, [Parameter(Mandatory)]$startDateTime, [Parameter(Mandatory)]$endDateTime, [Parameter(Mandatory)]$shiftType, [Parameter(Mandatory)]$theme, [Parameter(Mandatory)]$schedulingGroupId, #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, [string]$notes ) #Convert from current TZ to UTC $strCurrentTZ = (Get-CimInstance win32_timezone).StandardName $TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTZ) $shiftStartDateTime = [System.TimeZoneInfo]::ConvertTimeToUtc($startDateTime, $TZ) $shiftEndDateTime = [System.TimeZoneInfo]::ConvertTimeToUtc($endDateTime, $TZ) #Convert to "ISO 8601" date format, which is supported in json queries $convertedStartDateTime = [Xml.XmlConvert]::ToString($shiftStartDateTime,[Xml.XmlDateTimeSerializationMode]::Utc) $convertedEndDateTime = [Xml.XmlConvert]::ToString($shiftEndDateTime,[Xml.XmlDateTimeSerializationMode]::Utc) $splat = @{ "Method" = "POST" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/shifts" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "Content-type" = "application/json" "MS-APP-ACTS-AS" = $actAsUID } "Body" = @{ "userId" = $userId "schedulingGroupId" = $schedulingGroupId "sharedShift" = @{ "@odata.type" = "microsoft.graph.shiftItem" "displayName" = $shiftType "notes" = $notes "startDateTime" = $convertedStartDateTime "endDateTime" = $convertedEndDateTime "theme" = $theme } } | ConvertTo-Json } Invoke-RestMethod @splat } #EndRegion '.\Public\New-MgShift.ps1' 48 #Region '.\Public\New-MgShiftTimeOff.ps1' 0 function New-MgShiftTimeOff { param ( [Parameter(Mandatory)]$userId, [Parameter(Mandatory)]$startDateTime, [Parameter(Mandatory)]$endDateTime, [Parameter(Mandatory)]$timeOffReasonId, #Id of the Team to get shifts from [Parameter(Mandatory)]$teamId, #Id of the user that the request is sent on the behalf of [Parameter(Mandatory)]$actAsUID, [string]$notes, $theme = "gray" ) #Convert from current TZ to UTC $strCurrentTZ = (Get-CimInstance win32_timezone).StandardName $TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTZ) $shiftStartDateTime = [System.TimeZoneInfo]::ConvertTimeToUtc($startDateTime, $TZ) $shiftEndDateTime = [System.TimeZoneInfo]::ConvertTimeToUtc($endDateTime, $TZ) #Convert to "ISO 8601" date format, which is supported in json queries $convertedStartDateTime = [Xml.XmlConvert]::ToString($shiftStartDateTime,[Xml.XmlDateTimeSerializationMode]::Utc) $convertedEndDateTime = [Xml.XmlConvert]::ToString($shiftEndDateTime,[Xml.XmlDateTimeSerializationMode]::Utc) $splat = @{ "Method" = "POST" "Uri" = "https://graph.microsoft.com/v1.0/teams/$teamId/schedule/timesOff" "Headers" = @{ "Authorization" = "Bearer $(Get-MgAccessToken)" "Content-type" = "application/json" "MS-APP-ACTS-AS" = $actAsUID } "Body" = @{ "userId" = $userId "sharedTimeOff" = @{ "@odata.type" = "microsoft.graph.timeOffItem" "timeOffReasonId" = $timeOffReasonId "notes" = $notes "startDateTime" = $convertedStartDateTime "endDateTime" = $convertedEndDateTime "theme" = $theme } } | ConvertTo-Json } Invoke-RestMethod @splat } #EndRegion '.\Public\New-MgShiftTimeOff.ps1' 46 |