SharePoint rara vez vive aislado. El ERP quiere dejar facturas en una biblioteca, una aplicación web necesita leer una lista, el equipo de TI tiene que crear veinte sitios con la misma configuración. Hacerlo a mano es lento y propenso a errores; hacerlo con código, cuestión de minutos. En el libro de SharePoint dedicamos un capítulo a la integración con Microsoft 365 y Azure; aquí tienes una introducción práctica a las dos herramientas más útiles.
Graph, PnP PowerShell y la API REST de SharePoint
| Herramienta | Qué es | Úsala para |
|---|---|---|
| Microsoft Graph | La API unificada de Microsoft 365: sitios, listas, archivos, usuarios, Teams, correo… | Integrar SharePoint con otras aplicaciones |
| PnP PowerShell | Módulo de PowerShell de la comunidad con cientos de comandos para SharePoint y Microsoft 365 | Administración, scripts y tareas repetitivas |
| API REST de SharePoint | La API propia de SharePoint (/_api/) | Funciones específicas que Graph todavía no cubre, y desde SPFx |
Requisito: registrar una aplicación en Entra ID
Cualquier script o aplicación que acceda a Microsoft 365 necesita una identidad: una aplicación registrada en Microsoft Entra ID (antes Azure Active Directory) con los permisos que vaya a usar. Hay dos modelos:
- Delegado: la aplicación actúa en nombre de un usuario que inicia sesión, y solo puede hacer lo que ese usuario puede hacer. Ideal para scripts que ejecuta un administrador.
- Solo aplicación (app-only): la aplicación actúa por sí misma, sin usuario, por ejemplo en un proceso nocturno. Requiere especial cuidado con los permisos.
Sites.FullControl.All para procesos que solo tocan un sitio.
Con el permiso Sites.Selected puedes dar acceso a una aplicación únicamente a los sitios que
necesita.
Microsoft Graph: leer y crear elementos de una lista
Estas son las llamadas para trabajar con la lista Solicitudes de compra del sitio de Compras.
Todas llevan la cabecera Authorization: Bearer <token>:
# 1. Obtener el id del sitio a partir de su URL
GET https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/compras
# 2. Listar los elementos con sus columnas (la lista se puede indicar por su id o por su nombre)
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/Solicitudes%20de%20compra/items?expand=fields(select=Title,Estado,Importe)
# 3. Crear un elemento
POST https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items
Content-Type: application/json
{
"fields": {
"Title": "Monitor 27 pulgadas",
"Importe": 210000
}
}
Las columnas se identifican por su nombre interno, que puede diferir del nombre visible (por ejemplo, si la columna se creó con tildes o espacios). Lo ves en la URL de la configuración de la columna.
El mismo flujo en Python
import os
import msal
import requests
TENANT_ID = os.environ["TENANT_ID"]
CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"] # nunca en el código
app = msal.ConfidentialClientApplication(
CLIENT_ID,
authority=f"https://login.microsoftonline.com/{TENANT_ID}",
client_credential=CLIENT_SECRET,
)
token = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
cabeceras = {"Authorization": f"Bearer {token['access_token']}"}
GRAPH = "https://graph.microsoft.com/v1.0"
sitio = requests.get(f"{GRAPH}/sites/contoso.sharepoint.com:/sites/compras",
headers=cabeceras, timeout=30).json()
items = requests.get(
f"{GRAPH}/sites/{sitio['id']}/lists/Solicitudes de compra/items",
params={"expand": "fields(select=Title,Estado,Importe)"},
headers=cabeceras, timeout=30,
).json()
for item in items["value"]:
campos = item["fields"]
print(campos["Title"], campos.get("Estado"), campos.get("Importe"))
Con muchos elementos, Graph devuelve los resultados por páginas: si la respuesta incluye
@odata.nextLink, hay que seguir pidiendo esa URL hasta que deje de aparecer.
PnP PowerShell: administración desde la terminal
PnP PowerShell requiere PowerShell 7 y, desde 2024, una aplicación de Entra ID propia para iniciar sesión. El propio módulo incluye un comando para crearla:
# Instalación (una vez)
Install-Module PnP.PowerShell -Scope CurrentUser
# Registrar la aplicación para el inicio de sesión interactivo (una vez, como administrador)
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP Scripts" -Tenant "contoso.onmicrosoft.com" -Interactive
# Conectarse a un sitio con el ClientId de la aplicación registrada
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/compras" -Interactive -ClientId "00000000-0000-0000-0000-000000000000"
# Ver las listas y bibliotecas del sitio con su número de elementos
Get-PnPList | Select-Object Title, ItemCount
# Crear un elemento
Add-PnPListItem -List "Solicitudes de compra" -Values @{ Title = "Monitor 27 pulgadas"; Importe = 210000 }
# Exportar la lista a CSV
Get-PnPListItem -List "Solicitudes de compra" -PageSize 500 |
ForEach-Object { [pscustomobject]@{ Titulo = $_["Title"]; Estado = $_["Estado"]; Importe = $_["Importe"] } } |
Export-Csv -Path "solicitudes.csv" -NoTypeInformation -Encoding utf8
# Crear un sitio de comunicación nuevo
New-PnPSite -Type CommunicationSite -Title "Calidad" -Url "https://contoso.sharepoint.com/sites/calidad"
El potencial real aparece al combinar comandos: crear veinte sitios de proyecto desde un CSV, aplicar la misma plantilla a todos, o revisar los permisos de toda la organización (lo vemos en permisos en SharePoint).
Buenas prácticas
- Mínimo privilegio: pide solo los permisos que el script necesita y, si puedes, limítalo a sitios concretos.
- Credenciales fuera del código: variables de entorno, Azure Key Vault o certificados, nunca un secreto escrito en el script.
- Prueba en un sitio de pruebas antes de ejecutar un script masivo en producción.
- Respeta la limitación de solicitudes: si Microsoft 365 responde con el código 429,
espera el tiempo que indica la cabecera
Retry-Afterantes de reintentar. - Registra lo que hace cada script: qué cambió, dónde y cuándo.
SharePoint conectado con todo Microsoft 365
El libro de SharePoint dedica un capítulo a la integración con Microsoft 365 y Azure, incluyendo Teams, OneDrive y Power Apps.
Comprar en Amazon