Script

[SharePoint Online] – Modifier la Timezone sur une collection de sites

Posted on Updated on

Bonjour à tous,

Aujourd’hui un script utile pour modifier la Timezone (fuseau horaire) sur l’ensemble des sites d’une collection sur SharePoint Online (Office 365). J’ai eu ce besoin suite à une migration d’un tenant O365 vers un autre tenant O365 hébergé sur une autre plaque (Europe vers Etats-Unis).

J’ai décidé ici d’utiliser le CSOM de SharePoint Online mais c’est tout à fait réalisable avec du Powershell ou en utilisant le Pattern & Practice (https://dev.office.com/patterns-and-practices).

Voici le script que j’ai utilisé (qui est sans doute perfectible et optimisable !).

Tout d’abord, il vous faudra installer les binaires Microsoft.SharePoint.Client.dll et Microsoft.SharePoint.Client.Runtime.dll via le setup : https://www.microsoft.com/en-US/download/details.aspx?id=35588 (à télécharger & installer donc). Ces dlls seront installées par défaut dans C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\.

Une fois ceci fait, vous pourrez les référencer dans votre script de cette manière :


add-type -Path 'C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll'
add-type -Path 'C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll'

Ensuite, j’initialise la connexion vers la collection de site que je souhaite mettre à jour (remplacer par vos valeurs ce qui est entre [ ]) :

$SiteCollectionUrl = "https://[MONTENANT].sharepoint.com/sites/[MACOLLECTIONDESITES]"
$username = "[LOGIN]@[DOMAIN].com"
$password = "[PASSWORD]"

Puis ensuite, on initialise le contexte :

function GetClientContext($SiteCollectionUrl, $username, $password) {
    $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
    $context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteCollectionUrl)
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)
    $context.Credentials = $credentials
    return $context
}

 

Et enfin la fonction qui permet de mettre la Timezone à jour. Pour ma part, je la positionne sur la Timezone “(UTC) Dublin, Edinburgh, Lisbon, London”. Une petite recherche sur le net pour trouver votre zone… (http://blog.jussipalo.com/2013/10/list-of-sharepoint-timezoneid-values.html).

Cette fonction est récursive et permet d’itérer sur l’ensemble des sites de la collection :

function ProcessSites($subsiteurl){
    $clientContext = GetClientContext $subsiteurl $username $password
    $rootWeb = $clientContext.Web
    $childWebs = $rootWeb.Webs
    $clientContext.Load($rootWeb)
    $clientContext.Load($childWebs)
    $clientContext.ExecuteQuery()
 
    write-host $rootWeb.url -ForegroundColor Yellow
    $TimeZones = $rootWeb.RegionalSettings.TimeZones
    $clientContext.Load($TimeZones)
    $clientContext.ExecuteQuery()

    $RegionalSettings = $rootWeb.RegionalSettings
    $clientContext.Load($RegionalSettings)
    $clientContext.ExecuteQuery()
    $TimeZone = $TimeZones| Where {$_.Description -eq "(UTC) Dublin, Edinburgh, Lisbon, London"}

    $TimeZone | Select ID,Description
    Write-Host "TimeZone " $TimeZone.Description -ForegroundColor Yellow
    $RegionalSettings.TimeZone = $TimeZone
    $RegionalSettings.Update()

    $rootWeb.Update()
    $clientContext.ExecuteQuery()
    foreach ($childWeb in $childWebs)
    {
        write-host $childWeb.url -ForegroundColor Yellow
        $clientContext.Load($childWeb)
        $clientContext.ExecuteQuery()

        $TimeZones = $childWeb.RegionalSettings.TimeZones
        $clientContext.Load($TimeZones)
        $clientContext.ExecuteQuery()

        $RegionalSettings = $childWeb.RegionalSettings
        $clientContext.Load($RegionalSettings)
        $clientContext.ExecuteQuery()
        $TimeZone = $TimeZones | Where {$_.Description -eq "(UTC) Dublin, Edinburgh, Lisbon, London"}

        $TimeZone | Select ID,Description
        Write-Host "TimeZone " $TimeZone.Description -ForegroundColor Yellow
        $RegionalSettings.TimeZone = $TimeZone 
        $RegionalSettings.Update()

        $childWeb.Update()
        $clientContext.ExecuteQuery()

        Write-Host "Done :" $childWeb.Title "-" $TimeZone.ID

        ProcessSites $childWeb.url
    }
}


ProcessSites $SiteCollectionUrl

Il ne reste qu’à lancer dans Powershell ou Powershell ISE.

Advertisements

[SP2010 & SP2013] – Envoyer les résultats de l’analyseur de santé et d’intégrité par e-mail

Posted on Updated on

 

Bonjour à tous.

Cela fait quelques temps que je n’avais rien publié, je reviens avec un script bien pratique permettant d’envoyer les résultats produits par l’analyseur de santé et d’intégrité de SharePoint (SharePoint Health Analyzer) par e-mail, à l’administrateur par exemple.

Le but étant de ne plus avoir à se connecter à l’administration centrale de SharePoint pour consulter et monitorer l’état de la plateforme, mais d’automatiser cela par un envoi de courrier électronique.

Pour cela, nous allons écrire un script permettant de récupérer le contenu des résultats, récupérer les paramètres d’envoi de courrier électronique et enfin automatiser le tout via une tâche planifiée. Et bien sûr compatible avec SharePoint 2010 et SharePoint 2013 !

1/ Récupérer les paramètres d’envoi d’e-mail

NB : le script doit être exécuté avec un compte possédant les droits nécessaires pour effectuer les opérations. Dans mon cas c’est l’administrateur de ferme SharePoint.

Pour cela, c’est très simple. Nous allons écrire un script PowerShell permettant de récupérer l’instance du site d’administration centrale de SharePoint puis récupérer les paramètres de courrier sortant (Outgoing e-mail parameters).

Pour récupérer la Web Application de l’administration centrale, soit on connait l’URL soit on ne la connait pas.

Dans le cas où on la connait (il faudra la modifier lorsque l’on changera de ferme… et si elle change d’url / serveur) :

$w = Get-SPWebApplication http://sitename

Si on ne la connait pas, et si on veut faire un script portable (mon cas) :

$CAWebApp = (Get-SPWebApplication -IncludeCentralAdministration) | ? { $_.IsAdministrationWebApplication -eq $true }

$CARootWeb = Get-SPWeb -Identity $CAWebApp.Url

Ce qui donne :

01

On récupère bien l’adresse du site Web (racine) de la Web Application contenant la centrale d’administration de notre ferme SharePoint.

Ensuite, nous allons récupérer les paramètres :

  • L’adresse de provenance (From)
  • L’adresse (le nom) du serveur d’envoi d’e-mails (renseigné dans la console d’administration centrale de SharePoint).
$from = $CAWebApp.OutboundMailReplyToAddress

$mailserver = $CAWebApp.OutboundMailServiceInstance.Server.Address

Et également fournir l’adresse où l’on souhaite envoyer le courrier électronique :

$to = "admin.sharepoint@demo.local"

02

2/ Récupérer le contenu du SharePoint Health Analyzer

Le SharePoint Health Analyzer enregistre ses résultats dans une liste SharePoint dont l’adresse est statique (toujours la même), dans le site racine de l’administration centrale SharePoint.

Il suffit donc de se connecter à cette liste, d’en récupérer le contenu pour le formater dans le corps du courrier électronique.

Récupérons l’instance de la liste de résultats :

$list = $CARootWeb.GetList("\Lists\HealthReports")

03

Il nous reste ensuite à récupérer le contenu de cette liste et le formater dans un contenu HTML qui deviendra le corps de l’e-mail. Pour récupérer le contenu, rien ne vaut une petite requête CAML !

Ici nous voulons récupérer seulement les cas qui ne sont pas en réussite (succès), c’est-à-dire les problèmes. Il faut donc filtrer sur un champ qui s’appelle “HealthReportSeverity” (internalName, en anglais dans mon ca), en ne récupérant que les items où la valeur est différente de “4 – Success” :

$where = "<Where><Neq><FieldRef Name='HealthReportSeverity' /><Value Type='Text'>4 - Success</Value></Neq></Where>"
$query = New-Object Microsoft.SharePoint.SPQuery
$query.Query = $where
$items = $list.GetItems($query)

Dans mon cas, je récupère 3 items ($items.Count) :

04

3/ Construire le contenu du courrier électronique

Le contenu étant récupéré, il nous faut construire le corps du message en HTML (très basique !). Pour ma part, je suis parti sur quelque chose de simple: un tableau.

Ce tableau contiendra :

  • Le nom de l’erreur avec un lien pointant vers le détail (vers la page DispForm.aspx de SharePoint)
  • Le Type (catégorie) d’erreur
  • Le contenu du message
  • Le type d’erreur : avertissement, erreur, etc.
  • La date d’exécution (de la tâche planifiée SharePoint)

Nous allons également ajouter un peu de texte avant et après le tableau pour préciser :

  • La date et l’heure courante
  • Le nom du rapport
  • Une signature

On construit l’entête et la signature :

NB : Attention à l’encodage des simples et double quotes !!! => Passer par NotePad / Notepad++, ça vous aidera 🙂

$entete = "Bonjour, voici le rapport d’exécution de l’analyseur de santé et d’intégrité de la ferme SharePoint : " + $CAWebApp.Farm.Name

$titre = "<Title>" + $entete + "</Title>"

$signature = "Bonne journée, <br/><br/>L’équipe SharePoint."

05

Puis nous allons construire le tableau en itérant sur la collection d’Items chargée via la requête CAML :

$corps = "<h2>" + $entete + "</h2><br />"

$corps = $corps + "<table cellspacing='5' cellpadding='5' style='width: 100%;border:1px solid #bbbbbb'>" 
foreach ($item in $items)
{
$itemTitle = $item.Title
$itemUrl = $CARootWeb.Url + ($list.Forms | where { $_.Type -eq "PAGE_DISPLAYFORM" }).ServerRelativeUrl + "?ID=" + $item.ID

$itemSeverity = $item["Severity"]
$itemCategory = $item["Category"]
$itemExplanation = $item["Explanation"]
$itemModified = $item["Modified"]

$corps = $corps + "<tr>"
$corps = $corps + "<td><a href=`"" + $itemUrl + "`">" + $item.Title + "</a></td>"
$corps = $corps + "<td>" + $itemCategory + "</td>"
$corps = $corps + "<td>" + $itemExplanation + "</td>"
$corps = $corps + "<td>" + $itemSeverity + "</td>"
$corps = $corps + "<td>" + $itemModified + "</td>"
$corps = $corps + "</tr>"
}

$corps = $corps + "</table><br /><br />" + $signature

$corpshtml = ConvertTo-Html –Head $titre –Body $corps

06

07

4/ Envoyer un e-mail en PowerShell

Ensuite il nous faut envoyer cet e-mail via des cmdlets PowerShell. Pour cela, nous allons recourir à l’API System.Net.Mail bien connue dans le monde Microsoft :

$CARootWeb.Dispose()
Send-MailMessage –From $from –To $to –Subject $titre –BodyAsHtml $corps –SmtpServer $mailserver

Puis fermer la connexion sur la Web Application :

$CARootWeb.Dispose()

Attention, dans cet exemple j’ai configuré le service SMTP sur mon serveur SharePoint, et en renseignant correctement les paramètres d’e-mails sortants dans la console d’administration centrale de SharePoint.

5/ Automatiser l’envoi par une tâche planifiée Windows

Dernière étape, l’automatisation. Pour cela nous allons créer une tâche planifiée Windows, exécutée sur l’un des serveurs SharePoint de la ferme. Dans mon cas ce sera sur le serveur hébergeant l’Administration Centrale de SharePoint.

Cette tâche planifiée devra lancer PowerShell, puis appeler le script. Il nous faut donc modifier à nouveau ce script pour intégrer l’appel du Snap-In permettant de charger le contexte SharePoint dans PowerShell (ce que fait le Management Shell de SharePoint, automatiquement).

Je vous invite à vous reporter à http://technet.microsoft.com/fr-fr/library/ee806878(v=office.15).aspx.

Nous allons alors ajouter en haut du fichier du script PowerShell :

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" –ErrorAction SilentlyContinue) -eq $null)
{
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

Et enregistrer le tout dans un fichier avec l’extension ps1. Pour moi SPHealthAnalyzerSendMail.ps1, que je tente d’exécuter avec PowerShell (et non pas le Management Shell de SharePoint :

14

 

Voici le fichier obtenu, vous pouvez le télécharger ici : http://1drv.ms/1ot9VJI

Créons donc cette tâche planifiée ! Pour cela, il faut ouvrir l’assistant de création des tâches panifiées de Windows Server :

Dans Démarrer > Outil d’administration > Tâches planifiées :

image

image

 

Cliquer sur “créer une tâche” dans le panneau Actions à droite et donnez-lui un nom, description, et surtout le compte exécutant la tâche (l’administrateur de la ferme dans mon cas) :

image

 

Aller dans l’onglet Triggers (déclencheur) et fournir une planification (schedule), dans mon cas chaque jour à 2h00 du matin :

image

 

Puis aller dans l’onglet Actions et entrer les paramètres :

  • Commande : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • Arguments : –command “.\\SPHealthAnalyzerSendMail.ps1”
  • Répertoire de démarrage : Répertoire où est enregistré votre fichier sur le serveur, dans mon cas dans le répertoire 14 == C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14

image

 

Enregistrer le tout, l’assistant vous demande le mot de passe du compte utilisé pour lancer la tâche :

image

 

La tâche est créée :

image

 

Faites un clic droit, Démarrer pour tester :

image

 

Les résultats de l’exécution sont présentés dans la fenêtre en bas :

image

 

Voici l’e-mail reçu… C’est simple et épuré dira-t’on. Si vous rencontrez des problèmes d’encodage pour les caractères accentués par exemple, n’hésitez pas à jouer avec la fonction :

[System.Web.HttpUtility]::HtmlEncode(“MON TEXTE A ENCODER”)

15

 

Il n’y a plus qu’à revoir un peu le Html envoyé dans l’e-mail pour peaufiner, et c’est tout bon !