Uso de la API de Microsoft Graph con Powershell

La API de Microsoft Graph le brinda la capacidad de interactuar con los servicios de Azure en constante evolución a través de un único punto de conexión: https://graph.microsoft.com. Vamos a conectarnos a Graph con Powershell, OAuth 2.0 y REST.

Registrando tu aplicación

Para interactuar con Graph necesitamos registrar nuestra aplicación. Ir https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade Para empezar. Inicie sesión con su cuenta asociada con su inquilino. Agregue una nueva aplicación e ingrese los siguientes detalles:

  • Nombre > solo dale un nombre
  • Tipo de aplicación > Aplicación web/-API
  • Inicie sesión en Url> No importa, así que buscamos: http://localhost:8000

Luego seleccione su aplicación recién creada y vaya a Permisos requeridos, aquí vamos a agregar el permiso Graph API.

Tendrá que seleccionar un permiso diferente según a lo que desee acceder.

Puede cambiar esto más tarde, así que por ahora hacemos clic en Agregar en la parte superior, seleccionamos Microsoft Graph y en el paso 2 simplemente seleccionamos Acceso de lectura y escritura al perfil de usuario.

El último paso es crear una clave, vaya a Llaves e ingresa un Descripción clave y establezca la duración en Nunca expira.

Cuando haga clic en Guardar, el valor (ClientSecret) se solo se muestra una vezasí que escríbelo hecho cuando se muestre.

Conviértase en un hacker ético que puede piratear sistemas informáticos como piratas informáticos de sombrero negro y protegerlos como expertos en seguridad.

Autenticación y autorización

Para acceder a Graph API necesitamos obtener un código de acceso. Si es nuevo en el trabajo con Rest and Graph API, hay algunas cosas que debe tener en cuenta:

  1. Para obtener un token de acceso, necesita un código de autorización. El código solo es válido por 1 hora, pero mientras su token de actualización sea válido, solo necesita renovarlo cada 90 días.
  2. El token de acceso, que se utiliza en cada solicitud, solo es válido durante 1 hora. Puedes renovarlo con el Refresh Token.
  3. El Refresh Token es válido por 14 días.

Entonces, el primer paso es obtener el código de autenticación. Usamos el siguiente script para esto. Ejecute los scripts con:

GraphAPIGetAuthCode.ps1 -ClientId <clientId> -ClientSecret <clientSecret> -RedirectUrl <redirectUrl>

Almacenará el código de autenticación en un archivo de texto en la ubicación raíz del script. De esta manera podemos acceder fácilmente a él más tarde.

[CmdletBinding()]
PARAM(
	[parameter(ValueFromPipeline=$true,
				ValueFromPipelineByPropertyName=$true,
				Mandatory=$true)]
	[string]$ClientId,

	[parameter(ValueFromPipeline=$true,
				ValueFromPipelineByPropertyName=$true,
				Mandatory=$true)]
	[string]$ClientSecret,

	[parameter(ValueFromPipeline=$true,
				ValueFromPipelineByPropertyName=$true,
				Mandatory=$true)]
	[string]$RedirectUrl
)
BEGIN
{
	$ResourceUrl = "https://graph.microsoft.com"
}
PROCESS
{
	Function Get-AuthCode {
		Add-Type -AssemblyName System.Windows.Forms

		$form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=440;Height=640}
		$web  = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=420;Height=600;Url=($url -f ($Scope -join "%20")) }

		$DocComp  = {
			$Global:uri = $web.Url.AbsoluteUri        
			if ($Global:uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
		}
		$web.ScriptErrorsSuppressed = $true
		$web.Add_DocumentCompleted($DocComp)
		$form.Controls.Add($web)
		$form.Add_Shown({$form.Activate()})
		$form.ShowDialog() | Out-Null

		$queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
		$output = @{}
		foreach($key in $queryOutput.Keys){
			$output["$key"] = $queryOutput[$key]
		}

		$output
	}

	# UrlEncode the ClientID and ClientSecret and URL's for special characters 
	$clientIDEncoded = [System.Web.HttpUtility]::UrlEncode($ClientId)
	$clientSecretEncoded = [System.Web.HttpUtility]::UrlEncode($ClientSecret)
	$redirectUrlEncoded =  [System.Web.HttpUtility]::UrlEncode($RedirectUrl)
	$resourceUrlEncoded = [System.Web.HttpUtility]::UrlEncode($ResourceUrl)
	$scopeEncoded = [System.Web.HttpUtility]::UrlEncode("https://outlook.office.com/user.readwrite.all")

	# Get AuthCode
	$url = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&redirect_uri=$redirectUrlEncoded&client_id=$clientID&resource=$resourceUrlEncoded&prompt=admin_consent&scope=$scopeEncoded"

	Get-AuthCode
	
	# Extract Access token from the returned URI
	$regex = '(?<=code=)(.*)(?=&)'
	$authCode = ($uri | Select-string -pattern $regex).Matches[0].Value

	# Store AuthCode
	Set-Content "$PSScriptRoot\AuthCode.txt" $authCode
}

Gracias a Darren Robinson: https://gist.github.com/darrenjrobinson/b74211f98c507c4acb3cdd81ce205b4f#file-ps2graphapi-ps1

Obtenga el token de acceso y actualización

Con el código de autenticación podemos obtener el token de acceso más importante y el token de actualización que tanto necesitamos.

Debido a que el token de acceso solo tiene una validez de 1 hora, debemos verificar su antigüedad y solicitar uno nuevo con el token de actualización si está vencido.

El siguiente script almacena el token de acceso y actualización en archivos de texto en la ubicación raíz del script.

Siempre puede cambiarlo para almacenarlo solo en variables, pero tenga en cuenta que cuando cierra el shell todo desaparece y debe comenzar de nuevo con el código de autorización.

Los scripts verifican la última hora de modificación de accesstoken.txt, si tiene más de 1 hora, solicitará un nuevo token de acceso con el token de actualización. Si eso falla, solicitará un nuevo código de autorización y comenzará de nuevo.

Uso un archivo config.json para almacenar mi ClientId, ClientSecret y RedirectUrl, de esta manera puede cambiarlo fácilmente.

Configuración.json

{
  "AppId": {
    "ClientId": "fa9d9d34-7a2a-****-****-************",
    "ClientSecret": "J/WDSKLjE+XC9G0+ASDHUen31/***********=",
    "RedirectUrl": "https://localhost:8000",
    "ResourceUrl": "https://graph.microsoft.com"
  }
}

Conectar a gráfico

#----------------------------------------------------------[Declarations]----------------------------------------------------------

#Get the config file
$config = Get-Content $PSScriptRoot"\config.json" -Raw | ConvertFrom-Json

# Add System Web Assembly to encode ClientSecret
Add-Type -AssemblyName System.Web

# Encode ClientSecret
$clientSecretEncoded = [System.Web.HttpUtility]::UrlEncode($config.AppId.ClientSecret) 

# Get the accessToken
If ((Test-Path -Path $PSScriptRoot"\accessToken.txt") -ne $false) {
	$accessToken = Get-Content $PSScriptRoot"\accessToken.txt"
}

#---------------------------------------------------------[Initialisations]--------------------------------------------------------

# Check if the AccessToken is not older then 1 hour
If (($accessToken -eq $null) -or ((get-date) - (get-item $PSScriptRoot"\accessToken.txt").LastWriteTime).TotalHours -gt 1) {

	# Get the refreshToken
	$refreshToken = Get-Content $PSScriptRoot"\refreshToken.txt"

	$clientId = $config.AppId.ClientId
	$clientSecret = $config.AppId.clientSecret
	$redirectUrl = $config.AppId.RedirectUrl
	$resourceUrl = $config.AppId.ResourceUrl
	
	Try {
		$refreshBody = "grant_type=refresh_token&redirect_uri=$redirectUrl&client_id=$clientId&client_secret=$clientSecretEncoded&refresh_token=$refreshToken&resource=$resourceUrl"

		$Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token `
			-Method Post -ContentType "application/x-www-form-urlencoded" `
			-Body $refreshBody `
			-UseBasicParsing
	}
	Catch {
		$webResponse = $_.Exception.Response
	}

	If ($webResponse -ne $null) {
		# Get Authorization code
		GraphAPIGetAuthCode.ps1 -ClientId $clientId -ClientSecret $clientSecret -RedirectUrl $redirectUrl   

		$authCode = get-content $PSScriptRoot"\authCode.txt"
		$body = "grant_type=authorization_code&redirect_uri=$redirectUrl&client_id=$clientId&client_secret=$clientSecretEncoded&code=$authCode&resource=$resourceUrl"

		$Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token `
			-Method Post -ContentType "application/x-www-form-urlencoded" `
			-Body $body `
			-UseBasicParsing
	}

	# Store refreshToken
	Set-Content $PSScriptRoot"\refreshToken.txt" $Authorization.refresh_token

	# Store accessToken
	$accessToken = $Authorization.access_token
	Set-Content $PSScriptRoot"\accessToken.txt" $accessToken
} 

Obtener la fecha real con Invoke-RestMethod de Graph

Una vez hecho todo, podemos interactuar con Graph de la siguiente manera:

Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} `
                  -Uri  https://graph.microsoft.com/v1.0/me `
                  -Method Get

Puedes descargar los guiones aquí: https://github.com/ruudmens/SysAdminScripts/tree/master/Graph

Otros artículos relacionados

¿Qué puedes hacer con eso?

¿Qué puedes hacer con eso?

Pathping es una de las mejores herramientas de resolución de problemas de red integradas en Windows. Le ayuda a encontrar ...
Leer Más
Se acerca OneDrive de 64 bits, ¡pero no lo instales todavía!

Se acerca OneDrive de 64 bits, ¡pero no lo instales todavía!

La función más solicitada en OneDrive Voz de usuario es una versión de 64 bits del cliente OneDrive. Sí, su ...
Leer Más
Cómo arreglar el reinicio y seleccionar el dispositivo de arranque adecuado en Windows 10

Cómo arreglar el reinicio y seleccionar el dispositivo de arranque adecuado en Windows 10

El error Reinicie y seleccione el dispositivo de arranque adecuado puede ocurrir cuando enciende su computadora. Indica que su computadora ...
Leer Más
Error 0xFFFD0000 después de ejecutar la tarea programada de Powershell

Error 0xFFFD0000 después de ejecutar la tarea programada de Powershell

Utilizo muchas tareas programadas de Powershell para hacer mi vida como SysAdmin un poco más fácil. Recientemente, uno de los ...
Leer Más
Eliminar la licencia de Office 365 de un ordenador con PowerShell

Eliminar la licencia de Office 365 de un ordenador con PowerShell

Uno de mis usuarios recibió un aviso en Office 2016 de que necesitaba reactivar su suscripción a Office 365. Después ...
Leer Más
Aplicación Windows Terminal: todo lo que necesita saber

Aplicación Windows Terminal: todo lo que necesita saber

La versión preliminar de la nueva aplicación Windows Terminal ya está disponible. Esta nueva aplicación de línea de comandos se ...
Leer Más

Deja un comentario