OneDrive para la Empresa personalización en el modelo de complemento de SharePoint

El enfoque que se usa para personalizar OneDrive para la Empresa sitios en el nuevo modelo de complementos de SharePoint es diferente de lo que era con el código de plena confianza. En un escenario típico de solución de granja de servidores/código de plena confianza (FTC), los trabajos de temporizador de SharePoint se creaban con el código del modelo de objetos del lado servidor de SharePoint, se implementaban con soluciones de granja de servidores y se administraban en el sitio web de Administración central de SharePoint. En este escenario, SharePoint controla tanto la programación como la ejecución del trabajo del temporizador.

En un escenario de modelo de complemento de SharePoint, los trabajos del temporizador se crean y programan fuera de SharePoint. En este escenario, SharePoint no se encarga ni de la programación ni de la ejecución del trabajo del temporizador.

¿Por qué personalizaría OneDrive para la Empresa sitios?

Hay numerosos aspectos diferentes en la aplicación de la personalización a sitios de OneDrive para la Empresa (OD4B). Sin duda puede personalizar estos sitios, ya que son sitios de SharePoint, pero al mismo tiempo siempre debe tener en cuenta el impacto a corto y largo plazo de la personalización.

Directrices avanzadas

Como regla general, nos gustaría proporcionar las siguientes directrices de alto nivel para personalizar sitios OD4B.

  • Aplicación de personalización de marca mediante temas de Office 365 o motor de temas de sitio de SharePoint
  • Si los motores de tema no son suficientes, puede ajustar algunos valores css mediante la opción CSS alternativa.
  • Evite personalizar sitios OD4B mediante páginas maestras personalizadas, ya que esto provocará costos y desafíos adicionales a largo plazo con futuras actualizaciones.
    • En la mayoría de los casos, puede lograr todos los escenarios comunes de personalización de marca con temas y CSS alternativo, por lo que esto no es realmente ese factor limitante
    • Si decide usar páginas maestras personalizadas, prepárese para aplicar cambios a los sitios cuando se apliquen actualizaciones funcionales importantes a Office 365
  • Puede usar la inserción de JavaScript para modificar u ocultar la funcionalidad en el sitio.
  • Puede usar CSOM para controlar, por ejemplo, la configuración regional o de idioma en los sitios de OD4B (consulte nuevas API).
  • No se recomienda el uso de tipos de contenido y columnas de sitio en sitios OD4B para evitar desafíos con los campos necesarios u otros elementos, lo que podría causar problemas para casos de uso normales con sitios de OD4B.
    • Piense en sitios OD4B como para datos y documentos personales no estructurados. Los sitios de equipo y la colaboración son, a continuación, para los datos y documentos de la empresa, donde sin duda puede usar las directivas y metadatos de administración de la información que desee.

Como resumen, la personalización se admite definitivamente en Office 365 y puede seguir usándolas con sitios de OD4B. Realmente queremos asegurarnos de que tiene en cuenta el impacto a corto y largo plazo de la personalización desde la perspectiva operativa y de mantenimiento. Esto no es realmente específico para SharePoint, sino una regla general para cualquier compilación de solución de TI con cualquier plataforma.

Este es un ejemplo del sitio OD4B, que se ha personalizado con las directrices anteriores. En este caso, el resultado final se ha logrado con la combinación de temas de Office 365, tema del sitio y uso del denominado patrón de inserción de JavaScript.

Vista de un sitio OD4B personalizado finalizado.

Desafíos con la aplicación de personalizaciones del sitio de OneDrive para la Empresa

Empecemos con la definición del reto y lo que estamos intentando solucionar. Técnicamente, cada sitio OneDrive para la Empresa actualmente usa una arquitectura idéntica a la que usaban los sitios personales o mis sitios en la versión de SharePoint 2007 o 2010. Esto significa que técnicamente cada sitio OneDrive para la Empresa es su propia colección de sitios y no tenemos ninguna ubicación centralizada para aplicar personalización de marca ni ninguna otra personalización.

Desafíos con la aplicación de personalizaciones del sitio de OneDrive para la Empresa

La solución clásica para aplicar la configuración necesaria a los sitios de OneDrive para la Empresa (incluidos mis sitios personales) se basaba en la grapada de características en el nivel de granja de servidores. Esto significaba que implementó la solución de granja de servidores en la granja de servidores de SharePoint y usó el marco de características para asociar la característica personalizada que se activará cada vez que se crated un sitio, que luego fue responsable de aplicar las personalizaciones necesarias. Este enfoque similar no funciona en Office 365, ya que requiere la implementación de la solución de granja de servidores y eso es simplemente imposible con Office 365 sitios. Por lo tanto, necesitamos buscar alternativas para aplicar los cambios necesarios a los sitios.

En Office 365 no se genera ningún evento centralizado, al que podríamos adjuntar nuestro código personalizado cuando se crea el sitio OD4B. Esto significa que debemos pensar en soluciones alternativas, lo que es bastante común con los enfoques del modelo de aplicación. No se bloquee en modelos antiguos, piense en cómo lograr el mismo resultado final mediante nuevas API y tecnologías. Desde la perspectiva de los requisitos puros, no importa realmente cómo se aplican las personalizaciones a los sitios, siempre y cuando se apliquen, ya que el requisito empresarial es no usar el estapling de características, se trata de aplicar las personalizaciones necesarias mediante cualquier mecanismo técnico compatible.

Varias opciones para aplicar la personalización

En la práctica, tenemos cuatro mecanismos diferentes para aplicar la personalización centralizada a los sitios de OD4B en el Office 365. También podría considerar la opción manual como la quinta, pero en el caso de tener cientos o miles de sitios OD4B, el uso de opciones manuales no es realmente una opción realista. Estas son las diferentes opciones que tenemos.

  1. Configuración de nivel de conjunto de aplicaciones de Office 365 (temas de Office 365 y otras opciones de configuración)
  2. Elemento de aplicación oculto con contexto de usuario
  3. Crear y aplicar la configuración previamente
  4. Trabajo de temporizador remoto basado en las actualizaciones del perfil de usuario

Cada una de las opciones tiene ventajas y desventajas en ellas y la opción adecuada depende de sus requisitos empresariales detallados. Algunas de las configuraciones que también se pueden aplicar desde el nivel de conjunto de Office 365, pero a menudo se buscan algunas más específicas, por lo que se necesitan personalizaciones reales. Obviamente, todo se reduce a requisitos exactos y análisis de casos empresariales sobre su impacto a corto y largo plazo.

Configuración de nivel de conjunto de aplicaciones de Office 365

Office 365 es mucho más que solo SharePoint, como usted sabe. Puede encontrar más y más servicios adicionales que no se basan ni siquiera en la arquitectura de SharePoint, como Delve, Yammer y muchos servicios próximos. Esto significa que la personalización de marca y la configuración de la empresa no se trata solo de controlar lo que tenemos en los sitios de SharePoint, sino que deberíamos pensar en la experiencia general del usuario final y en cómo proporcionamos configuraciones coherentes entre diferentes servicios.

El ejemplo clásico de estos requisitos empresariales es la personalización de marca y, para ello, ya hemos introducido Office 365 creación de temáticas, que se pueden usar para controlar algún nivel de personalización de marca. También tenemos otras características próximas, que le ayudarán a controlar la gobernanza del sitio y otras configuraciones, desde una ubicación centralizada fuera de la configuración de la colección de sitios, como el próximo Centro de cumplimiento para Office 365, que actualmente aparece en la hoja de ruta de Office 365.

En la imagen siguiente se muestran los diferentes valores de configuración en este momento para el tema de Office 365, que se aplicará a todos los servicios de Office 365.

Muestra el sitio Office 365, que muestra la página de pestaña temas personalizados, titulada Administrar temas personalizados para su organización, Personalizar Office 365 para reflejar la marca de la oganización. La configuración está disponible para logotipo personalizado, dirección URL para un logotipo en el que se puede hacer clic, imagen de fondo, color de énfasis, color de fondo de la barra de navegación, color de texto e iconos y color del icono del menú Aplicación.

Dado que de forma predeterminada Office 365 configuración de tema es para controlar la barra de conjuntos de sitios de OD4B, lo más probable es que use estas opciones junto con otras opciones para asegurarse de que puede proporcionar al menos los elementos de personalización de marca adecuados entre los sitios de OD4B. Tenga en cuenta que, al cambiar por ejemplo Office 365 configuración del tema en Office 365 herramienta de administración, se tarda bastante tiempo en aplicar la configuración para los sitios de OD4B, así que tenga paciencia.

Elemento de aplicación oculto con contexto de usuario

Este es un enfoque en el que se usa la página de aterrizaje centralizada como ubicación para iniciar el proceso de personalización necesario. Esto significa que tendría que tener una ubicación centralizada, como la página principal de la intranet de la empresa, donde los usuarios siempre están aterrizando cuando abren su explorador. Este es un proceso bastante típico con empresas medianas y grandes en las que la página de aterrizaje corporativa se controla mediante la configuración de directiva de grupo en AD. Esto garantizará que los usuarios finales no puedan invalidar la página de bienvenida predeterminada de los exploradores unidos al dominio de la empresa.

Cuando el usuario llegue a la intranet, tendremos un elemento de aplicación oculto en la página, que iniciará el proceso de personalización. En realidad, también puede ser responsable de la creación de todo el sitio de OD4B, ya que normalmente el usuario tendría que visitar el sitio de OD4B una vez, antes de que se inicie el proceso de creación del sitio. El elemento de aplicación oculto realmente hospeda una página de la aplicación hospedada por el proveedor hospedada en Azure. A continuación, esta página es responsable de iniciar el proceso de personalización.

Echemos un vistazo más de cerca al diseño lógico de este enfoque.

Diagrama para mostrar las relaciones. La parte Aplicación del sitio de SharePoint usa la creación de instancias para ir a Aplicaciones hospedadas por proveedor. Las aplicaciones hospedadas por el proveedor usan Agregar mensaje para ir a la cola de almacenamiento. La cola de almacenamiento usa una instancia de para ir a WebJob. WebJob usa Aplicar modificaciones para ir al sitio de OD4B.

  1. Coloque la parte oculta de la aplicación en el sitio centralizado donde aterrizarán los usuarios finales. Normalmente se trata de la página principal de la intranet corporativa.
  2. El elemento de aplicación hospeda una página de la aplicación hospedada por el proveedor, donde en el código del lado servidor iniciamos el proceso de personalización agregando los metadatos necesarios a la cola de Azure Storage. Esto significa que esta página solo recibirá la solicitud de personalización, pero en realidad no aplicará ningún cambio para mantener el tiempo de procesamiento normal.
  3. Esta es la cola de Azure Storage real, que recibirá los mensajes a la cola para su procesamiento. De este modo, podemos controlar el proceso de control de personalización de forma asincrónica para que no importe realmente cuánto tiempo permanecerá el usuario final en la primera página de la intranet. Si el proceso de personalización fuera sincrónico, dependeríamos del usuario final para mantener el explorador abierto en la página principal de intranet hasta que finalice la ejecución de la página. Esto definitivamente no sería óptimo y fue el desafío con el proceso de personalización original de OD4B, que blogged while back.
  4. WebJob se enlaza para seguir la cola de almacenamiento, a la que se llama cuando se coloca un nuevo elemento en la cola de almacenamiento. Este trabajo web recibirá los parámetros y metadatos necesarios del mensaje en cola para acceder a la colección de sitios correcta. WebJob solo usa un token de aplicación y se le han concedido los permisos necesarios para manipular colecciones de sitios en el nivel de inquilino.
  5. Las personalizaciones reales se aplican uno a uno a los sitios de esas personas que visitan la página principal de intranet para iniciar el proceso.

Este es sin duda el proceso más confiable para garantizar que hay configuraciones correctas en los sitios de OD4B. Puede agregar fácilmente lógica de control de versiones de personalización al proceso, que también aplica las actualizaciones necesarias a los sitios de OD4B, cuando se necesita una actualización y el usuario visita la página principal de intranet la próxima vez. Sin embargo, esta opción requiere que tenga esa ubicación centralizada en la que están llegando los usuarios finales.

Si está familiarizado con los modelos de desarrollo clásicos de SharePoint con soluciones de granja de servidores, se trata de un proceso bastante similar al de ejecutar trabajos del temporizador una vez.

Crear y aplicar la configuración previamente

Esta opción se basa en la creación previa de los sitios de OD4B antes de que los usuarios accedan a ellos. Esto se puede lograr mediante el uso de una API relativamente nueva que nos proporciona lejos para crear sitios OD4B para usuarios específicos en proceso por lotes, mediante CSOM o REST. El código necesario se puede iniciar mediante un script de PowerShell o escribiendo código real que llame a las API remotas.

Un administrador usa, antes de crear y personalizar, para crear un sitio OD4B.

  1. El administrador usa las API de creación remota para crear sitios de OD4B para los usuarios y está aplicando las personalizaciones necesarias a los sitios de OD4B como parte del proceso de script.
  2. Los sitios OD4B reales se crean en el Office 365 para usuarios específicos y se asocian a sus perfiles de usuario.

En cierto sentido, esto también es un proceso realmente confiable, pero tendría que administrar nuevas personas y actualizaciones "manualmente", lo que podría significar más trabajo y, a continuación, usar el enfoque de parte oculta de la aplicación. Este es definitivamente un enfoque válido que se puede adoptar y especialmente útil si va a migrar desde alguna otra solución de uso compartido de archivos a la OD4B y quiere evitar la necesidad de que los usuarios finales accedan al sitio de OD4B una vez, antes de que se inicie la creación del sitio real.

Trabajo de temporizador remoto basado en las actualizaciones del perfil de usuario

Este enfoque significa examinar los perfiles de usuario para comprobar a quién se ha creado el sitio OD4B y, a continuación, aplicar los cambios a los sitios según sea necesario. Esto significaría que el trabajo programado se ejecuta fuera de SharePoint, lo que comprobará periódicamente el estado y realizará las personalizaciones necesarias. El trabajo programado podría ejecutarse como un trabajo web en Azure o tan sencillo como el script de PowerShell programado en su propio programador de Windows. Obviamente, la escala de la implementación tiene un gran impacto en la opción de programación elegida.

Un trabajo del temporizador remoto usa, recorrer en bucle las colecciones de sitios, para personalizar cada sitio.

  1. Se inicia una tarea programada que accederá a los perfiles de usuario de los usuarios para comprobar quién tiene aprovisionado el sitio de OD4B.
  2. Los sitios reales se personalizan uno a uno en función de los requisitos empresariales

Una de las principales desventajas de esta opción es que puede haber claramente una situación en la que el usuario pueda acceder a los sitios de OD4B antes de que se hayan aplicado las personalizaciones. Al mismo tiempo, esta opción es un complemento interesante para otras opciones para asegurarse de que los usuarios finales no han cambiado ninguna de las configuraciones necesarias en los sitios o para comprobar que el contenido del sitio OD4B se alinea con las directivas de la empresa.

Personalización mejorada basada en elementos de la aplicación

Esta es una descripción más detallada de las personalizaciones mejoradas basadas en elementos de la aplicación, que parece ser el enfoque típico para aplicar y administrar las personalizaciones necesarias a los sitios de OD4B. El código fuente y los detalles adicionales sobre esta solución están disponibles en Office 365 Guía de patrones y prácticas para desarrolladores.

El diseño lógico real sigue el enfoque de la parte oculta de la aplicación, mencionado anteriormente en esta entrada de blog. Esto significa que la suposición es que ha centralizado intranet en el entorno de Office 365 donde puede colocar la parte de aplicación necesaria y que los usuarios finales llegarán a esta página de bienvenida cuando abran su explorador. Es habitual que cada explorador de la empresa tenga la misma página principal establecida mediante directivas de grupo, de modo que los usuarios finales siempre comenzarán desde una ubicación centralizada cuando abran su explorador. Esta es la ubicación donde colocaría la parte de la aplicación, que se puede establecer para que tenga un tamaño de 0 píxeles de ancho y alto. El punto clave aquí es que se usa el contexto del usuario final para ejecutar el elemento de aplicación, que contiene la página del complemento hospedado por el proveedor.

Consideraciones de optimización y mantenimiento del rendimiento

Dado que esta parte de la aplicación se ejecutará cada vez que el usuario llegue a la primera página de la intranet, debemos tener en cuenta el impacto en el rendimiento de esto o cómo hacer que el código funcione de forma eficaz y solo realizar partes clave de las ejecuciones de código cuando sea realmente necesario. La segunda consideración de optimización también es donde colocamos los recursos reales que se usan en cada uno de los sitios. Estos son desafíos bastante típicos a abordar con las personalizaciones. Esta es una breve lista de cosas que se deben concentrar en las implementaciones del modelo de aplicación.

  • Ubicación de los recursos: solución de red de entrega de contenido centralizado (CDN), en cada colección de sitios o en la colección de sitios raíz?
  • Frecuencia de actualización de los recursos o cómo asegurarse de que, independientemente del almacenamiento en caché del explorador del lado cliente, podemos garantizar que se ejecutan las versiones más recientes de los scripts (JavaScript) o se muestran las versiones más recientes de las imágenes?
  • Ejecución reducida del código para evitar la carga innecesaria en Azure y Office 365 servicio
  • Personalizaciones de versiones que se aplican al sitio de OD4B

Ubicación de los recursos

Hay pocas soluciones diferentes para esto. En el ejemplo de código de referencia usamos la inserción de JavaScript en cada uno de los sitios de OD4B para proporcionar un mensaje de directiva de empresa y para quitar la posibilidad de crear subsitios (u ocultar el vínculo). En esta solución concreta, vamos a cargar el archivo JavaScript necesario en la colección de sitios raíz del esquema de direcciones OneDrive para la Empresa y hacemos referencia a ese archivo directamente desde esa ubicación en los sitios OD4B individuales. Esto significa que solo tiene una ubicación para mantener y actualizar el archivo JavaScript, si se necesitan cambios.

En esta implementación de referencia también actualizamos este archivo cada vez que se ejecuta WebJob, lo que ciertamente no es necesario, pero el código de ejemplo estaba diseñado para funcionar con la mayor facilidad sin ningún paso adicional y posible. También podría cargar el archivo JavaScript manualmente en la colección de sitios raíz y, a continuación, hacer referencia a él desde allí. La solución alternativa sería también usar algún CND para almacenar el archivo necesario o hacer referencia a JavaScript desde la aplicación hospedada por el proveedor. Siempre que solo tenga una copia del archivo, tendrá:

Ubicación de los recursos

Desafío de almacenamiento en caché del lado cliente y cómo resolverlo

Uno de los desafíos de la implementación basada en JavaScript es el almacenamiento en caché del lado cliente. Cuando los exploradores descarguen los archivos JavaScript usados, almacenarán en caché esos archivos para reducir la cantidad de recursos descargados para las siguientes solicitudes. Esto es excelente desde la perspectiva de la optimización del rendimiento, pero provoca un desafío cuando necesitamos actualizar el archivo JavaScript. En el peor de los casos, el archivo JavaScript almacenado en caché provocará excepciones con otras actualizaciones introducidas con versiones actualizadas.

Para quitar este problema, podemos empezar a usar el atributo revision con la referencia de dirección URL de JavaScript. Cuando asociamos la acción personalizada del usuario al sitio de OD4B, se incluye la dirección URL de JavaScript para que tenga un GUID único en la dirección URL. Este es el ejemplo de la referencia que apuntará al sitio raíz de la colección de sitios. Observe el GUID adicional que se ha agregado después del atributo rev en la dirección URL. Cada vez que se ejecute el personalizador para un sitio OD4B determinado, este atributo se actualizará. En la práctica, esto significa que el archivo JavaScript se almacena en caché en el explorador hasta que se agrega una nueva versión al sitio OD4B, lo que cambiará la dirección URL y, por tanto, el explorador descargará la nueva versión y la almacenará en caché después de la siguiente actualización.

  • /OneDriveCustomization/OneDriveConfiguration.js?rev=4bb89029e7ba470e893170d4cba7de00

Este es el código que se usa para generar la dirección URL de JavaScript para la acción personalizada del usuario.

/// <summary>
/// Just to build the JS path which can be then pointed to the OneDrive site.
/// </summary>
/// <returns></returns>
public string BuildJavaScriptUrl(string siteUrl)
{
    // Solve root site collection URL
    Uri url = new Uri(siteUrl);
    string scenarioUrl = String.Format("{0}://{1}:{2}/{3}", 
                            url.Scheme, url.DnsSafeHost, 
                            url.Port, JSLocationFolderName);
    // Unique rev generated each time JS is added, so that we force browsers to 
    // refresh JS file wiht latest version
    string revision = Guid.NewGuid().ToString().Replace("-", "");
    return string.Format("{0}/{1}?rev={2}", scenarioUrl, JSFileName, revision);
}

Ejecución reducida del código

Dado que este proceso se basa en tener un elemento de aplicación oculto en la página principal de la intranet, significará que el código se ejecutará cada vez que el usuario actualice su explorador o se mueva a la página. Dado que esta página principal se establece a menudo como la página principal del explorador predeterminada para los usuarios corporativos, el código se ejecutaría cada vez que se inicia una sesión del explorador.

Sin embargo, dado que no actualizamos las personalizaciones que se aplican a los sitios de OD4B que a menudo, realmente no tiene sentido iniciar todo el proceso de actualización de personalización en primer lugar. Al hacerlo, se reduce el uso de las colas de almacenamiento y la ejecución del trabajo web, lo que reducirá directamente los costos asociados en la aplicación hospedada del proveedor, ya que no usaremos tanta CPU ni otros recursos en nuestro diseño.

La manera más sencilla de asegurarse de que nuestro procesamiento no se realiza en cada solicitud es usar el enfoque de cookies del explorador clásico, donde almacenaremos cookies específicas en el explorador del cliente con un tiempo de vida específico. Al comprobar esta existencia de cookies, podemos omitir la ejecución, hasta que la cookie haya expirado y es cuando se vuelve a comprobar el estado de personalización real en los sitios de OD4B.

Esto es lo que tenemos en el método de carga de página para la parte de la aplicación. Esta llamada al método comprobará la existencia de la cookie y, si la cookie existe, omitiremos el código de negocio real hasta que se necesite de nuevo la ejecución.

// Check if we should skip this check. We do this only once per hour to avoid 
// perf issues and there's really no point even hitting the user profile 
// in every request.
if (CookieCheckSkip())
    return;

El estado real de la cookie y la configuración de la cookie se realizan de la siguiente manera.

/// <summary>
/// Checks if we need to execute the code customization code again. 
/// Timer set to 60 minutes to avoid constant execution of the code for nothing.
/// </summary>
/// <returns></returns>
private bool CookieCheckSkip()
{
    // Get cookie from the current request.
    HttpCookie cookie = Request.Cookies.Get("OneDriveCustomizerCheck");

    // Check if cookie exists in the current request.
    if (cookie == null)
    {
        // Create cookie.
        cookie = new HttpCookie("OneDriveCustomizerCheck");
        // Set value of cookie to current date time.
        cookie.Value = DateTime.Now.ToString();
        // Set cookie to expire in 60 minutes.
        cookie.Expires = DateTime.Now.AddMinutes(60);
        // Insert the cookie in the current HttpResponse.
        Response.Cookies.Add(cookie);
        // Output debugging information
        WriteDebugInformationIfNeeded(
            string.Format(@"Cookie did not exist, adding new cookie with {0} 
                            as expiration. Execute code.",
                            cookie.Expires));
        // Since cookie did not existed, let's execute the code, 
        // so skip is false.
        return false;
    }
    else
    {
        // Output debugging information
        WriteDebugInformationIfNeeded(string.Format(@"Cookie did existed, 
                                    with {0} as expiration. Skipping code.", 
                                    cookie.Expires));
        //  Since cookie did existed, let's skip the code
        return true;
    }
}

Si echa un vistazo más de cerca al código en la página de elementos de la aplicación, verá que en cada llamada se comprueban las existencias del sitio de OD4B para el usuario final. Dado que esto solo se puede hacer mediante el acceso al perfil de usuario, el código tendrá impacto en el rendimiento. Mediante el uso de la comprobación de cookies anterior, podemos mejorar la experiencia del usuario final y evitar alcanzar el servicio de perfil de usuario constantemente sin requisitos reales. También es bueno observar que hemos colocado esa comprobación de cookies como primer paso en el método Page_Load , de modo que omitamos todo el procesamiento, si es necesario. Este es un fragmento de código corto del método Page_Load de Customizer.aspx para mostrar el proceso de código.

protected void Page_Load(object sender, EventArgs e)
{
    // Check if we should skip this check. We do this only once per hour to avoid 
    // perf issues and there's really no point even hitting the user profile 
    // in every request.
    if (CookieCheckSkip())
        return;
  
    var spContext = 
        SharePointContextProvider.Current.GetSharePointContext(Context);
    using (ClientContext clientContext = 
        spContext.CreateUserClientContextForSPHost())
    {
        // Get user profile
        ProfileLoader loader = ProfileLoader.GetProfileLoader(clientContext);
        UserProfile profile = loader.GetUserProfile();
        Microsoft.SharePoint.Client.Site personalSite = profile.PersonalSite;

        clientContext.Load(profile, prof => prof.AccountName);
        clientContext.Load(personalSite);
        clientContext.ExecuteQuery();

        // Let's check if the site already exists
        if (personalSite.ServerObjectIsNull.Value)
        {

Personalizaciones de versiones que se aplican al sitio de OD4B

El segundo nivel de optimización en nuestro procesamiento de código se realiza mediante el control de versiones específicamente las personalizaciones que implementamos en los sitios de OD4B. Esto significa que almacenamos la versión de las personalizaciones en el contenedor de propiedades del sitio OD4B y solo actualizamos los archivos y los recursos si es necesario. Esto significa que en la ejecución de WebJob comparamos la versión de personalización actual de OD4B con la versión que estamos a punto de implementar y solo si las versiones de personalización no existen en el sitio de OD4B, cargamos los recursos necesarios y aplicamos otras configuraciones.

Este enfoque también reducirá significativamente los recursos necesarios de Microsoft Azure, ya que evitamos actualizar o ejecutar código de personalización real cuando no es necesario. Esto significa una reducción en el uso de CPU y otros recursos en Microsoft Azure y menos solicitudes hacia Office 365.

Toda la lógica de personalización se almacena en este ejemplo y se encuentra en el método ApplySiteConfiguration en OD4B. Clase Configuration.Async.Common.SiteModificationManager . WebJob también llama a este método con los parámetros adecuados para iniciar el proceso de personalización. Antes de realizar realmente cualquier operación, estamos comprobando el valor del contenedor de propiedades con una clave de "Contoso_OneDriveVersion" y la ejecución solo continuará si la versión actual del sitio es inferior a la versión que planeamos aplicar. Este es el código real que usa el componente Office PnP Core para simplificar el código.

// Check current site configuration status - is it already in right version?
if (ctx.Web.GetPropertyBagValueInt(
    SiteModificationManager.OneDriveMarkerBagID, 0) 
    < SiteModificationManager.BrandingVersion)
{

Cuando se aplique la personalización al sitio, estableceremos la versión de personalización aplicada en el contenedor de propiedades para la siguiente ejecución.

// Save current branding applied indicator to site
ctx.Web.SetPropertyBagValue(SiteModificationManager.OneDriveMarkerBagID, SiteModificationManager.BrandingVersion);

Se trata de un proceso relativamente sencillo, pero reducirá significativamente los recursos necesarios de Azure y también reducirá las operaciones remotas innecesarias hacia Office 365, lo que tendrá un impacto positivo en el rendimiento.

Configuración necesaria en Azure

El requisito clave para que este ejemplo funcione correctamente es que ha creado Azure Storage Data Service y ha actualizado las cadenas de conexión de almacenamiento en consecuencia para los proyectos que las usan. Simplemente puede crear como servicio de almacenamiento desde el Portal de administración de Azure (manage.windowssazure.com), seleccionando Nuevo –> Servicios de datos –> Almacenamiento –> Creación rápida. Después de esto, solo tendrá que definir el nombre, la ubicación y algunas otras configuraciones y estará bien.

Configuración de creación rápida: el campo URL se establece en myveryownstorage, el grupo Ubicación/afinidad se establece en Oeste de EE. UU., Suscripción se establece en MSDN Ultimate y Replicación en Redundancia geográfica.

Una vez creado el almacenamiento, debe ir a copiar la clave necesaria para el cadena de conexión. Al pasar a la página de detalles de almacenamiento, puede acceder a la información de clave haciendo clic en "Administrar claves de acceso" desde la parte inferior de la página.

El vínculo a Administrar claves de acceso se resalta en la parte inferior de la página.

Tendrá que actualizar App.config archivo para los siguientes proyectos en la solución de Visual Studio. Cada uno de los proyectos se explica más adelante en esta entrada de blog.

OD4B. Configuration.Async.WebJob OD4B. El proyecto Configuration.Async.Console.SendMessage WebJob tiene dos claves, que se pueden actualizar para que apunten a la misma conexión y SendMessage solo tiene una clave para actualizar.

El archivo App.config está abierto en Visual Studio en el elemento appSettings. Dos elementos secundarios denominados Add aparecen en el elemento appSettings. Para el primer elemento Add, el atributo key=ClientId y el atributo value son iguales a un par de comillas dobles. Para el segundo elemento Add, el atributo key=ClientSecret y el atributo value también son iguales a un par de comillas dobles.

Estructura de la solución de referencia

Esta solución de Visual Studio consta de bastantes soluciones, pero cada una de ellas tiene motivos bastante razonables para estar allí. Esta es la introducción a cada uno de los proyectos de la solución y por qué existen o para qué sirven.

El Explorador de soluciones muestra una carpeta denominada Documentation seguida de seis proyectos que se describen en detalle a continuación.

OD4B.Configuration.Async

Este es el proyecto de aplicación de SharePoint real, que presentará la aplicación hospedada del proveedor en SharePoint y pedirá los permisos necesarios. Tenga en cuenta que, aunque en realidad no realizamos operaciones de nivel de inquilino desde la parte de la aplicación, se piden permisos bastante altos para el complemento. Esto se debe a que usaremos el mismo identificador de cliente y secreto de este archivo de aplicación en nuestra ejecución de WebJob. Con este enfoque, no es necesario registrar manualmente el identificador de aplicación y el secreto en SharePoint, sino que simplemente usamos el mismo identificador y secreto entre soluciones.

Lista de permisos: el inquilino de ámbito tiene el permiso FullControl. El ámbito Perfiles de usuario (social) tiene el permiso FullControl. La casilla Permitir que la aplicación realice llamadas de solo aplicación a SharePoint está activada.

Este proyecto también contiene la definición del elemento de aplicación que se implementará en la web host.

OD4B. Configuration.Async.Common

Este proyecto contiene toda la lógica de negocios real y los proyectos cruzados de código compartido, como la definición del objeto de datos que se coloca en la cola de almacenamiento y la lógica de negocios real para personalizar los sitios OD4B. La razón para colocar código aquí es simplemente para proporcionarnos una manera más sencilla de desarrollar y probar las operaciones cuando se crea el proyecto. Al igual que con el desarrollo general, no debe colocar realmente el código de lógica de negocios directamente en el elemento WebJob o en el elemento de aplicación, sino en el nivel de lógica de negocios para facilitar las pruebas y reutilizar el código.

Todas las operaciones reales hacia los sitios de OD4B se encuentran en OD4B. Clase Configuration.Async.Common.SiteModificationManager .

OD4B. Configuration.Async.Console.Reset

Este proyecto es nuestro proyecto de prueba y depuración para las personalizaciones reales. Se puede usar para aplicar manualmente las personalizaciones deseadas a cualquier sitio de OD4B. Durante el tiempo de desarrollo, este proyecto fue nuestro proyecto de prueba para probar el proceso de personalización antes de que se enlazara a WebJob. Project también se puede usar para restablecer las personalizaciones desde cualquier sitio de OD4B con fines de demostración o pruebas. Dado que la lógica de negocios real se encuentra en el proyecto común, este proyecto usará la misma clase SiteModificationManager que los demás para aplicar o restablecer las personalizaciones de los sitios.

Al probar las personalizaciones, simplemente puede cambiar el código en el método Main entre Aplicar y Restablecer para cambiar la operación deseada.

static void Main(string[] args)
{
  
    Uri url = 
        new Uri("https://vesaj-my.sharepoint.com/personal/vesaj_veskuonline_com");
  
        //get the new site collection
    string realm = TokenHelper.GetRealmFromTargetUrl(url);
    var token = TokenHelper.GetAppOnlyAccessToken(
                    TokenHelper.SharePointPrincipal, 
                    url.Authority, realm).AccessToken;
    using (var ctx = 
        TokenHelper.GetClientContextWithAccessToken(url.ToString(), 
        token))
    {
        // Uncomment the one you need for testing/reset
        // Apply(ctx, url);
        Reset(ctx);
    }
}

Tenga en cuenta que tendrá que asegurarse de que el identificador de aplicación y el secreto de este proyecto en el app.config coincidan con los que ha dado los permisos necesarios para el inquilino. Puede ejecutar fácilmente el proyecto haciendo clic con el botón derecho en el proyecto y eligiendo Depurar – Iniciar nueva instancia, para que pueda recorrer el código real que se ejecuta línea por línea.

OD4B. Configuration.Async.Console.SendMessage

Este proyecto se agregó a la solución para probar el mecanismo de cola de almacenamiento antes de que se enlazara a la parte de la aplicación. El proyecto se puede usar para pasar el proceso de parte de la aplicación para agregar nuevos mensajes a la cola de almacenamiento. Tenga en cuenta que tendrá que actualizar la cola de almacenamiento cadena de conexión en consecuencia en el app.config para que el proyecto funcione correctamente.

Puede ejecutar fácilmente el proyecto haciendo clic con el botón derecho en el proyecto y eligiendo Depurar – Iniciar nueva instancia, para que pueda recorrer el código real que se ejecuta línea por línea.

OD4B. Configuration.Async.WebJob

Este es el proyecto de WebJob real, que se creó mediante la plantilla de proyecto WebJob, introducido en el Visual Studio 2013 Update 4. Esta plantilla facilita la creación de proyectos de WebJob mediante la adición de referencias correctas y también proporciona una buena automatización de la implementación con compatibilidad con el clic derecho para el proyecto. Simplemente puede implementar la versión inicial o la nueva versión del proyecto en Azure haciendo clic con el botón derecho y seleccionando Publicar como trabajo web de Azure... que abrirá el asistente para publicación.

Se muestra el cuadro de diálogo Publicar web y se muestra la pestaña Conexión. El campo Servidor contiene el valor vesaj-od4bconf.scm.azurewebsites.net:443, el campo Nombre del sitio contiene el valor vesaj-0d4bconf, se redacta el campo Nombre de usuario, se enmascara el campo Contraseña, se activa la casilla Guardar contraseña y el campo Dirección URL de destino contiene el valor http://vesaj-od4bconf.azurewebsites.net.

Este trabajo web se crea como un WebJob continuo, que es necesario para el procesamiento basado en cola. Esto significa que en el método Main, solo establecemos el proceso para que se ejecute continuamente como sigue.

class Program
{
    // Please set the following connection strings in app.config for this 
    // WebJob to run: AzureWebJobsDashboard and AzureWebJobsStorage
    static void Main()
    {
        var host = new JobHost();
        // The following code ensures that the WebJob will be 
        // running continuously
        host.RunAndBlock();
    }
}

El procesamiento de cola real es muy fácil con WebJobs. Lo único que debemos hacer es establecer los atributos adecuados para el método y garantizar que las cadenas de conexión de Almacenamiento de Azure en la configuración de la aplicación se actualicen en consecuencia y coincidan con las colas de almacenamiento que ha creado en Microsoft Azure. A continuación se muestra el método ProcessQueueMessage de la clase functions.cs. Observe cómo usamos el modelo de token solo de aplicación para acceder a SharePoint desde WebJob. Para que esto funcione, deberá asegurarse de que ha copiado el identificador y el secreto de aplicación correctos en la app.config del proyecto. La lógica de negocios real se encuentra en la clase SiteModificationManager , por lo que simplemente lo llamamos con el contexto de cliente y los parámetros adecuados.

// This function will get triggered/executed when a new message is written 
// on an Azure Queue called queue.
public static void ProcessQueueMessage(
    [QueueTrigger(SiteModificationManager.StorageQueueName)] 
    SiteModificationData request, TextWriter log)
{
    Uri url = new Uri(request.SiteUrl);
  
    //Connect to the OD4B site sing App Only access
    string realm = TokenHelper.GetRealmFromTargetUrl(url);
    var token = TokenHelper.GetAppOnlyAccessToken(
        TokenHelper.SharePointPrincipal, url.Authority, realm).AccessToken;

    using (var ctx = TokenHelper.GetClientContextWithAccessToken(
        url.ToString(), token))
    {
        // Set configuration object properly for setting the config
        SiteModificationConfig config = new SiteModificationConfig()
        {
            SiteUrl = url.ToString(),
            JSFile = Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\OneDriveConfiguration.js"),
            ThemeName = "Garage",
            ThemeColorFile = Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\Themes\\Garage\\garagewhite.spcolor"),
            ThemeBGFile = Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\Themes\\Garage\\garagebg.jpg"),
            ThemeFontFile = "" // Ignored in this case, but could be also obviously set
        };

        new SiteModificationManager().ApplySiteConfiguration(ctx, config);
    }
}

Otra cosa que merece la pena notar es que tendrá que asegurarse de que ha establecido la propiedad Copiar local para la propiedad de referencias de ensamblado de CSOM de SharePoint para el proyecto, de modo que todos los ensamblados dependientes se copien correctamente en Azure al implementar el trabajo web. Esto se debe simplemente a que estos ensamblados no se encuentran en el sitio web normal de Azure de forma predeterminada, por lo que al establecer esta propiedad True, se asegurará de que los ensamblados a los que se hace referencia también se copien en la nube.

OD4B. Configuration.AsyncWeb

Esta es la aplicación hospedada del proveedor real que se hospeda en Microsoft Azure. Contiene la página de la parte de la aplicación, que se coloca en la primera página de la intranet. La página Default.aspx de esta aplicación no contiene realmente ninguna operación; en ella se muestran detalles sobre cómo usar la aplicación.

Aviso. Si se enfrentan a problemas de permisos denegados con el acceso a WebJob o a la aplicación solo en general, asegúrese de que ha actualizado el identificador de cliente y el secreto de la aplicación en el app.config para que coincidan con los valores de la web.config de este proyecto. Visual Studio puede cambiar estos valores en determinados escenarios.

Procesamiento de colas en WebJob

El uso de las colas de almacenamiento es muy sencillo con las API disponibles en Azure. La forma más sencilla de empezar es usar el paquete Nuget "Windows Azure Storage", que asociará todas las API necesarias y otros paquetes al proyecto. Una vez que haya agregado este paquete Nuget, simplemente puede empezar a usar las API de cola de almacenamiento para el procesamiento. A continuación se muestra el fragmento de código de OD4B. Proyecto Configuration.Async.Common (método AddConfigRequestToQueue en la clase SiteModificationManager), que contiene código de control de mensajes de cola real y se usa desde numerosos proyectos (proporciona una depuración de tiempo de desarrollo más sencilla).

public void AddConfigRequestToQueue(
            string account, string siteUrl, string storageConnectionString)
{
    CloudStorageAccount storageAccount = 
                        CloudStorageAccount.Parse(storageConnectionString);
  
    // Get queue... create if does not exist.
    CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
    CloudQueue queue = 
        queueClient.GetQueueReference(SiteModificationManager.StorageQueueName);
    queue.CreateIfNotExists();

    // Pass in data for modification
    var newSiteConfigRequest = new SiteModificationData()
    {
        AccountId = account,
        SiteUrl = siteUrl
    };

    // Add entry to queue
    queue.AddMessage(
        new CloudQueueMessage(
            JsonConvert.SerializeObject(newSiteConfigRequest)));
}

En este caso, el procesamiento real de la cola se realizó con el proyecto WebJob. En el caso de WebJob, simplemente podemos usar atributos específicos para automatizar el control de colas. Lo único que necesitamos para asegurarnos es que estamos usando el mismo cadena de conexión de almacenamiento y el mismo nombre de cola en la parte de envío y recepción.

// This function will get triggered/executed when a new message is written 
// on an Azure Queue called queue.
public static void ProcessQueueMessage(
    [QueueTrigger(SiteModificationManager.StorageQueueName)] 
    SiteModificationData request, TextWriter log)
{
    Uri url = new Uri(request.SiteUrl);

Realmente no se vuelve más fácil que esto. Observe que usamos SiteModificationManager.StorageQueueName en ambos lados para asegurarse de que el nombre de la cola coincide.

Aplicación de configuraciones reales al sitio

En estas implementaciones de referencia se realizan las siguientes personalizaciones en cada uno de los sitios de OD4B.

  • Adición de un mensaje de directiva de empresa que se muestra todo el tiempo en los sitios de OD4B
  • Ocultar la opción crear vínculo de subsitio en la página de contenido del sitio
  • Aplicar un tema personalizado al sitio de OD4B para que coincida con la personalización de marca de la empresa

La directiva de empresa y la ocultación del vínculo crear subsitio se logran mediante el llamado patrón de inserción de JavaScript, donde se agrega una acción de usuario personalizada al nivel de sitio con referencia al archivo JavaScript específico, que se ejecuta en cada solicitud de página. Esto significa que podemos controlar el procesamiento de páginas mediante tecnologías del lado cliente agregando, quitando o actualizando cualquier elemento de cualquier página. Con este enfoque no es necesario introducir una página maestra personalizada, lo que podría provocar costos de mantenimiento más significativos a largo plazo, especialmente si los cambios necesarios son bastante mínimos.

La segunda operación con los temas personalizados requiere que carguemos algunos archivos adicionales en el sitio y, a continuación, los establezcamos para que se usen como configuración de tema. Usamos estrictamente CSOM para cargar todos los archivos necesarios en los sitios para evitar futuras complicaciones con las asociaciones de elementos del marco de características. Dado que cargar un archivo en SharePoint mediante el CSOM es muy sencillo, esta es sin duda la manera más fácil de realizar la automatización y no es necesario preocuparse por ninguna dependencia de configuraciones específicas xml para las soluciones de espacio aislado. Este es el método de configuración de sitio real de OD4B. Clase Configuration.Async.Common.SiteModificationManager. Observe que usamos el componente principal PnP para desarrolladores Office 365 para simplificar algunas de las operaciones necesarias.

También es bueno observar que, de hecho, cargamos una nueva versión de JS en la colección de sitios raíz cada vez que personalizamos el sitio OD4B personal. Definitivamente no es una solución óptima, sino que está allí por motivos de simplicidad para esta solución de referencia. Podría considerar la posibilidad de agregar esa operación de carga de archivos de JavaScript al evento instalado de la aplicación, de modo que solo se haga una vez cuando se instale la aplicación, pero en ese caso tendría que realizar algún trabajo adicional con las actualizaciones de ese archivo JS.

// This function will get triggered/executed when a new message is written 
// on an Azure Queue called queue.
public static void ProcessQueueMessage(
    [QueueTrigger(SiteModificationManager.StorageQueueName)] 
    SiteModificationData request, TextWriter log)
{
    Uri url = new Uri(request.SiteUrl);
  
    //Connect to the OD4B site using App Only token
    string realm = TokenHelper.GetRealmFromTargetUrl(url);
    var token = TokenHelper.GetAppOnlyAccessToken(
        TokenHelper.SharePointPrincipal, url.Authority, realm).AccessToken;

    using (var ctx = TokenHelper.GetClientContextWithAccessToken(
        url.ToString(), token))
    {
        // Set configuration object properly for setting the config
        SiteModificationConfig config = new SiteModificationConfig()
        {
            SiteUrl = url.ToString(),
            JSFile = Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\OneDriveConfiguration.js"),
            ThemeName = "Garage",
            ThemeColorFile = 
                Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\Themes\\Garage\\garagewhite.spcolor"),
            ThemeBGFile = 
                Path.Combine(Environment.GetEnvironmentVariable
                ("WEBROOT_PATH"), "Resources\\Themes\\Garage\\garagebg.jpg"),
            ThemeFontFile = "" // Ignored in this case, but could be also set
        };

        new SiteModificationManager().ApplySiteConfiguration(ctx, config);
    }
}

Obviamente, las operaciones necesarias dependen en gran medida de los requisitos empresariales. Puede encontrar varios patrones y enfoques diferentes con operaciones basadas en CSOM de la Office 365 Patrones y prácticas de desarrollador.

Notas adicionales sobre las soluciones basadas en WebJob

Estas son algunas notas adicionales relacionadas con el desarrollo de WebJobs en Azure. Esta es una técnica extremadamente eficaz que se usará sin duda ampliamente entre las personalizaciones Office 365. Sin duda verá que se agregarán soluciones nuevas y mejoradas basadas en la tecnología WebJob al programa Office 365 Developer Patterns & Practices.

Depuración de WebJobs y proceso de personalización

Uno de los procedimientos recomendados para el código en general es localizar las operaciones reales fuera del proceso de ejecución final real, de modo que pueda concentrarse primero en probar fácilmente el código necesario simplemente mediante la aplicación de consola o, por ejemplo, con proyectos de prueba en Visual Studio. De este modo, puede asegurarse de que la lógica de negocios real es totalmente funcionalidad antes de enlazarla realmente al proceso final, en este caso, es decir, el trabajo web. En este caso de solución de referencia colocamos todo el código de negocio en el OD4B. Clase Configuration.Async.Common.SiteModificationManager y lo llamamos desde numerosas ubicaciones.

Esto significaba que durante el tiempo de desarrollo podíamos usar OD4B. Aplicación de consola Configuration.Async.Console.Reset para probar y restablecer las personalizaciones tantas veces como sea necesario desde los sitios para asegurarse de que la lógica de negocios es totalmente sólida. Esto realmente no tiene nada que ver con el modelo de complementos de SharePoint o el desarrollo de Azure, sino con prácticas prácticas de desarrollo paso a paso, independientemente de la tecnología que use. En ocasiones, cuando era orador en el entrenamiento de certificación de MCM for SharePoint, me refería a esto como el método NKOTB, pero eso no es realmente una terminología estándar del sector :-)

Una de las grandes mejoras desde la perspectiva de depuración de WebJobs se introdujo en Visual Studio 2014 Update 4. Con las conexiones de Azure recién introducidas y las plantillas de proyecto, realmente puede realizar la depuración remota con WebJob que se ejecuta en El lado de Azure. Tendrá que implementar WebJob en Azure y, después, puede iniciar la sesión de depuración haciendo clic con el botón derecho en Instancia de WebJob desde el Explorador de servidores y elija Asociar depurador en el menú contextual.

El Explorador de servidores expandió los objetos anidados Websites, vesaj-od4bconf, WebJobs, Continuous, OD4BConfigurationAsyncWebJob. Aparece un menú contextual sobre OD4BConfigurationAsyncWebJob y la opción de menú contextual Asociar depurador está resaltada.

Incluso hay un evaluador para enviar mensajes con formato correcto a la cola en la solución de referencia. OD4B. El proyecto Configuration.Async.Console.SendMessage se creó simplemente para tener la oportunidad de depurar el proceso de WebJob sin tener que implementar el elemento de aplicación en cualquier lugar. Esto regresó de nuevo al depurar y probar todo el proceso paso a paso.

Variables de entorno de WebJob

Una de las cosas interesantes de WebJobs es que se ejecutan en sitios web de Azure, pero su ubicación de ejecución es ligeramente diferente de los sitios web normales de Azure. Lo que quiero decir con esto es que si implementa archivos o recursos adicionales junto con WebJob en Azure, podría encontrarse con desafíos si asume que puede hacer referencia a esos recursos directamente mediante rutas de acceso relativas clásicas en el código de WebJob.

En este caso, teníamos un archivo JavaScript y pocos archivos para el tema personalizado, que se implementaron en el sitio web de Azure, de modo que se pudieran cargar en los sitios de SharePoint según sea necesario. Puede ver esos archivos en Azure si extiende la rama Archivos en un sitio web específico.

El Explorador de servidores expandió los objetos anidados Websites, vesaj-od4bconf, Files, Resources, Themes, Garage y muestra los archivos en la carpeta Garage.

Normalmente, en los sitios web de Azure, podría hacer referencia a esos archivos mediante el siguiente formato.

string path = HostingEnvironment.MapPath(
    string.Format("~/{0}", "Resources/OneDriveConfiguration.js"));

Sin embargo, dado que webJobs se ejecutan en una ubicación diferente y no en el contexto de IIS, la referencia anterior al archivo no funcionaría, ya que la asignación produciría un error en el contexto del proceso de WebJob. Aquí es donde las variables de entorno específicas de WebJob pueden ayudar. En el caso de la solución de referencia, usamos la variable de entorno específica de WebJob WEBROOT_PATH para obtener acceso a la carpeta del sitio web asociada.

string jsFile = Path.Combine(
    Environment.GetEnvironmentVariable("WEBROOT_PATH"), 
    "Resources\\OneDriveConfiguration.js");

También hay algunas otras variables de entorno para WebJobs, lo que podría ayudarle. Puede comprobar las distintas variables de entorno mediante código y hay buenas referencias en GitHub para ello.

Vídeo que muestra la solución y las acciones

Este es un vídeo en el que se muestra la solución en la práctica, incluida la explicación de las estructuras de la solución y cómo la usaría en el entorno de Office 365 para modificar OneDrive para la Empresa sitios.

Ejemplos de PnP

Se aplica a

  • Office 365 multiempresa (MT)
  • Office 365 dedicado (D) parcial
  • SharePoint 2013 local parcial

Los modelos para Office 365 dedicado y local son idénticos a las técnicas del modelo de complemento de SharePoint, pero existen algunas diferencias en las posibles tecnologías que se pueden usar.