Microsoft.Graph.API.psm1
function Connect-MSGraphCertificate { [CmdletBinding(HelpURI = 'https://bwit.blog')] param ( [Parameter(Mandatory = $true)] [Alias("ID", "AppID", "ClientID", "App")] [string] $ApplicationID, [Parameter(Mandatory = $true)] [string] $Thumbprint, [Parameter(Mandatory = $true)] [Alias("TenantName", "Tenant")] [string] $TenantID ) begin { $global:ApplicationID = $ApplicationID $global:Thumbprint = $Thumbprint $global:TenantID = $TenantID $Global:Login = 'MSGraphCertificate' $global:ErrorList = [system.Collections.Generic.List[system.Object]]::new() } process { try { Get-MSGRAPHOauthToken ` -AppID $global:ApplicationID ` -Thumbprint $global:Thumbprint ` -Tenant $global:TenantID } catch { $Object = [PSCustomObject] @{ Information = "Connect-MSGraphCertificate: Error in process of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Connect-MSGraphCertificate: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } end { Write-Verbose "Connect-MSGraphCertificate: We've succesfully logged in." return $EndResult } } function Connect-MSGraphAppSecret { [CmdletBinding(HelpURI = 'https://bwit.blog')] param ( [Parameter(Mandatory = $true)] [Alias("ID", "AppID", "ClientID", "App")] [string] $ApplicationID, [Parameter(Mandatory = $true)] [Alias("Password", "PW", "AppSecret", "Pass")] [string] $ApplicationSecret, [Parameter(Mandatory = $true)] [Alias("TenantName", "Tenant")] [string] $TenantID ) begin { $global:ApplicationID = $ApplicationID $global:ApplicationSecret = $ApplicationSecret $global:TenantID = $TenantID $global:Login = 'MSGraphAppSecret' $global:ErrorList = [system.Collections.Generic.List[system.Object]]::new() } process { try { Get-MSGRAPHOauthToken ` -AppID $global:ApplicationID ` -AppPass $global:ApplicationSecret ` -Tenant $global:TenantID } catch { $Object = [PSCustomObject] @{ Information = "Connect-MSGraphAppSecret: Error in begin of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Connect-MSGraphAppSecret: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } end { Write-Verbose "Connect-MSGraphAppSecret: We've succesfully logged in." return $EndResult } } function Get-MSGraphReport { [CmdletBinding(HelpURI = 'https://bwit.blog')] param ( [Parameter(Mandatory = $true)] [Alias("URI")] [string] $URL ) begin { try { $global:ErrorList = [system.Collections.Generic.List[system.Object]]::new() if ($global:Login -eq 'MSGraphAppSecret') { Get-MSGRAPHOauthToken ` -AppID $global:ApplicationID ` -AppPass $global:ApplicationSecret ` -Tenant $global:TenantID } elseif ($global:Login -eq 'MSGraphCertificate') { Get-MSGRAPHOauthToken ` -AppID $global:ApplicationID ` -Thumbprint $global:Thumbprint ` -Tenant $global:TenantID } else { Throw "You need to run one of these cmdlets: Connect-MSGraphAppSecret or Connect-MSGraphCertificate before you can continue. Exiting script..." break } } catch { $Object = [PSCustomObject] @{ Information = "Get-MSGRaphReport: Error in begin of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Get-MSGRaphReport: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } process { try { Write-Verbose "Get-MSGRaphReport: Getting results from $URL." $Result = Invoke-WebRequest -UseBasicParsing -Headers $global:HeaderParameters -Uri $URL -Method get if ($result.Headers.'Content-Type' -like "application/octet-stream*") { Write-Verbose "Get-MSGRaphReport: Result is in CSV format. Converting to CSV." Write-Verbose "Get-MSGRaphReport: We will add the data to endresult." $EndResult = ConvertFrom-Csv -InputObject $Result } if ($result.Headers.'Content-Type' -like "application/json*") { Write-Verbose "Get-MSGRaphReport: Result is in JSON format. Converting to JSON." $JSON = ConvertFrom-Json -InputObject $Result if ($JSON.'@odata.nextLink') { Write-Verbose "Get-MSGRaphReport: Data output is more than 100 results. We will run script again with next data link." $EndResult = @() foreach ($Line in ($JSON).value) { $EndResult += $Line } While ($JSON.'@odata.nextLink') { Write-Verbose "Get-MSGRaphReport: Data output is still more than 100 results. We will run script again with next data link." $JSON = (Invoke-WebRequest -UseBasicParsing -Headers $HeaderParameters -Uri $JSON.'@odata.nextLink' -Method Get).Content | ConvertFrom-Json foreach ($Line in ($JSON).value) { $EndResult += $Line } Write-Verbose "Get-MSGRaphReport: Count is: $($EndResult.count)" } } elseif ($JSON.value) { Write-Verbose "Get-MSGRaphReport: Data output is less than 100 results. We will add the data to end result." $EndResult = $JSON.value } else { Write-Verbose "Get-MSGRaphReport: Data output is less than 100 results. We will add the data to end result." $EndResult = $JSON } } } catch { $Object = [PSCustomObject] @{ Information = "Get-MSGRaphReport: Error in process of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Get-MSGRaphReport: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } end { Write-Verbose "Get-MSGRaphReport: We've succesfully retrieved the end result. The end result will be returned." return $EndResult } } function Get-MSGraphOauthToken { [CmdletBinding(HelpURI = 'https://bwit.blog')] param ( [Parameter(Mandatory = $true)] [string] $AppID, [Parameter(Mandatory = $false)] [string] $AppPass, [Parameter(Mandatory = $false)] [string] $Thumbprint, [Parameter(Mandatory = $true)] [string] $Tenant ) begin { try { $loginURL = "https://login.microsoft.com" $Resource = "https://graph.microsoft.com" Write-Verbose "Get-MSGRAPHOauthToken: Login URL is: $LoginUrl." Write-Verbose "Get-MSGRAPHOauthToken: Resource is: $Resource." if ($AppPass) { Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: We will continue logging in with ApplicationSecret." $global:Body = @{ grant_type = "client_credentials"; resource = $Resource; client_id = $AppID; client_secret = $AppPass } } elseif ($Thumbprint) { Write-Verbose "Get-MSGRAPHOauthToken: Thumbprint: We will continue logging in with Certificate." $Cert = Search-MSGRAPHCertByThumbprint -Thumbprint $Thumbprint $AssertionCert = [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate]::new($AppID, $Cert) $AuthContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.microsoftonline.com/$Tenant") } else { Throw "There is no Password nor Thumbprint. Exiting script..." break } } catch { $Object = [PSCustomObject] @{ Information = "Get-MSGRAPHOauthToken: Error in begin of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Get-MSGRAPHOauthToken: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } process { try { [datetime]$UnixDateTime = '1970-01-01 00:00:00' $Date = Get-Date $UTCDate = [System.TimeZoneInfo]::ConvertTimeToUtc($Date) if ($AppPass) { if (!($global:AppPass)) { Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: Body has formed to retrieve Oauth access token from $Resource." $global:AppPass = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantID/oauth2/token?api-version=1.0 -Body $Body if ($null -eq $global:AppPass.access_token) { throw 'We did not retrieve an Oauth access token to continue script. Exiting script...' break } else { $global:headerParameters = @{ Authorization = "$($global:AppPass.token_type) $($global:AppPass.access_token)" } } } else { Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: Oauth token already exists from previously running cmdlets." Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: Running test to see if Oauth token expired." $OauthExpiryTime = $UnixDateTime.AddSeconds($global:AppPass.expires_on) if ($OauthExpiryTime -le $UTCDate) { Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: Oauth token expired. Emptying Oauth variable and re-running function." $global:AppPass = $null Get-MSGRAPHOauthToken -URL $URL ` -AppID $ApplicationID ` -AppPass $ApplicationSecret ` -Tenant $TenantID } else { Write-Verbose "Get-MSGRAPHOauthToken: ApplicationSecret: Oauth token from last run is still active." } } } else { [datetime]$UnixDateTime = '1970-01-01 00:00:00' $Date = Get-Date $UTCDate = [System.TimeZoneInfo]::ConvertTimeToUtc($Date) if (!($global:CertLogin)) { Write-Verbose "Get-MSGRAPHOauthToken: Certificate: Using certificate to log on $Resource." $global:CertLogin = $AuthContext.AcquireTokenAsync('https://graph.microsoft.com', $AssertionCert) if ($null -eq $global:CertLogin.result.AccessToken) { throw 'We did not retrieve an Oauth access token to continue script. Exiting script...' break } else { $global:headerParameters = @{ Authorization = "$($global:CertLogin.result.AccessTokenType) $($global:CertLogin.result.AccessToken)" } } } else { Write-Verbose "Get-MSGRAPHOauthToken: Certificate: Oauth token already exists from previously running cmdlets." Write-Verbose "Get-MSGRAPHOauthToken: Certificate: Running test to see if Oauth token expired." $OauthExpiryTime = $global:CertLogin.Result.ExpiresOn.UtcDateTime if ($OauthExpiryTime -le $UTCDate) { Write-Verbose "Get-MSGRAPHOauthToken: Certificate: Oauth token expired. Emptying Oauth variable and re-running function." $global:CertLogin = $null Get-MSGRAPHOauthToken ` -AppID $ApplicationID ` -Thumbprint $Thumbprint ` -Tenant $TenantID } else { Write-Verbose "Get-MSGRAPHOauthToken: Certificate: Oauth token from last run is still active." } } } } catch { $Object = [PSCustomObject] @{ Information = "Get-MSGRAPHOauthToken: Error in process of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Get-MSGRAPHOauthToken: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } end { if ($global:AppPass) { Write-Verbose "Get-MSGRAPHOauthToken: ClientSecret: We have succesfully retrieved the Oauth access token. We will continue the script." } elseif ($global:CertLogin) { Write-Verbose "Get-MSGRAPHOauthToken: Certificate: We have succesfully retrieved the Oauth access token. We will continue the script." } else { Write-Verbose "There is no active Oauth token available or it expired. We will empty Oauth token variable and re-run the script." } } } function Search-MSGraphCertByThumbprint { param ( [parameter(mandatory = $true)] [string] $Thumbprint ) begin { try { if ($Thumbprint.length -eq '40') { Write-Verbose "Search-MSGRAPHCertByThumbprint: Thumbprint length is correct. We will continue searching for the cerrtificate in CurrentUser\My and LocalMachine\My." $Certificate = $null } else { throw 'The thumbprint length is incorrect. Make sure you paste the thumbprint correctly. Exiting script...' break } } catch { $Object = [PSCustomObject] @{ Information = "Search-MSGRAPHCertByThumbprint: Error in begin of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Search-MSGRAPHCertByThumbprint: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } process { try { Write-Verbose "Search-MSGRAPHCertByThumbprint: Starting search in CurrentUser\my." $Certificate = Get-Item Cert:\CurrentUser\My\$Thumbprint -ErrorAction SilentlyContinue if ($null -eq $Certificate) { Write-Verbose "Search-MSGRAPHCertByThumbprint: Certificate not found in CurrentUser. Continuing in LocalMachine\my." $Certificate = Get-Item Cert:\localMachine\My\$Thumbprint -ErrorAction SilentlyContinue } if ($null -eq $Certificate) { throw "We did not find a thumbprint under: $Thumbprint. Exiting script..." break } } catch { $Object = [PSCustomObject] @{ Information = "Search-MSGRAPHCertByThumbprint: Error in process of function." ErrorMessage = "$($_.Exception.Message)" } $global:ErrorList.Add($Object) Write-Warning 'Search-MSGRAPHCertByThumbprint: To see if there are more errors please run: $global:ErrorList.' throw $_.Exception.Message break } } end { Write-Verbose "Search-MSGRAPHCertByThumbprint: Certificate has been found. Returning Certificate." Return $Certificate } } |