MSGraphAPI.ps1
Function Write-GraphLog { Param ( $Message, $Exception, [switch]$Verbose ) $Output = "$(Get-Date) $Message" if($Exception -ne $null) { $ErrorJSON = '' try { $ErrorJSON = $Exception.ErrorDetails.Message | ConvertFrom-Json -ErrorAction Continue } catch { } $ErrorMessage = '' if(-not [string]::IsNullOrEmpty($ErrorJSON)) { $ErrorJSON = "`nError JSON Information:`n" + ` "Error: $($ErrorJSON.Error)`n" + ` "Error Description: $($ErrorJSON.Error_Description)`n" + ` "Error Codes: $($ErrorJSON.Error_Codes)`n" + ` "Error Timestamp: $($ErrorJSON.Timestamp)`n" + ` "Trace Id: $($ErrorJSON.Trace_Id)`n" + ` "Correlation Id: $($ErrorJSON.Correlation_Id)" } $Output = $Output + @" ERROR Details: Script Name: $($Exception.InvocationInfo.ScriptName) Error Line Number: $($Exception.InvocationInfo.ScriptLineNumber) Error Line: $($Exception.InvocationInfo.Line.Trim()) Error Message: $($Exception.Exception)$($ErrorJSON) "@ } if($Exception -ne $null) { Write-Error $Output } elseif ($Verbose -eq $true) { Write-Verbose $Output } else { Write-Output $Output } } Function Get-GraphAuthenticationToken { <# .SYNOPSIS Used to get the authentication token to Microsoft Graph .DESCRIPTION Creates an OAuth 2.0 token through https://login.microsoftonline.com. If silent is not used, it will prompt you for credentials. .EXAMPLE $secpasswd = ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force $mycreds = New-Object System.Management.Automation.PSCredential ('USER@TENANT', $secpasswd) $GraphParams = @{ 'TenantName' = 'TENANT' 'Credential' = $mycreds 'clientid' = 'CLIENTGUID' } Get-GraphAuthenticationToken @GraphParams .PARAMETER TenantName The name of your tenant .PARAMETER Credential Only used with the Silent switch. Your credential object. Can be created with the code: $secpasswd = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force $mycreds = New-Object System.Management.Automation.PSCredential ('user@tenant', $secpasswd) .PARAMETER clientid Client ID of your Azure Application .PARAMETER redirectUri Redirect URI of your Azure Application .NOTES AUTHOR: Ryan Ephgrave LASTEDIT: 12/14/2016 19:09:06 .LINK https://github.com/Ryan2065/MSGraphCmdlets/wiki/Getting-Started #> Param ( [Parameter(Position=0, Mandatory=$true)][string]$TenantName, [Parameter(Position=1, Mandatory=$true)][pscredential]$Credential, [Parameter(Position=2, Mandatory=$true)][guid]$clientid, [Parameter(Position=3, Mandatory=$true)][string]$redirectUri, [Parameter(Position=4, Mandatory=$false)][string]$scope = 'openid' ) try { $username = $Credential.UserName $password = $Credential.Password $Marshal = [System.Runtime.InteropServices.Marshal] $Bstr = $Marshal::SecureStringToBSTR($Password) $Password = $Marshal::PtrToStringAuto($Bstr) $Marshal::ZeroFreeBSTR($Bstr) } catch { Write-GraphLog 'Error retrieving password from credential object!' $_ break } $resourceAppIdURI = "https://graph.microsoft.com" #$PayLoad = "resource=https://graph.microsoft.com/&client_id=$($clientId)&client_secret=$($clientsecret)&grant_type=password&username=$($Username)&scope=$($scope)&password=$($Password)" $PayLoad = "resource=https://graph.microsoft.com/&client_id=$($clientId)&grant_type=password&username=$($Username)&scope=$($scope)&password=$($Password)" $response = '' try { Write-GraphLog 'Trying to get token...' -Verbose $Response = Invoke-WebRequest -Uri "https://login.microsoftonline.com/Common/oauth2/token" -Method POST -Body $PayLoad Write-GraphLog 'Successfully received token!' -Verbose } catch { $ExceptionMessage = $_.ErrorDetails.Message | ConvertFrom-Json if($ExceptionMessage.Error -eq 'invalid_grant') { $ErrorMessage = "Invalid grant errors are generally caused by the application not having permissions in your environment. " + ` "Please go to the link below and sign in as an Azure AD Domain Admin. You will need to give this application permissions in your environment. " + ` "Visit the wiki on GitHub for more information. Wiki Page: https://github.com/Ryan2065/MSGraphCmdlets/wiki/Getting-Started`n" + ` "URL for permissions:`n https://login.microsoftonline.com/$($TenantName)/oauth2/authorize?resource=https://graph.microsoft.com&client_id=$($clientid)&response_type=code&haschrome=1&redirect_uri=$($redirectUri)" Write-GraphLog -Message $ErrorMessage -Exception $_ break } } $ResponseJSON = $Response | ConvertFrom-Json $GraphAPIAuthenticationHeader = $null $GraphAPIAuthenticationHeader = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]" $GraphAPIAuthenticationHeader.Add("Authorization", "Bearer " + $ResponseJSON.access_token) $Global:GraphAuthenticationHash = @{ 'Parameters' = @{ 'TenantName' = $TenantName 'Credential' = $Credential 'clientid' = $clientid 'redirecturi' = $redirectUri } 'Token' = $ResponseJSON.access_token 'Header' = $GraphAPIAuthenticationHeader } } Function Invoke-GraphMethod { Param( $Version = 'v1.0', $query, $filter, $Class, $scope, $method = 'Get', $body, $ContentType ) try { if ($null -ne $Global:GraphAuthenticationHash.Parameters['TenantName']) { $Parameters = $Global:GraphAuthenticationHash['Parameters'] Get-GraphAuthenticationToken @Parameters -scope $scope } } catch { Write-Error -Exception $_ } $uri = "https://graph.microsoft.com/$($version)/$($query)" if(-not [string]::IsNullOrEmpty($Filter)) { $uri = $uri + "&`$filter=$($Filter)" } $RestParams = @{ 'Method' = $method } if($null -ne $body) { $RestParams['Body'] = $body } if($null -ne $ContentType) { $RestParams['ContentType'] = $ContentType } try { $returned = Invoke-RestMethod -Uri $uri -Headers $Global:GraphAuthenticationHash['Header'] @RestParams Write-GraphLog -Message $returned -Verbose } catch { Write-GraphLog -Exception $_ } if($null -ne $returned) { if(($null -ne $returned."@odata.type") -and ($null -eq $returned.Value)) { try { $type = ($returned."@odata.type").split('.') $type = $type[$type.count - 1] $type = "Graph$($type)_$(($Version.split('.'))[0])" Get-GraphClass -Class $type -object $returned } catch { $returned } } $returnedvalue = $returned.value foreach($instance in $returnedvalue) { if(-not [string]::IsNullOrEmpty($Class)) { Get-GraphClass -Class $Class -object $instance } elseif($instance."@odata.type" -ne $null) { try { $type = ($instance."@odata.type").split('.') $type = $type[$type.count - 1] $type = "Graph$($type)_$(($Version.split('.'))[0])" Get-GraphClass -Class $type -object $instance } catch { $instance } } else { $instance } } } } Function Get-GraphMetadata { param( $Version = 'v1.0' ) (Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/$($Version)/`$metadata").Edmx.DataServices.Schema } Function Get-GraphClass { param( $object, $Class ) try { $tempObject = New-Object "$Class" $tempObjectProperties = ($tempObject | Get-Member -MemberType Property).Name $psObjectProperties = ($Object | Get-Member -MemberType NoteProperty).Name foreach($property in $tempObjectProperties) { if($psObjectProperties -contains $property) { $tempObject."$property" = $object."$property" } } return $tempObject } catch { throw $_ } } Import-Module "$PSScriptRoot\User.ps1" Import-Module "$PSScriptRoot\Classes_v1.ps1" |