PI Services

Le blog des collaborateurs de PI Services

Powershell : Comparer une date manuellement saisie avec un format spécifique à la date du last logon d'un utilisateur dans Active Directory

Dans le cadre de l'automatisation, il arrive de recevoir une demande pour développer un script PowerShell pour le nettoyage ou la gestion de l'obsolescence des utilisateurs dans l'Active Directory.

Dans le script, vous aurez peut être besoin de comparer la date du last logon utilisateur dans l'Active Directory avec une date manuellement saisie (variable du script) avec un format spécifique.

Ci-dessous un exemple de PowerShell pour comparer une date donnée avec une date de last logon utilisateur dans Active Directory :

# Import Active Directory Module
Import-Module ActiveDirectory
 
#Set a fixed date for comparison
$Fixed_Date = "13/11/2021"
 
#Convert the fixed date from a string to a compatible specific format
$Fixed_Date_Convert = [datetime]::parseexact($Fixed_Date, 'dd/MM/yyyy', $null)  
 
#Get AD user last logon date in dd/MM/yyyy format
$ADUser = get-aduser "jdoe" -Properties lastlogondate | select @{Name=”ModifiedLastLogonDate”;Expression={$_.LastLogonDate.ToString(“dd/MM/yyyy”)}}
 
#Convert AD last logon date to a specific format to be compared with the chosen date above
$ADdate = [datetime]::parseexact($ADUser.ModifiedLastLogonDate, 'dd/MM/yyyy', $null)
 
if($ADdate -le $Fixed_Date_Convert)
    {
        echo "Active directory last logon date is inferior to the fixed date"
        }
    else
    {
        echo "Active directory last logon date is superior to the fixed date"
        }

Conclusion:

La méthode [datetime]::parseexact(dateString, format, provider) Convertit la représentation sous forme de chaîne spécifiée d'une date et d'une heure en son équivalent DateTime.

Script Powershell - Archive log files to Zip

Le script ci-dessous archive des fichiers de log plus ancien que $daysthreshold vers une archive zip existante ($zipfilepath). Il crée le sous dossier et l'archive zip horodatée si elle n'existe pas.

ArchiveLogToZip.ps1

 

###############################################################
### ArchiveLogs.ps1                                    ###
### Add Log Files older than $days to existing zip archive. ###

### Params
### $logpath: Log Folder
### $archpath: Archive Folder
### $zipfilePath: zip file path
### $daysthreshold: Treat log older than $daysthreshold days
###############################################################
 
Param(
$logpath = "C:\MyLogFolder", 
$archpath = "C:\MyLogFolder\Archive\",
$zipfilePath =  "$archpath"+"*.zip",
[int]$daysthreshold = 0 
)
 



# Test if $archpath exist
If ( -not (Test-Path $archpath)) {New-Item $archpath -type directory} 
 
# Get items to archive
$ItemsToArc = Get-Childitem -Path $logpath -recurse | Where-Object {$_.extension -eq ".log" -and $_.LastWriteTime -lt (get-date).AddDays(-$daysthreshold)}

# Log and exit if  No items to archive
If (! $ItemsToArc)
    {
    Write-Host -F Yellow "No items to archive - Check the existence of the logs"
    exit 0
    }



# If the zip file not exist, create it
if (!(Get-Item $zipfile -ErrorAction SilentlyContinue))
{
$date = $(Get-Date).ToString("MM-dd-yyyy_HH-mm-ss")
New-Item -Path "$archpath$date.zip"
$zipfile = $(Get-Item "$archpath$date.zip").FullName
}
Else
{
$zipfile = $(Get-Item $zipfilePath).FullName
}


# Create a com object that will represent the zip file
$Zip = New-Object -ComObject Shell.Application

write-progress -activity "Archiving Data" -status "Progress..." 

try
{
$ItemsToArc | foreach {$Zip.namespace($zipfile).Movehere($_.fullname,8) ; start-sleep -Seconds 3}
}
catch
{
Write-Host "Error during File add to Zip"
}

 

Configuration IP d’un serveur Nano

 

Nous allons voir comment configurer l’adressage IP d’un serveur Nano lors de son premier démarrage.

Monter le vhdx de votre image Nano.

image

 

Aller dans la lettre de lecteur monté contenant votre image Nano

image

 

Positionner vous dans le répertoire I:\Windows.

Créer le répertoire Setup si celui ci n’existe pas.

image

 

Créer maintenant dans i:\Windows le répertoire Scripts

image

 

Créer dans le répertoire Scripts un fichier portant le nom setupcomplete.cmd

image

 

Lors du premier démarrage de votre image Nano, le script setupcomplete.cmd sera exécuté.

Ainsi, vous pouvez à partir de ce script, configurer l’interface réseau de votre serveur Nano.

Exemple :

Nous allons configurer sur notre serveur Nano l’adresse IP 192.168.1.11/24 avec comme adresse DNS le 192.168.1.10.

Pour cela, nous allons enregistrer les lignes de commandes suivante dans le setupcomplete.cmd :

PowerShell -Command "& {if ($env:computername -eq 'NANO'){netsh interface ip set address 'Ethernet' static 192.168.1.11 255.255.255.0 192.168.1.254}}"
PowerShell -Command "& {if ($env:computername -eq 'NANO'){netsh interface ipv4 add dnsserver "Ethernet" address=192.168.1.10 index=1}}"

image

Ejecter votre VHD depuis l’explorateur Windows.

Lancer votre serveur Nano.

Le script SetupComplete.cmd s’exécute (car il s’agit du premier lancement du serveur Nano depuis sa génération).

 

image

image

Authentifier vous

image

Nos paramètres IP se sont correctement configurés.

image

 

image

Nested Hyper-V sous NanoServer Technical Preview 4

 

La Technical Preview 4 de Windows Server 2016 est désormais disponible. https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-technical-preview

 

De nouveaux Packages Nano sont désormais disponible.

Vous pouvez construire vos VM nanos avec l’outil NanoServerBuild_x64.

 

Disponible ici : https://onedrive.live.com/?cid=b370cc46ea3ab572&id=B370CC46EA3AB572%21137&authkey=%21ANkLug_PPC-kh-8

 

Présentation ici :  http://blog.piservices.fr/post/Provisionner-des-VHDs-et-VM-Nano-Server.aspx

 

 

Exemple de nouveaux Packages disponible sous TP4

 

clip_image001

 

 

Un package SCVMM même :D

 

clip_image002

 

 

Cocher la case New-VM.

 

Pour activer le Nested sur le/les VMs créées, cocher la case Nested.

Celle-ci autorisera la virtualisation imbriquée.

 

Attention : Pour que le Nested soit fonctionnel, vous devez être sous une build de l’OS Hyperviseur root supportant la fonctionnalité Nested (Exemple : Windows 10 Build 10586)

 

clip_image003

 

 

Cliquer sur Let’s Go pour démarrer les opérations.

(Des fichiers logs sont générés là ou vos VHDs sont créés).

 

clip_image004

 

 

image

 

 

Une fois les opérations finies, votre / vos VM(s) sont créées.

 

 

Démarrer votre VM

clip_image006

 

 

Authentifier vous

clip_image008

 

 

Nous sommes bien en TP4.

clip_image010

 

 

Création d’un VM imbriquée

 

Nous allons maintenant essayer de créer une VM dans notre Nano Server lui-même virtualisé.

 

Enter-PSSession -VMName NanoTP4 -Credential administrator

New-VHD -Path c:\Base.vhdx -SizeBytes 1GB

New-VM -Name "new 3" -MemoryStartupBytes 32MB -VHDPath c:\Base.vhdx

Get-vm | Start-VM

 

On remarque que la VM démarre correctement. Cela signifie que le Nested est fonctionnel.

 

clip_image012

 

En TP3, le démarrage de la VM ne fonctionnait pas.

image

 

 

Vous pouvez désormais créés des labos avec SCVMM en prime avec tout un tas de clusters :) (y)

 

Have Fun !

Powershell & Office 365 : Provisionning de licences

Introduction

Dans Office 365, il existe plusieurs méthodes pour ajouter des licences à un utilisateur :

  • Via l'interface d'administration manuellement sur chaque utilisateur.
  • Via l'interface d'administration manuellement sur plusieurs utilisateurs.
  • Avec les cmdlets Powershell Office 365.

Dans cet article, nous allons nous intéresser à l'ajout/suppression de licences via Powershell. Le but est d'automatiser cette opération. On peut facilement imaginer des scénarios conjoints avec Dirsync. Ce dernier provisionne un compte, puis, une tâche ajoute automatiquement les licences nécessaires à l'utilisateur.

D'autre part, il est possible d'ajouter pour chaque utilisateur :

  • Une licence complète incluant tout les services de l'abonnement souscrit.
  • Certains services d'une licence afin de limiter les accès aux utilisateurs (par exemple : ne donner qu'une licence Exchange sans donner les accès à la suite Office).

    Nous nous attarderons sur ces différentes possibilités dans l'un des paragraphes suivants.

    Nous ferons un rappel sur les prérequis nécessaires à l'utilisation des cmdlets Powershell avant d'appréhender leur attribution. Nous verrons enfin un script permettant d'automatiser le processus d'ajout/suppression de services via l'utilisation des groupes de sécurité Office 365.

Pré requis

L'administration des utilisateurs Office 365 via Powershell a besoin de l'installation d'un module spécifique. Ce dernier nécessite un prérequis : Microsoft Online Services Sign-In Assistant. Ci dessous, vous trouverez le lien de téléchargement de ce dernier :

http://www.microsoft.com/en-us/download/details.aspx?id=41950

Voici maintenant les liens pour récupérer le module Powershell :

http://go.microsoft.com/fwlink/p/?linkid=236298

A titre informatif, la version 32 bits de ces composants n'est plus pris en charge et ne sera plus mis à jour par Microsoft.

 

Connexion à Office 365 et permission

Pour se connecter à Office 365, il est nécessaire d'exécuter la commande suivante :

Les informations d'authentification fourni doivent correspondre à un utilisateur possédant à minima le rôle de gestion des utilisateurs. Cette attribution permettra d'affecter les licences.

 

Licences et abonnements

Tout d'abord, nous allons commencer par récupérer les différents abonnements disponibles sur un tenant Office 365. Il s'agit de la commande :

Le résultat obtenu permet aussi de voir les licences disponibles (ActiveUnits) et utilisées. (ConsumedUnits)

Get-MsolAccountSku

Pour chacun des abonnements, il est possible d'accéder aux services disponibles. Exemple avec le premier abonnement de la liste :

ServiceStatus

Chaque service Office 365 possède donc un identifiant qui est utilise lors de l'affectation de licences à certains utilisateurs. Les services étant différents d'un plan à un autre, voici un tableau récapitulant les identifiants et les services auxquels ils donnent accès pour un abonnement de type E3 :

EXCHANGE_S_STANDARD Exchange Online (Plan 2)
MCOSTANDARD Lync Online (Plan 2)
SHAREPOINTENTERPRISE SharePoint Online (Plan 2)
SHAREPOINTWAC Office Online
OFFICESUBSCRIPTION Office ProPlus
RMS_S_ENTERPRISE Azure Active Directory Rights Management
INTUNE_O365 Intune
YAMMER_ENTERPRISE Yammer
 

Pour les autres abonnements, les services ont des noms identiques ou similaires (exemple : SHAREPOINT_S_DEVELOPER au lieu de SHAREPOINTENTERPRISE pour un abonnement développeur).

NB : J'ai noté deux spécificités sur certains services. Premièrement, la licence Office Online doit être attribué conjointement à une licence Sharepoint (on peut facilement s'en rendre compte via le portail d'administration Office 365). Enfin, les licences Yammer n'ont pas besoin d'être attribués. Cela est sans doute dû au fait que l'intégration du service dans l'offre Office 365 n'est pas terminée. Il se peut aussi que cela soit pensé pour simplifier le système. Néanmoins, il apparaît que le nombre d'utilisateurs peut dépasser le nombre de licences sans avoir de réduction de services (Il faut donc faire un suivi régulier du nombre de licences afin d'être en règle).

 

Gestion des licences utilisateurs

Attribution d'une licence complète

L'attribution d'une licence utilisateur se fait via la commande Powershell "Set-MSOLUserLicence". Il est possible d'utiliser cette commande pour un ou plusieurs utilisateurs. Le paramètre AddLicenses permet d'ajouter une licence correspondant à un plan Office 365.

Exemple d'attribution d'une licence :

NB : Il est nécessaire de fournir l'attribut AccountSkuId de l'objet obtenu avec la commande Get-MsolAccountSku.

NB2 : Si vous attribuez des licences à plusieurs utilisateurs et que le nombre restants est insuffisant, alors la cmdlet affectera quand même des licences jusqu'à épuisement de celles-ci.

Attention, avant d'attribuer une licence, il est nécessaire d'ajouter une localisation à l'utilisateur. Cette opération est automatisable avec la commande suviante :

La location est à remplacer par la valeur voulue (ici : FR).

 

Attribution d'une licence partielle

Pour l'instant nous avons vu, l'attribution d'une licence donnant accès à tous les services offert par l'abonnement Office 365. Dans certains cas, il peut être voulu de n'autoriser un utilisateur qu'à un certain nombre de services. Pour se faire, il faut créer un objet du type MsolLicenceOption. Celui-ci est une licence à laquelle on a désactivé certains services.

Exemple :

Cette cmdlet crée une licence avec un pack de service désactivant Azure Right Management Services et Lync Online.

La commande crée les options de licencing à partir d'un abonnement (AccountSkuId) et une liste de services sous forme de tableau. Les noms des services à fournir sont ceux définis dans le tableau du paragraphe "Licences et abonnements". On peut ensuite attribuer ces options de licencing via la même commande que précédemment mais en changeant de paramètre :

Script

Présentation

Le but du script ci-dessous est d'effectuer un provisioning automatique des licences Office 365 pour les utilisateurs synchronisés avec Dirsync. Celui-ci est basé sur l'utilisation des groupes de sécurité Office 365 (ce dernier peut être synchronisé via Dirsync). Chaque groupe correspond à l'attribution d'un ou plusieurs accès à des services Office 365.Ce script peut aussi bien gérer l'ajout que la suppression d'accès. Afin de ne pas perturber les accès déjà affectés à un utilisateur sont réattribués (tant qu'ils ne sont pas concerné par le script). Afin de mieux comprendre le comportement du script, voici un scénario d'exemple :

  • USER1 appartient au groupe GRP-SharepointOnline
  • GRP-SharepointOnline attribue les accès SHAREPOINTENTERPRISE et SHAREPOINTWAC
  • USER1 possède déjà un accès à Lync (via MCOSTANDARD)
  • Le script s'exécute et donne les accès à SHAREPOINT Online et Office Online à USER1
  • USER1 conserve également son accès à Lync Online.

Pour obtenir ce résultat, l'algorithme recalcule les accès de chaque utilisateur. Cette opération est réalisé en récupérant l'attribut DisabledServices de la licence utilisateur (avec Get-MsolUserLicense).

Il permet aussi de ne pas gérer certains services. Cela peut être notamment utile pour Yammer dont l'attribution de licence n'est pas à administrer.

Celui-ci a été utilisé au travers d'un runbook dans System Center Orchestrator mais il peut aussi être utilisé dans une tâche planifié. Il est possible d'imaginer des variantes de ce script. Par exemple, les licences à attribuer pourraient être stockée dans un attribut du groupe. On peut aussi supprimer l'exigence d'être un utilisateur synchronisé par Dirsync (dans ce cas le groupe devra être alimenté via la console Office 365 et non dans Active Directory).

 

Script

Exchange / Powershell : EWS et Impersonation

Introduction

Les Exchanges Web Services (EWS) sont très pratiques pour manipuler le contenu d'une boite aux lettres. Ceux-ci ont été créés pour s'intégrer dans des applications en C# mais peuvent aussi être utilisés dans un script Powershell. Grâce aux EWS, nous pouvons manipuler des dossiers, des messages, le calendrier. Il est possible de réaliser des opérations de créations (comme l'envoi d'un email), suppressions et modifications. Cependant, nous verrons qu'il est nécessaire d'avoir des droits sur la boite aux lettres d'un utilisateur ou d'utiliser un mécanisme d'impersonation pour réaliser ces opérations.


Contexte

Cet article est basé sur un retour d'expérience d'utilisation des EWS dans un environnement Exchange 2010 SP3. Le système de réservation de ressources d'une entreprise (salle, équipements) devait migrer vers Exchange. Un mécanisme de reprise de l'existant a dû être mis en place pour créer les réservations dans les calendriers des ressources et des personnes réservant la ressource.


EWS

Afin d'utiliser les Exchange Web Services dans un script Powershell, il faut installer le package permettant d'interagir avec ceux-ci.


Ce dernier est actuellement en version 2.2 et peuvent s'interfacer avec toutes les versions d'Exchange de 2007 SP1 à la dernière en date : 2013 SP1 (Les cumulatives updates n'ont pas d'importance).


Il est disponible en suivant le lien ci-dessous :

http://www.microsoft.com/en-us/download/details.aspx?id=42951


Impersonation

Les Exchange Web Services utilisent l'autodiscover pour communiquer avec une boite aux lettres spécifique.


Exemple de connexion aux EWS :



Cependant, dès que j'effectuerai une opération sur la boite aux lettres, il me faudra des droits sur cette boite aux lettres comme le contrôle total. Dans le cas contraire, j'obtiendrai des erreurs.


Donner des droits sur un grand nombre de boites aux lettres n'est pas recommandable car cela complexifie l'administration. il existe donc une seconde option permettant de se faire passer pour le compte utilisateur de la boite aux lettres. Il s'agit de l'impersonation. C’est un rôle à attribuer à un compte de service (via le mécanisme RBAC). Cette solution offre plusieurs avantages :


  • Simplicité d'administration : on peut rapidement ajouter ou supprimer les droits d'impersonation à un compte.
  • Contrôle des comptes visés : le scope des utilisateurs pouvant être "remplacer" par un compte de service peut facilement être modifié sans devoir changer les propriétés de chaque boite aux lettres.
  • Décoreller des délégations : le processus d'impersonation n'apparait pas dans les délégations et il est ainsi plus simple de faire la différence entre les deux mécanismes et les différentes autorisations.

Implémentation RBAC

Le rôle permettant l'impersonation est nommé ApplicationImpersonation. Pour l'implémenter, nous allons d'abord créer un scope, c’est-à-dire définir les utilisateurs sur lesquels le compte de service pourra faire de l'impersonation.


Dans l'exemple ci-dessous, nous créons un scope contenant toutes les boites aux lettres utilisateurs :

Puis, nous ajoutons le rôle ApplicationImpersonation à l'utilisateur souhaité en spécifiant le scope créé précédemment.


NB : Pensez à changer la valeur MYUSER par le nom d'utilisateur de du compte réalisant de l'impersonation.


Script

Ci-dessous vous trouverez différentes fonctions Powershell commentées permettant la création d’une réunion avec la possibilité de réserver une salle mais aussi la validation que ces réunions ont bien été créées. Ces fonctions gèrent l’impersonation tant que le compte avec lequel la connexion aux EWS possède ce droit sur les boites aux lettres visées.

 

Fonction de création de réunions :


 

Fonction de validation de la réunion dans le calendrier utilisateur :

Cette fonction valide qu’une réunion possédant les bonnes ressources ainsi que les bonnes dates de début et de fin existe dans le calendrier de l’utilisateur.


 

Elle permet aussi de vérifier qu’il n’y a pas eu de création de doublons dans le calendrier (utile si un script de création de réunion à été exécuté plusieurs fois).

 

Fonction de validation de la réunion dans le calendrier de la boîte aux lettres de ressources :

Cette fonction cherche une réservation de la ressource en validant les dates et heures ainsi que le nom de la personne ayant créé cet objet. Cette vérifications s‘effectue sur le calendrier de la boite aux lettres de ressource. Le statut de la réservation est aussi vérifié (valeur attendue : Accept) afin d’être certain que la ressource n’ait pas été réservée pas une autre personne.


Tips

La création de nombreuses réservations peut engendrer un grand nombre d'envoi d'email aux utilisateurs ayant réservés ces ressources. En effet, ils vont recevoir des réponses des ressources (acquittement ou refus de la demande) si le système de réservation automatique a été activé (Resource booking attendant). Une solution de contournement peut être mise en place pendant la phase de migration. Elle consiste à limiter le nombre de destinataires à 0 lors de l'envoi d'un mail par la boite aux lettres de ressources.


Pour réaliser cette opération, il suffit de lancer une invite de commande Powershell Exchange (EMS) et d'exécuter la commande suivante :


Ou bien, si l'on souhaite changer la valeur sur toutes les boites aux lettres de salles en une seule commande (on peut remplacer RoomMailbox par EquipmentMailbox pour les boites aux lettres d'équipements).


NB : Pensez à remplacer IDENTIFIANT_BAL par l'identifiant de la boite aux lettres de ressources (Alias par exemple).

Utilisation de la commande CopyPe dans un contexte Powershell

 

Si vous exécuter CopyPe.exe dans une fenêtre PowerShell, vous aurez comme résultat :

ERROR: The following processor architecture was not found: x86.

 

image

Une petite astuce :

Lorsque vous lancez l’environnement de déploiement de l’ADK

image

En réalité, vous lancez le script DandISetEnv.bat.

image

Ce script peut être trouvé dans le répertoire suivant :

"C:\Program Files (x86)\Windows Kits\xx\Assessment and Deployment Kit\Deployment Tools"

image

Nous allons donc ajouter à ce script la ligne de commande Copype nous intéressant. Ainsi, l’exécutable Copype sera lancé dans le contexte de l’environnement de déploiement de l’ADK.

Comment allons-nous procéder ?

Pour ne pas modifier le script DandISetEnv.bat original, nous allons récupérer son contenu, le copier dans un emplacement temporaire et modifier ce fichier.

get-content "C:\Program Files (x86)\Windows Kits\xx\Assessment and Deployment Kit\Deployment Tools\DandISetEnv.bat" | Out-File "$env:temp\DandISetEnv.bat" -encoding ASCII

On ajoute la commande copype à la copie du fichier.

"" | Out-File -Append "$env:TEMP\DandISetEnv.bat" -Encoding ASCII

"copype x86 c:\MonPE_x86" | Out-File –Append "$env:TEMP\DandISetEnv.bat" -Encoding ASCII

 

Et on exécute le script

cd $env:TEMP

.\DandISetEnv.bat

image

Le répertoire de travail du PE est maintenant construit.

image

Exchange / Powershell : Influence du paramètre DomainController

Introduction

 

Exchange bénéficie d'un grand nombre de cmdlet Powershell très abouties et permettant de configurer et d'administrer l'intégralité d'une infrastructure de messagerie. Aussi, celles-ci sont très utiles dans le cas de scripts de provisionning. J'ai rencontré une erreur lorsque je cherchais à créer et à configurer un grand nombre de boites aux lettres de ressources.

 

Contexte

 

L'environnement dans lequel j'ai découvert ce problème est une forêt mono domaine Active Directory avec une infrastructure Exchange 2010 SP3 dans laquelle il y avait plusieurs contrôleurs de domaine dans le même site Active Directory que la totalité des serveurs de messagerie.

 

Plus globalement, cette erreur pourra être rencontrée dès qu'un serveur Exchange pourra être amené à interroger plus d'un contrôleur de domaine.

 

Erreur rencontrée

 

Dans un script de provisionning de boîtes aux lettres, on cherche à les créer mais aussi à les configurer. Si l'on souhaite configurer une boite aux lettres tout de suite après sa création alors on obtient une erreur similaire à celle ci-dessous (“ObjectNotFoundException”) :



Cela peut se retrouver en exécutant l'exemple suivant :



Une ou plusieurs opérations de modification (de type Set-…) vont échouer avec le message d'erreur cité précédemment.

 

Explication

 

Suite à cette erreur, il est logique de penser que cela est dû à l'interrogation de différents contrôleurs de domaine qui n'ont pas encore répliqué entre eux (Une réplication intra site peut prendre quelques secondes).

 

Aussi, on peut se dire qu'il suffit alors de spécifier le paramètre DomainController pour corriger le problème en l'indiquant sur toutes les commandes et en définissant un contrôleur de domaine unique qui traitera toutes les opérations.

 

Cependant, cela ne corrigera pas le problème. Microsoft en donne l'explication dans les fiches Technet des cmdlets :http://technet.microsoft.com/en-us/library/dd335046.aspx.

 

Le paramètre DomainController ne concerne que le contrôleur de domaine qui va écrire les modifications dans Active Directory. Cependant, un autre contrôleur de domaine  peut être utilisé pour lire l'objet avant d'écrire les changements sur celui spécifié en paramètre.

 

Aussi, pour une cmdlet de type Get-… (lecture), le paramètre DomainController sera bien le contrôleur de domaine sur lequel l'objet sera lu (cela sera utile pour mettre en place l'une des solutions proposées).

 

Solution

 

Pour résoudre ce problème,  il faut donc attendre que la réplication ait eu lieu sur la totalité des contrôleurs de domaine du site Active Directory de l'infrastructure Exchange. Pour cela, nous avons trois solutions.

 

Solution 1 :

 

Il est possible de séparer la création des boîtes aux lettres et leurs configurations. Cette solution oblige donc a réaliser le provisioning en plusieurs phases.

 

Solution 2 :

 

On peut définir un délai entre l'opération de la cmdlet de création et la cmdlet de configuration via un Start-Sleep par exemple. Cependant, cette solution ne garantit pas que les opérations vont toutes se dérouler correctement. Il faudra sans doute que le délai soit important pour que le provisioning ait un taux de réussite élevé et donc augmenter considérablement le temps d'exécution du script.

 

Solution 3 :

 

La dernière solution est une combinaison des deux précédentes puisqu'elle permet de n'avoir qu'une seule phase de provisioning tout en ayant un temps d'exécution relativement rapide.

 

Cette solution consiste à implémenter une boucle de test de l'opération à réaliser sur le même contrôleur de domaine via la cmdlet de lecture (Get-…).

 

Exemple :



Il est possible d'ajouter une courte pause entre chaque test afin de ne pas surcharger le processus sans pour autant trop pénaliser le temps d'exécution du script. Le paramètre ErrorAction permet d'alléger l'affichage car on connait déjà l'erreur que l'on va rencontrer.

Il ne vous reste plus qu'à choisir la solution que vous préférez.

ADFS / Yammer : Renouvellement des certificats

Introduction

Cet article est un retour d'expérience sur un incident rencontré dans le cadre d'une infrastructure ADFS possédant une fédération avec Yammer. Ce dernier s'est produit lors du renouvellement de certains certificats de l'environnement ADFS. L'authentification unique n'était plus fonctionnelle. En effet, une mise à jour doit être réalisée du côté de Yammer lorsque l'un des certificats ADFS est renouvelé. Pour rappel, contrairement à d'autres services qui peuvent être fédérés (comme Office 365), il n'est pas possible de configurer automatiquement le SSO. Cette opération doit être réalisée via une demande au support Office 365.

 

Dans un premier temps, il sera question de faire quelques rappels sur les certificats ADFS puis d'étudier leurs renouvellements. Enfin, nous verrons comment mettre à jour Yammer pour que le l'authentification ne soit pas indisponible lorsque les certificats sont renouvelés. Ce dernier nous permettra de voir comment gérer les certificats avec des services fédérés qui ne peuvent pas récupérer les métadatas automatiquement.

 

Cette manipulation a été réalisée sur une infrastructure sous Windows 2012 R2 (ADFS 3.0).

 

ADFS

Dans une infrastructure ADFS, 3 certificats sont nécessaires au bon fonctionnement de celle-ci :

  • Un certificat public portant le nom DNS du service de fédération. Il s'agit d'un certificat web permettant de sécuriser les communications via SSL.

  • Un certificat auto-généré de type X.509 permettant de signé les tokens d'authentification (Token-Signing). Celui-ci permet de certifier que le token provient bien de la ferme ADFS.

  • Un certificat auto-généré de type X.509 permettant de décrypter des tokens (Token-Decrypting) provenant d'un autre fournisseur de revendications.

Renouvellement du certificat Service-Communications

Le renouvellement pour le certificat public de type Service-Communications se fait manuellement. Lorsque vous posséder votre nouveau certificat, il est nécessaire de l'importer dans le magasin personnel de l'ordinateur des serveurs ADFS (comme lors de la configuration d'ADFS) et des serveurs Web Application Proxy (si vous en posséder) .

 

Sur les serveurs ADFS, lorsque le certificat est importé, il faut ajouté les permissions de lecture sur la clé privée. Pour réaliser cette opération, il faut effectuer un clic droit sur le certificat (lorsque l'on se trouve dans le magasin personnel de l'ordinateur) puis choisir “All Tasks” puis “Manage Private Keys”.

 

03

 

Dans l'onglet sécurité, il suffit d'ajouter les comptes “NT Service\ADFSSRV” et “NT Service\DRS” (pour la fonctionnalité Workplace Join) puis d'attribuer le droit “Read”. Attention, cette opération est à réaliser sur l'ensemble des serveurs de la ferme ADFS.

 

02

 

Les commande Powershell ci-dessous nous permettent ensuite de mettre à jour la configuration des serveurs ADFS.

 

Sur les serveurs ADFS :

 

On récupère, le certificat en utilisant la commande suivante :

 

Cette dernière permet d'interroger le magasin personnel de l'ordinateur (pensez à remplacer NOM_DNS_FERME_ADFS par le nom de votre ferme de serveurs ADFS). Il est nécessaire de récupérer la valeur de l'attribut thumbprint (Pour rappel, ce champ est unique pour chaque certificat).

 

Ensuite, on modifie la configuration du service ADFS pour utiliser notre nouveau certificat en spécifiant la valeur de l'attribut thumbprint.

 

NB : Attention, il faut remplacer THUMBPRINT par la valeur obtenu précédemment.

 

Sur chacun des serveurs ADFS d'une ferme, il faut exécuter la commande ci-dessous pour mettre en place le bindings HTTPS avec le nouveau certificat :

 

NB : Attention, il faut remplacer THUMBPRINT par la valeur obtenu précédemment.

 

Enfin, il est nécessaire de redémarrer le service ADFS sur chacun des serveurs de la ferme.

 

On peut ensuite vérifier les valeurs grâce aux commandes suivantes :

 
 

La seconde cmdlet doit être exécuté sur chacun des serveurs de la ferme ADFS pour effectuer une vérification complète.

 

Les serveurs Web Applications Proxy se mettent à jour via les commandes suivantes :

 
 

NB : Attention, il faut remplacer THUMBPRINT par la valeur obtenu précédemment.

 

Tout d'abord on change le certificat. Dans un second temps, on redémarre le service ADFS pour que le changement de configuration soit pris en compte. Ces deux commandes sont à exécuter sur chacun des serveurs Web Applications Proxy que vous possédez.

 

Renouvellement des certificats Token-Signing et Token-Decrypting

Au sujet, des autres certificats, il existe deux possibilités :

  • Renouvellement manuel

  • Renouvellement automatique

Le renouvellement automatique est la configuration par défaut d'ADFS. 20 jours avant l'expiration d'un certificat, ADFS en génère un nouveau. Celui-ci possède le statut de certificat secondaire. Au bout de 5 jours (soit 15 jours avant l'expiration du certificat), il est promu comme certificat primaire.

 

Les paramètres d'auto renouvèlement se consultent/configurent via Powershell. Pour cela, il faut utiliser la commande “Get-ADFSProperties”. C'est l'attribut AutoCertificateRollover qui permet de déterminer si l'auto renouvèlement des certificats de type Token-Signing et Token-Decrypting est activé.

 

Voici les paramètres ADFS qui peuvent être modifiés par la commande Set-ADFSProperties et qui concernent le mécanisme évoqué précédemment :

  • CertificateDuration : Durée de validité d'un certificat auto généré (par défaut : 365 jours)

  • CertificateGenerationThreshold : Nombre de jours avant la génération d'un nouveau certificat Token Signing or Token Decrypting (par défaut 20).

  • CertficatePromotionThreshold : Nombre de jours avant la promotion du nouveau certificat (passage du status Secondary au status Primary, valeur par défaut : 5 jours).

  • CertificateRolloverInterval : Interval de temps (en minutes) entre chaque vérification de la validité d'un certificat (par défaut 720 minutes).

  • CertificateCriticalThreshold : Nombre de jours avant qu'un certificat expire et qu'un renouvèlement critique ne soit déclenché (ce paramètre intervient lors d'un problème avec le système d'auto renouvellement).

Point d'attention :

Lors du renouvèlement d'un certificat, les métadatas changent. Aussi, si l'un des relying party trust n'est pas capable de récupérer par lui même les métadatas alors l'authentification ne sera plus fonctionnelle.

 

Yammer

La configuration de l'authentification unique via Yammer se fait manuellement. Il est nécessaire d'ouvrir un ticket auprès du support. Celle-ci ne nécessite pas d'envoyer les certificats mais simplement les métadatas. Néanmoins lorsque les certificats ADFS se renouvèlent, il est nécessaire de les transmettre au support Yammer via une demande de service sur le portail d'administration Office 365. Pour se faire, il suffit de créer une archive contenant les nouveaux certificats et de les joindre…

 

Cependant, il peut arriver que le délais soit trop court pour que le ticket soit traité à temps par le support si l'on se trouve presque à la fin de la période de 5 jours après le renouvellement des certificats (voir paragraphe précédent) ou pire, si le nouveau certificat a déjà été défini comme certificat primaire. Ce dernier cas aura pour effet de couper totalement l'authentification unique auprès de Yammer et ainsi causé une coupure de service pour les utilisateurs. En effet, Yammer n'est pas capable de récupérer les nouvelles métadatas contenant les nouvelles informations des certificats.

 

Dans ce cas, on obtient l'erreur ci-dessous lorsque l'on essaie de s'authentifier :

 

01

 

De plus dans l'observateur d'évènements, on remarque des events avec l'id 364 avec pour message :

Lorsque ce problème est rencontré, il faut transmettre le nouveau certificat au support Office 365, ce qui peut peut demander un temps de traitement long. Cependant, si l'ancien certificat est encore valide (c'est à dire qu'il est passé en statut secondaire), il existe une méthode pour rétablir le service temporairement pendant la durée de validité dudit certificat. Pour ce faire, il faut repasser le certificat en statut primaire. Cette opération peut être réalisée via la console graphique.

 

Dans la console ADFS Management, il faut se rendre dans la section “Service” puis “Certificate” puis effectuer un clic droit sur le certificat concerné et choisir l'option “Set as Primary”. Celle-ci peut être grisée. Cela survient lorsque le renouvellement automatique est activé. Il faut donc le désactiver temporairement via la commande suivante :

 

Lorsque le certificat sera de nouveau en statut primaire, le service sera rétabli. Attention, n'oubliez pas de changer le certificat primaire lorsque le support Office 365 vous aura informé de la prise en compte du nouveau certificat.

Powershell 5.0 : Les classes

Introduction

Powershell 5.0 a bénéficié de plusieurs releases lors de l'année 2014, chacune d'entre elles apportant son lot de nouveautés/correctifs. Ce dernier est toujours en développement (la version finale n'arrivant qu'avec Windows 10) mais nous allons tout de même nous attarder dans cet article sur une nouvelle notion : la création de classes. Celle-ci n'était pas disponible nativement jusqu'en Powershell 5.0, ce qui pouvait paraître étrange pour un langage de scripting orienté objet. Je ferai un bref rappel sur les options disponibles avant cette version.

Dorénavant, nous pourrons créer nos propres objets personnalisés. Souvent, dans les scripts Powershell, on remarque l'utilisation de tableau ou de dictionnaire imbriqués et qu'il faut ensuite analyser pour récupérer la bonne valeur. Ces scripts obligent à avoir des algorithmes assez long et le script devient difficilement lisible en dehors du fait de ne pas être rigoureux. De plus, ils nécessitent souvent l'imbrication de multiples boucles de traitement influençant les performances générales du script.

Dans cet article, nous aborderons la création de classes d'objets en Powershell, l'ajout de propriétés et de méthodes ainsi que la façon d'instancier ("créer") nos objets. Pour certaines notions, une définition sera donnée (Cela permettra aux personnes non familières avec certaines notions de programmation objet de mieux appréhender le sujet).

Dans la suite de cet article, nous prendrons l'exemple d'une classe d'objet HRUser définissant un utilisateur dans le système RH pour illustrer la nouvelle syntaxe. Imaginons que cet exemple soit utilisé dans le cadre d'une interaction avec une base de données. L'objet utilisateur possédera les attributs suivant (nous ajouterons d'autres propriétés et des méthodes/fonctions ultérieurement) :

  • firstname
  • lastname
  • isCollaborator (un booléan permettant de savoir si l'utilisateur est un collaborateur)
  • salary (un nombre entier)

NB : Contrairement à la première beta, Powershell 5.0 est dorénavant disponible pour Windows 2012 et supérieur (qui n’était compatible qu’avec Windows 2012 R2 et supérieur). Le lien suivant vous mènera à la dernière beta sortie (Novembre 2014) :

http://www.microsoft.com/en-us/download/details.aspx?id=44987

Avant Powershell 5.0

Jusqu'à Powershell 4.0, il existait plusieurs méthodes pour créer des objets personnalisés en Powershell.

New-Object et NoteProperty :

La première méthode consiste à créer un objet de type PSCustomObject auquel on ajoute des propriétés de type NoteProperty.

Cependant, cette méthode ne permet pas d'ajouter des fonctions et le typage de nos attributs est dynamique. De plus, tout les objets personnalisés posséderont la même classe : PSCustomObject.

C# et Add-Type :

La seconde méthode était l'utilisation de code C#. Powershell pouvant interprété ce langage,  il est tout à fait possible d'écrire entièrement une classe en C# puis de l'ajouter dans une session Powershell via la commande Add-Type.

On peut ensuite créer l'objet grâce à la commande New-Object. Ce dernier possédera son propre type (HRUser) qui sera différent pour toutes les classes que vous créerez.

 

Il est aussi possible d'ajouter des fonctions statiques ou non à notre classe (nous reviendrons sur cette notion ultérieurement).

Cette méthode est complète mais nécessite de connaître le C#, ce qui complexifie aussi la lecture des scripts. Dans les prochains paragraphes, nous allons voir que Powershell offre dorénavant nativement les mêmes possibilités.

Les classes

Une classe contient la définition de nos objets ainsi que les traitements qui peuvent être effectués sur ceux-ci. Une nouveau mot clé apparaît dans Powershell 5.0 : “class” que l'on retrouve avant un scriptblock. Une classe se déclare de la façon ci-dessous :

Malheureusement, il n'existe pas encore de syntaxe pour gérer l'héritage de classe.

NB : Attention, les classes doivent obligatoirement être déclarées dans des scripts powershell. Une déclaration dans une invite de commande Powershell ne pourra donc pas être fonctionnelle.  De plus, lorsqu'une classe a été chargée, il est nécessaire d'ouvrir une nouvelle version avant d'en exécuter une version différente (elle ne peut pas être mis à jour dans une même session Powershell).

Les propriétés

Les propriétés contiennent tous les attributs de notre classe.

Celles-ci peuvent optionnellement contenir un type (comme dans l'exemple ci-dessus). Cela permet de réaliser de la validation sur les propriétés d'un objet.

Nous pouvons donc créer notre objet de type HRUser via la cmdlet New-Object en indiquant le type d'objet à créer.

 

On peut aussi créer un objet grâce à la méthode new qui existe dans chaque classe.

 

Toutes les propriétés sont initialisées avec une valeur par défaut (une chaîne vide, un booléen faux ou le chiffre 0 dans notre exemple).

On peut ensuite définir les propriétés de notre objet.

 

Attention, dans notre exemple, nos propriétés sont typées. On peut donc rencontrer une erreur si par exemple on définit une chaîne de caractères à la place d'un nombre pour la propriété “salary”.

ERROR PROPERTY TYPE

Les constructeurs

Un constructeur permet de créer un objet en initialisant certaines ou toutes de ces propriétés avec des valeurs fournies en paramètres et éventuellement d'effectuer des traitements lors de la création d'objets. La méthode “new” que nous avons vu précédemment correspond au constructeur par défaut. Mais il est possible d'en ajouter un ou plusieurs autre, c'est ce qu'on appelle la surcharge.

La syntaxe d'un constructeur est la suivante (il faut la placer à l'intérieur de la définition de notre classe) : On peut créer l'objet en lui passant des paramètres pour utiliser notre constructeur :

 

Ou

 

Cependant, on rencontrera une erreur si on ne renseigne pas tous les paramètres :

ERROR CONSTRUCTOR 

Pour palier à ce problème, on peut imaginer un second constructeur sans le salaire :

Les méthodes

Les méthodes sont l'équivalent de fonctions qui permettant d'interagir avec un objet. Nous allons créer une fonction permettant de gérer l'augmentation de salaire d'un employé.

Le type indiqué devant la méthode nous indique ce qui est retourné (“void” correspond à une méthode ne retournant rien).

Exemple d'exécution incluant une augmentation de salaire pour une personne :

EXEMPLE METHOD

Si nous souhaitons récupérer le nouveau salaire, il faut modifier la méthode en utilisant le mot clé “return” et en modifiant le type de retour.

Méthodes et propriétés statiques

Il reste un dernier mot clé à définir : “static”. Il permet de définir des méthodes et des propriétés qui sont accessibles sans avoir à créer un objet. Pour illustrer cette notion, nous allons ajouter une propriété représentant le total des utilisateurs du système. De plus, nous allons modifier les constructeurs pour incrémenter le compteur quand un utilisateur est créé.

On définit la propriété count :

 

On peut y accéder via : [HRUser]::count

Voici le script contenant l'intégralité de la définition de  la classe HRUser :

Exemple d'exécution :

EXEMPLE STATIC

Il aurait pu être intéressant d'intégrer la modification du compteur lors de la suppression de l'utilisateur dans la classe. Cependant, il n'existe pas de destructeur (méthode permettant de détruire un objet) dans la version actuelle de Powershell 5.0.

Conclusion

Nous avons aborder la création de classes d'objets en Powershell qui nécessite d'avoir des connaissances en programmation orientée objet. Initialement, Microsoft a ajouté cette notion pour simplifier la création de ressources pour Desired State Configuration (exemple : https://technet.microsoft.com/en-us/library/dn820211%28v=wps.640%29.aspx). A noter que lorsque vous charger une classe et que vous créer des objets, toutes les propriétés et méthodes associées sont accessible via l'auto complétion. Les classes écrites en Powershell sont une nouveauté et il reste encore des améliorations à réaliser :

  • l'héritage des classes.
  • la portée sur les propriétés : en Powershell, elles sont toutes publiques et donc accessible/modifiable depuis n'importe quel endroit dans un script. Changer la portée permettrait de spécifier des propriétés qui ne seraient accessibles que dans une méthode de la classe.