Calling Graph API with powershell or batch - powershell

In trying to design a simplified script for use with the office 365 graph API I can't seem to find any way to call it from a simplified outset.
For the use that I have intended for it I really don't want to take the time to build and compile an actual program when everything else can be done from powershell or a batch script.
In specific, I really only want to be able to call the graph API for a list of groups and store the result (in an array or text file). Is it possible to call the graph API from powershell or command line and if so, how?

In specific, I really only want to be able to call the graph API for a list of groups and store the result (in an array or text file).
If you just need to export a list of groups. I suggest you using the Azure Active Directory PowerShell.
$msolcred = get-credential
connect-msolservice -credential $msolcred
Get-MsolGroup | Out-File C:\Workbench\temp\tests\export.txt
Is it possible to call the graph API from powershell or command line and if so, how?
Yes, it is possible, to call the REST API:
First, you need to Obtaining an Access Token
Then, use the Invoke-RestMethod to call Graph API.
Invoke-RestMethod -Uri $uri -Headers #{Authorization = "Bearer {your_access_token}"}

You can use the PSMSGRAPH module for this. Can be download from the gallery
You must register an application in Azure to authenticate and delegate the necessary right to your app. You can do it at the appreg portal
Once this is done you just need to auth and run your request.
When running the code you will have to provide a credential to authorize.
$username = 'entertheappidhere'
$password = 'entertheapppaswordhere' | ConvertTo-SecureString -AsPlainText -Force
$ClientCredential = New-Object -TypeName
System.Management.Automation.PSCredential($username,$password)
$GraphAppParams = #{}
$GraphAppParams.Add('Name','Office365TenantMigration')
$GraphAppParams.Add('ClientCredential',$ClientCredential)
$GraphAppParams.Add('RedirectUri','https://localhost/')
$GraphAppParams.Add('Tenant','yourtenant.onmicrosoft.com')
$GraphApp = New-GraphApplication #GraphAppParams
# This will prompt you to log in with your O365/Azure credentials.
$AuthCode = $GraphApp | Get-GraphOauthAuthorizationCode
$GraphAccessToken = $AuthCode | Get-GraphOauthAccessToken -Resource 'https://graph.microsoft.com/'
$GraphAccessToken | Export-GraphOAuthAccessToken -Path 'f:\O365Report\AccessToken.XML'
$GraphAccessToken = Import-GraphOAuthAccessToken -Path 'f:\O365Report\AccessToken.XML'
$GraphAccessToken | Update-GraphOAuthAccessToken -Force
### Run the query
Invoke-GraphRequest -Uri "https://graph.microsoft.com/v1.0/groups"-Method GET -AccessToken $GraphAccessToken

Related

Run application insights query from powershell module

With the AZ Cli I can run the following to query application insight instances:
az monitor app-insights query
There doesn't appear to be a direct equivalent in the azure powershell module. I've seen suggestions that you should use the REST API for application insights, but that requires an API key.
I do not have an API key for each of my (many) application insights' and do not want to have to create and store them so I can query application insights - the reason for not being able to use the Az Cli in my script is I want to run my script as a function app and the az cli isn't supported in function apps.
Is there an alternative way to query AI from powershell that I'm missing?
At the moment, Azure PowerShell just provides the module to manage Azure application insight resource. For more details, please refer to here. So if you want to query application insight with PowerShell, we need to use rest API. Besides, if you do not want to access it with API key, you can do that with AD token. For more details, please refer to here
For example
If you want to Azure AD auth to access Azure application insights API, please refer to the following steps
Register Azure AD application in your tenant
Configure API permissions
Create a client secret for the application
Configure assign contributor to the AD application in your subscription
Script
$appKey=""
$appId=""
$resource="https://api5.applicationinsights.io"
$secpasswd = ConvertTo-SecureString $appKey -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($appId, $secpasswd)
Connect-AzAccount -ServicePrincipal -Tenant "hanxia.onmicrosoft.com" -Credential $mycreds
$res=Get-AzAccessToken -ResourceUrl $resource
$headers=#{"Authorization"="Bearer "+$res.Token}
$body=#{"timespan"="P7D"; "query"="requests| summarize totalCount=sum(itemCount) by bin(timestamp, 30m)"}| ConvertTo-Json
Invoke-RestMethod 'https://api.applicationinsights.io/v1/apps/bd7cacd8-9607-4b53-b57b-995255292f36/query' -Method 'POST' -Headers $headers -Body $body -ContentType "application/json"
Given you have $appInsResourceGroupName and $appInsName pointing to your Application Insights instance.
$component = Get-AzApplicationInsights -ResourceGroupName $appInsResourceGroupName -Name $appInsName
$apiKey = New-AzApplicationInsightsApiKey -ApplicationInsightsComponent $component -Permissions ReadTelemetry -Description "Collector"
$query = "requests | limit 5"
(Invoke-WebRequest -Method POST -Uri https://api.applicationinsights.io/v1/apps/$($component.AppId)/query -ContentType application/json -Body $('{"query":"' + $query + '"}') -Headers #{"X-Api-Key"=$apiKey.ApiKey}).Content
to clean up / remove unused API keys
Get-AzApplicationInsightsApiKey -ApplicationInsightsComponent $component | ?{$_.Description -eq "Collector"} | %{Remove-AzApplicationInsightsApiKey -ApplicationInsightsComponent $component -ApiKeyId $_.Id}
if you're using any domestic clouds you need to account for that; e.g. for China you need to change the URL to api.applicationinsights.azure.cn

Check Groupmembership or jobtitle of Logged On User withouth calling azuread (Get-AzureADUserMembership)

I am building a script with a colleague. This script will show a popup.
We want this popup only to be shown to a certain group of users (teachers and not students). So we want to check group membership of a user. Since this script will be installed on the computer locally and we would not like to install azuread cmdlets on all our computers and also not pass azure ad credentials to the script.
So we where wondering if their is azure-ad info about group membership stored on the computers locally. And also if we can acces it via powershell? (if we could get jobtitle of user that would also be helpfull)
Other ideas are also welcome.
The information related user that you are looking for less likely to be stored locally.
So to meet your requirement, you will have to have some means to communicate with the Azure AD. Your requirement was not to make use of any additional libraries and by using PowerShell.
Graph API can come handy.
To prevent user intervention, you can use App only Graph permission for the App.
You can refer this article to know more App registration, client secret & Application permission :
https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
https://learn.microsoft.com/en-us/graph/notifications-integration-app-registration
You consume the graph endpoint from PowerShell and acquire the necessary details of the logged user from the Azure AD without a necessity of external libraries.
#Acquiring the graph token
$web="https://login.microsoftonline.com/<TENANT ID>/oauth2/v2.0/token"
$body = "client_id=<CLIENT ID>&scope=https://graph.microsoft.com/.default&client_secret=<CLIENTSECRET>&grant_type=client_credentials"
$response = Invoke-WebRequest $web -Body $body -Method Post
$token = ($response | ConvertFrom-Json).access_token
#Getting the logged username that will be used in the graph api
$upn = $env:USERNAME + "#" + $env:USERDNSDOMAIN
#building the authorization header
$header = #{"Authorization" = " Bearer $token"}
#gettting the user details
$content = Invoke-WebRequest "https://graph.microsoft.com/v1.0/users/$upn" -Headers $header -Method Get
$details = $content.Content | ConvertFrom-Json
#getting the group membership
$content = Invoke-WebRequest "https://graph.microsoft.com/v1.0/users/$upn/memberof" -Headers $header -Method Get
$groupdetails = ($content.Content | ConvertFrom-Json).value

Using Powershell to get Azure AD Token (jwt)

I am trying to get a jwt token from AAD using Powershell using Username/Password authentication.
I am writing a powershell script that will to call an API using a bearer token. What I have works if I copy & paste the token from an SPA that uses the API. I am looking for a way to retrieve the token from my powershell.
This looks really promising: https://github.com/Azure-Samples/active-directory-dotnet-native-headless/blob/master/TodoListClient/Program.cs
I feel like I'm smacking my head against a wall trying to create a 'UserPasswordCredential' object. Any clues to how I can do this would be super-helpful.
I have Add-Type-ed:
- Microsoft.IdentityModel.Clients.ActiveDirectory.dll
- Microsoft.IdentityModel.Clients.ActiveDirectory.platform.dll (adds nothing?)
- Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
- Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
The docs page for 'UserPasswordCredential' :
https://learn.microsoft.com/en-us/dotnet/api/microsoft.identitymodel.clients.activedirectory.userpasswordcredential
It should be in one of the first two dlls
This, under 'Constraints & Limitations', makes me think it may not actually be possible from powershell:
http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
Looking at the code below, the first acquire token succeeds, the second fails - possibly/probably because $cred is a UserCredential not a UserPasswordCredential.
Is is possible to do this with powershell?
Finally, on a totally different track, how do I find the values for redirectUri and resourceAppIdURI that my application needs? When I look in the AAD console, and browser to my Enterprise Application, I can find the AppId (which I can use as $clientId).
I'm not sure the redirectUri is strictly necessary for me as all I really want is the token, but I can have a good guess at what it should be.
When I try to call the first AquireToken method (without $cred) using my app details, it fails with this message:
Exception calling "AcquireToken" with "4" argument(s): "AADSTS50001: The application named https://myappwithapi/Login was not found in the tenant named me.onmicrosoft.com.
Is it possible for me to find the require value for resourceAppIdURI by looking in my azure portal?
'https://myappwithapi/Login' is from my azure portal > enterprise apps > [app' > properties > HomepageUrl
code:
#setup
$TenantName = "mme.onmicrosoft.com"
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Microsoft
$clientId = "03faf8db-..........................." #
$username = "me#me.onmicrosoft.com"
$password = Read-Host -AsSecureString -Prompt "Enter Password"
# add dlls
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
$adalplatform = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.platform.dll"
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalplatform) | Out-Null
#prep request
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Microsoft
$resourceAppIdURI = "https://graph.windows.net"
$authority = "https://login.windows.net/$TenantName"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
# Get Token prompting for creds
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Always")
$authResult
# Get the cred
$cred = New-Object -TypeName 'Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential' -ArgumentList $username, $password
#$cred = New-Object -TypeName 'Microsoft.IdentityModel.Clients.ActiveDirectory.UserPassCredential' -ArgumentList $username, $password
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $cred)
$authResult
This post has more the one question in it.
Your base use case 'Using Powershell to get Azure AD Token (jwt)' is a common one and there are several samples and pre-built examples to leverage. For example:
https://github.com/pcgeek86/AzureADToken
A PowerShell module that allows you to get a JSON Web Token (JWT) from Azure Active Directory (AAD).
https://gallery.technet.microsoft.com/Get-Azure-AD-Bearer-Token-37f3be03
This script acquires a bearer token that can be used to authenticate to the Azure Resource Manager API with tools such as Postman. It uses the Active Directory Authentication Library that is installed with the Azure SDK.
See if those two resources resolves your use base line use case.
As for this...
"Is it possible for me to find the require value for resourceAppIdURI by looking in my azure portal?"
You can do this via a remote PowerShell logon to AzureAD. Install the AAD PowerShell module.
https://learn.microsoft.com/en-us/powershell/azure/overview?view=azurermps-5.1.1
https://msdn.microsoft.com/en-us/library/dn135248(v=nav.70).aspx
Download and install MSOL. Sign in with the MSOL
https://www.microsoft.com/en-US/download/details.aspx?id=39267
The Microsoft Online Services Sign-In Assistant provides end user sign-in capabilities
and use the built-in cmdlets to pull your information from your organization settings, and or hit the MSGraph API and query.
https://learn.microsoft.com/en-us/powershell/azure/active-directory/install-adv2?view=azureadps-2.0
You can use the Azure Active Directory PowerShell Module Version for Graph for Azure AD administrative tasks
As for this one:
"how do I find the values for redirectUri and resourceAppIdURI that my application needs?"
This is in your app registration section of your portal. The developer team provide the redir uri not Azure. It's part of the registration process all else is generated by Azure App Reg process.
The app registration process is here and of course you are someone else had to register this app in AzureAD, and thus can retrieve it at any time.:
https://blogs.msdn.microsoft.com/onenotedev/2015/04/30/register-your-application-in-azure-ad
Any registered apps and their details can be retrieved using...
Get-AzureADApplication
Get-AzureADApplication | Select -Property *
(Get-AzureADApplication).ReplyUrls
Get-AzureADApplication | Select -Property AppID, DisplayName,ReplyUrls
https://learn.microsoft.com/en-us/powershell/module/azuread/get-azureadapplication?view=azureadps-2.0

How can I authenticate to AAD and call the Graph API as a Daemon Application with PowerShell?

I am trying to do some very quick tests on Azure Active Directory, and I want to use a Daemon Application to access the Graph API without needing a user present to authenticate. I want to verify that my application registration can successfully authenticate to AAD, that my client secret is valid, and make calls to the AAD Graph API.
I have registered a "Web App/API" in my directory already, and I have set it up to have the appropriate permissions to call the AAD Graph API in the App Only Context. I have also generated an application key/certificate for my app so that I can authenticate as a confidential client.
I want to take a look at my AAD Token, and the output from the Graph API after my call. How can I use PowerShell to quickly accomplish this?
This question is very similar to this one where create a PowerShell script to authenticate as a Native Client Application. However, in this situation, there are some subtle and important differences because you want to authenticate as a confidential client. Specifically, we need to create a Client Credential so that we can authenticate without a user as a Daemon Application.
First you need to download and save the .NET dlls for ADAL. The download link can be found on Nuget.
Note: We specifically use ADAL v2 here.
You can extract the contents of the .nupkg with a File Extractor like
7z, WinZip, etc...
Extract the contents from \lib\net45\ and copy them into your working directory. I put the files in their own "ADAL" folder, to keep it separate.
Then you should be able to create a new PowerShell script with the following:
# Load ADAL
Add-Type -Path ".\ADAL\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
# Output Token and Response from AAD Graph API
$accessToken = ".\Token.txt"
$output = ".\Output.json"
# Application and Tenant Configuration
$clientId = "<AppIDGUID>"
$tenantId = "<TenantID>"
$resourceId = "https://graph.windows.net"
$login = "https://login.microsoftonline.com"
# Create Client Credential Using App Key
$secret = "<AppKey>"
# Create Client Credential Using Certificate
#$certFile = "<PFXFilePath>"
#$certFilePassword = "<CertPassword>"
#$secret = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate -ArgumentList $certFile,$certFilePassword
# Get an Access Token with ADAL
$clientCredential = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential($clientId,$secret)
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("{0}/{1}" -f $login,$tenantId)
$authenticationResult = $authContext.AcquireToken($resourceId, $clientcredential)
($token = $authenticationResult.AccessToken) | Out-File $accessToken
# Call the AAD Graph API
$headers = #{
"Authorization" = ("Bearer {0}" -f $token);
"Content-Type" = "application/json";
}
Invoke-RestMethod -Method Get -Uri ("{0}/{1}/users?api-version=1.6" -f $resourceId,$tenantId) -Headers $headers -OutFile $output
Note: You will need to update the App ID, Tenant ID, and your App Secret information in this script. If you use a certificate to authenticate, simply comment out the code that uses the App Key, and un-comment the code which uses the certificate. I have also pre-configured the AAD Graph API call to return the users in my tenant, but you can change this REST call to whatever you want.
After you successfully run the script, you should get 2 new files in your working directory: A text file that contains your encoded JSON access token, which can be base64 decoded on sites like this, and a JSON file with the response from the AAD Graph API.
Let me know if this helps!

access sharepoint REST api using powershell with windows authentication

I have a sharepoint 2013 server, which I can log into using Windows Authentication via a web-browser. When I have logged on using my browser, if I then - using that same browser - browse to http://mysharepointserver/_api/web I get some useful XML.
However, I want to write a powershell script that uses this XML. To that end, following the suggestions from this page:
How to make an authenticated web request in Powershell?
I wrote the following code:
$PWord = ConvertTo-SecureString –String "MyAwesomePassword" –AsPlainText -Force
$creds = New-Object System.Net.NetworkCredential("MyUserName",$PWord,"TheDomain")
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = $creds
$url = "http://mysharepointserver/_api/web"
$output = $webclient.DownloadString($url)
echo $output
However, when I run this code, I get the error message:
Exception calling "DownloadString" with "1" argument(s): "The remote server returned an error: (403) Forbidden."
Even though I can access the same URL using a web-browser, if I type in the (same) credentials using the Windows login dialog that pops up for authentication purposes.
Does anyone know if it is possible to do this using Powershell?
thanks heaps all
Why aren't you using the default CMDlets that come with Powershell (unless using PS2 or lower)?
Invoke-Webrequest and Invoke-Restmethod both support the -credential switch which can be used to authenticate against the webserver.
You can also use Get-credential to store your credentials (though you can't get yhem from a file or string that way, at least not the password)
Script (in pseudo code and since i'm on my phone no code tags) would look like this :
Invoke-Restmethod -uri 'http://bla/api' -credential (get-credential)