Trabajar con listas de Microsoft mediante el SDK de Microsoft Graph PowerShell
Cree, lea, actualice y elimine elementos en listas de Microsoft con PowerShell
Microsoft Lists es una aplicación popular para organizar datos personales y compartidos en tablas. Las listas personales se almacenan en OneDrive para la Empresa, mientras que las listas compartidas se guardan en un sitio de SharePoint Online. Muchos scripts de PowerShell dependen de entradas como un archivo CSV. Una ventaja importante de usar listas en lugar de archivos CSV es que es más fácil para los usuarios mantener los datos utilizando los elementos de la GUI disponibles para formatear y presentar datos en listas, lo cual es una de las razones por las que elegí usar una lista para guardar detalles de dominios defectuosos y spammers para generar actualizaciones automáticas de la lista de bloqueo de correo electrónico de mi inquilino. Otra ventaja es que las listas admiten características de Microsoft 365, como las políticas de retención.
Por otro lado, los archivos CSV son muy fáciles de manejar en PowerShell y los desarrolladores están muy acostumbrados a importar datos de un CSV a una matriz, procesar los datos y exportar los resultados a un archivo CSV. La familiaridad es un obstáculo difícil de superar. Este artículo intenta ampliar el conocimiento de la comunidad sobre el uso de listas a través del SDK de Microsoft Graph PowerShell. Después de eso, depende de usted decidir si desea quedarse con los archivos CSV o pasar a las listas.
Definición de terminología de listas de Microsoft
Para empezar, definamos algunos términos:
- Una lista es un objeto en un sitio de SharePoint Online. Las bibliotecas de documentos son una forma especializada de lista. En este contexto, nos referimos a una lista utilizada para almacenar datos que no son documentos.
- Una lista se compone de una colección de elementos.
- Un elemento tiene un conjunto de columnas (campos) que se utilizan para almacenar datos. Algunos campos se agregan automáticamente a una lista debido a la plantilla utilizada para crear la lista. Otros los define el propietario de la lista.
- Además de los campos, cada elemento tiene un conjunto de propiedades.
- SharePoint Online viene con un conjunto estándar de plantillas que se utilizan para crear listas. Si no se especifica una plantilla, SharePoint Online usa la plantilla genericList para crear una lista con una única columna Título. Una vez que se crea una lista, su plantilla no se puede cambiar.
- Las columnas contienen diferentes tipos de información, como booleano, fechahora, persona, texto, número . , personaOrGrupo y moneda.
Mi enfoque habitual es crear nuevas listas a través de la GUI para aprovechar las capacidades de ingresar y presentar datos en listas integradas en SharePoint Online. Siempre es más fácil usar la GUI que crear código para crear una lista personalizada. Si creo una lista mediante programación, invariablemente uso la plantilla de lista más simple (genericList) y la personalizo.
Crear una lista de Microsoft
Como ejemplo, vuelvo a un tema tratado en 2021 en una discusión sobre la creación de contactos organizacionales en los buzones de correo de cuentas nuevas. La idea es que las personas nuevas que se unen a una organización probablemente no sepan cómo comunicarse con unidades como RR.HH. y la mesa de ayuda, por lo que después de unirse, un trabajo en segundo plano crea contactos para unidades y personas importantes en sus buzones de correo. La idea original utiliza un atributo personalizado de Exchange Online para marcar los contactos organizacionales. Esta iteración utiliza una lista de SharePoint.
Lo primero es asegurarse de conectarse a Graph con el permiso correcto. Son necesarias dos cosas. Primero, la cuenta iniciada debe ser propietaria del sitio que aloja la lista. En segundo lugar, la conexión debe tener consentimiento para utilizar los ámbitos Sites.Manage.All y Sites.ReadWrite.All:
Connect-MgGraph -NoWelcome -Scopes Sites.Manage.AllAhora podemos ejecutar el cmdlet Get-MgSite para recuperar los detalles del sitio de destino. La identificación (identificador) es la información más importante porque se pasa a otros cmdlets para crear la lista, recuperar elementos, etc.
$Site = Get-MgSite -Search 'Office 365 News and Views'
$Site | Format-Table DisplayName, Name, Id
DisplayName Name Id
----------- ---- --
Office 365 News and Views Office365News office365itpros.sharepoint.com,bf887032-2619-44a2-a8b0-2b9cfb1cf701,e95c0fd7-42a6-4bd8-808f-e4683035ed6e
Es posible que varios sitios coincidan con los criterios de búsqueda, por lo que es posible que sea necesario realizar algún filtrado adicional para encontrar el sitio de destino correcto.
Una vez identificado el sitio correcto, el siguiente paso es crear una lista. El cmdlet New-MgSiteList crea una lista utilizando una estructura de parámetros de cuerpo que contiene las definiciones de las columnas que se agregarán a la lista y la plantilla que se usará. La plantilla Contactos es una opción adecuada. Como era de esperar, la plantilla contiene muchas de las columnas que le gustaría usar para capturar información sobre un contacto. Todo lo que necesitamos agregar son campos personalizados que no existen en la plantilla.
$NewListParameters = @{
displayName = "Organizational Contacts"
description = "Contacts to add to User Address Book"
columns = @(
@{
name = "Building"
description = "Contact's building"
text = @{ texttype = "plain | richtext" }
}
@{
name = "BusinessUnit"
description = "Contact's business unit"
text = @{ texttype = "plain | richtext" }
}
@{
name = "Description"
description = "Brief description of the contact"
text = @{ texttype = "plain | richtext" }
}
)
list = @{
template = "contacts"
}
}
La sintaxis utilizada para el ejemplo en la documentación de Microsoft no funciona porque no incluye una definición de tipo de columna para cada campo (como texto=@{ }). Cuando se omiten las definiciones, el cmdlet New-MgSiteList falla con:
New-MgSiteList -SiteId $Site.Id -BodyParameter $NewListParameters
New-MgSiteList_Create: Unable to determine type of provided column definition
Status: 400 (BadRequest)
La solución alternativa es utilizar Invoke-MgGraphRequest para ejecutar la solicitud o incluir definiciones precisas de lo que aceptará cada columna. Consulte la documentación en línea para conocer las definiciones de columnas.
$Uri = ("https://graph.microsoft.com/v1.0/sites/{0}/Lists" -f $Site.Id)
$NewList = Invoke-MgGraphRequest -Uri $Uri -Method POST -Body $NewListParameters
El identificador de lista es necesario para agregar elementos. Debido a que la variable $NewList recibió la salida del cmdlet Invoke-MgGraphRequest, el identificador está disponible en $NewList.Id. De lo contrario, los nuevos metadatos de la lista se pueden recuperar con el cmdlet Get-MgSiteList. Después de ejecutar el código siguiente, el identificador de la lista está disponible en $List.Id:
$List = Get-MgSiteList -SiteId $Site.Id -Filter "displayName eq 'Organizational Contacts'"La lista ahora se puede editar para finalizar las columnas. Por ejemplo, la plantilla Contactos agrega una columna de Archivos adjuntos. No necesito esta columna, así que la escondí. Asimismo, no necesito el número de fax ni el teléfono de casa. También moví algunas columnas. La Figura 1 muestra la nueva lista con algunos elementos agregados.
Agregar elementos a una lista de Microsoft
El cmdlet New-MgSiteListItem agrega un nuevo elemento a una lista. La carga útil del nuevo elemento se pasa en una tabla hash con una tabla hash incrustada que contiene los nombres y valores de las columnas. Lo importante aquí es que los nombres de las columnas deben coincidir con la ortografía y mayúsculas de las definidas en la lista.
$NewItemParameters = @{
fields = @{
Title = 'Payroll'
FullName = 'Employee Payroll'
FirstName = 'Employee'
Description = 'Employee Payroll Queries'
WorkPhone = '877-0012'
Company = 'Office 365 for IT Pros'
Email = 'Employee.Payroll@Office365itpros.com'
WorkCity = 'Dallas'
}
}
Para evitar errores en la tabla hash, es útil extraer los nombres de las columnas para compararlas. Esto se hace fácilmente usando el cmdlet Get-MgSiteList. Por ejemplo:
$Fields = Get-MgSiteList -SiteId $Site.Id -ListId $List.Id -ExpandProperty Columns | Select-Object -ExpandProperty Columns | Select-Object DisplayName, NameCon los valores de la tabla hash completos, el cmdlet New-MgSiteListItem puede agregar el elemento a la lista de destino en el sitio de destino:
$NewItem = New-MgSiteListItem -SiteId $site.Id -ListId $List.Id -BodyParameter $NewItemParametersRecuperar elementos de una lista de Microsoft
Sería bueno si el cmdlet Get-MgSiteListItem recuperara elementos sin mucho problema, pero debido a que los campos almacenan información en pares clave-valor, la llamada debe expandir la propiedad de campos y especificar (seleccionar) los nombres de los campos a utilizar. En este ejemplo, verá cómo especificar campos cuando Get-MgSiteListItem recupera todos los elementos de una lista. Para que los campos sean más fáciles de manipular, sus valores se escriben en una lista de PowerShell.
[array]$ListItems = Get-MgSiteListItem -ListId $List.Id -SiteId $Site.Id -ExpandProperty "fields(`$select=id,title,fullname,firstname,workphone,email,workcity,description)" -PageSize 999 -All
$ItemData = [System.Collections.Generic.List[Object]]::new()
ForEach ($Item in $ListItems.fields) {
$FullName = ($Item.AdditionalProperties.FullName)
$ReportLine = [PSCustomObject] @{
Id = $Item.Id
FullName = $FullName
FirstName = $Item.AdditionalProperties.FirstName
LastName = $Item.AdditionalProperties.Title
PhoneNumber = $Item.AdditionalProperties.WorkPhone
Email = $Item.AdditionalProperties.Email
City = $Item.AdditionalProperties.WorkCity
Description = $Item.AdditionalProperties.Description
}
$ItemData.Add($ReportLine)
}
Los detalles de un elemento individual de la lista tienen este aspecto:
Id : 4
FullName : Employee Payroll
FirstName : Employee
LastName : Payroll
PhoneNumber : 877-0012
Email : Employee.Payroll@Office365itpros.com
City : Dallas
Description : Employee Payroll Queries
Eliminar elementos de una lista de Microsoft
Cada elemento tiene un identificador de elemento que comienza en 1 y se incrementa en 1 a medida que los usuarios agregan nuevos elementos a la lista. Si conoce el identificador de un elemento, puede eliminarlo ejecutando el cmdlet Remove-MgSiteListItem. Este ejemplo elimina el elemento con el identificador 2:
Remove-MgSiteListItem -SiteId $Site.Id -ListId $List.Id -ListItemId 2Tenga en cuenta que no se requiere confirmación para eliminar un elemento de una lista. Esto significa que el código para eliminar elementos debe tener cuidado de eliminar los elementos correctos.
Encontrar un elemento con un valor específico en un campo requiere un paso intermedio para extraer los datos sobre los elementos en una matriz y luego filtrarlos según la matriz para encontrar el elemento correcto. Por ejemplo, el código para recuperar elementos creó una matriz (lista) llamada $ItemData. Para buscar y eliminar cualquier elemento con un valor de "Dallas" en la propiedad de la ciudad, podemos hacer esto:
[array]$ItemsToDelete = $ItemData | Where-Object {$_.City -eq "Dallas"}
ForEach ($Id in $ItemsToDelete.Id) {
Write-Host ("Removing item {0}…" -f $Id)
Remove-MgSiteListItem -SiteId $Site.Id -ListId $List.Id -ListItemId $Id
}
Para eliminar todos los elementos de una lista, busque los elementos y luego recorra el conjunto para eliminar cada elemento:
[array]$ListItems = Get-MgSiteListItem -ListId $List.Id -SiteId $Site.Id -All -PageSize 999
ForEach ($Id in $ListItems.Id) {
Write-Host ("Removing item {0}…" -f $Id)
Remove-MgSiteListItem -SiteId $Site.Id -ListId $List.Id -ListItemId $Id
}
A veces es más fácil borrar toda la lista y empezar de nuevo. Esto se puede hacer ejecutando el cmdlet Remove-MgSiteList:
Remove-MgSiteList -SiteId $Site.Id -ListId $List.IdEliminar una lista la coloca en la papelera de reciclaje del sitio. SharePoint Online no eliminará una lista si una etiqueta o política de retención prohíbe su eliminación.
La alternativa PnP
El módulo SharePoint PnP también se puede utilizar para crear y mantener listas de SharePoint Online. Debido a la estrecha afinidad entre PnP y SharePoint, es más fácil trabajar con los cmdlets PnP (aquí se muestra un ejemplo de cómo crear una lista de equipos). La desventaja es que PnP se convierte en un módulo adicional para el mantenimiento de scripts, lo que no será un problema si usas PnP para otros fines.
El siguiente paso es escribir código real
Después de todo eso, debe ser el momento de utilizar la lista de contactos de la organización para crear contactos en los buzones de correo de Exchange Online. Describir cómo hacerlo requiere más espacio del que tengo disponible, así que cubriré el tema en otro artículo.
