PI Services

Le blog des collaborateurs de PI Services

Powershell / Exchange : Erreur 9323 - Certificat expiré sur un objet AD

Introduction

Cet article permet de montrer la gestion des certificats via Powershell au travers d'un problème concret rencontré sur une infrastructure Exchange. Une solution basée sur un script Powershell sera détaillée.

Erreur rencontrée

Contexte : Infrastructure Exchange 2010 avec plusieurs dizaine de milliers de contacts Active Directory importés et mis à jour par un outil tierce.

Dans l’observateur d’événements de nombreux événements 9323 apparaissent.

9323

Ces derniers sont liés à la génération de l'OAB. Exchange détecte un utilisateur dont un certificat est expiré. Ces événements n'apparaissent que sur des objets de type "Contact"  La solution doit contrôler tous les objets Active Directory de ce type.

Solution

La soluton proposée pour purger les certificats invalides des contacts Active Directory se base sur un script Powershell V2. Ce dernier analyse l'attribut UserCertificate (il s'agit d'une liste de certificat).

Avec le type d'objet "System.Security.Cryptography.X509Certificates.X509Certificate2", il est possible d'obtenir des informations sur les certficats contenus dans cet attribut sous forme lisible (et non pas un tableau de bytes ou de valeur hexadécimal comme sur la console Active Directory Users and Computers).

Ci-dessous, un exemple de données récupérées sur les certificats d'un objet Active Directory (ici, il n'y a qu'un seul certificat et la variable $User est un utilisateur Active Directory).

Certificate

On remarque qu'on accède à des renseignements comme l'émetteur ou le sujet. Les informations qui nous interessent (dates de validité du certificat) sont aussi présentes. Il suffit donc de comparer la date d'expiration contenue dans l'attribut "notAfter" avec la date du jour en cours pour détecter les certificats expirés.

Grâce à la cmdlet "Set-ADObject", il sera ensuite possible de supprimer les certificats qui ne sont plus valides.

Script

En amont de ce script, un transcript est lancé afin de loguer toute les opération effectuées. Une vérification de la présence du module ActiveDirectory ainsi que son chargement sont ensuite réalisées.

Le script appelle une fonction créée pour traiter tout objet AD (ou tableau d'objets AD) qui lui est passé. Pour ma part, je transmets en paramètre tous les contacts présents dans Active Directory. Cependant cette fonction peut très bien être utilisée avec des utilisateurs. Voici l'algolrithme mis en place dans la fonction Test-CertExpiration :

  1. Filtrage des objets pour ne conserver que ceux ayant au moins un certificat présent dans l'attribut userCertificate.
  2. Boucle ForEach sur tous les utilisateurs :
    1. Boucle For sur tous les certificats de l'utilisateur (pas de ForEach afin d'être certain de la position du certificat dans l'attribut userCertificate)
    2. Analyse de la date d'expiration
    3. Si le paramètre DeleteExpired est présent alors on supprime le certificat dans Active     Directory s'il n'est plus valide.
    4. Si le paramètre DeleteExpired n'est pas présent alors deux attributs sont ajoutés à l'objet     AD :
      1. CertExpired : contient les index des certificats expirés dans le tableau de l'attribut userCertificate
      2. CertValid : contient les index des certificats valides dans le tableau de l'attribut userCertificate
  3. Si le paramètre Export et ExportPath ont été renseigné alors le tableau d'objet AD est exporté sous format CSV avec la liste des index des certificats valides et expirés.

Ci-dessous, vous trouverez le script intégralement commenté. A noter, que le compte exécutant ce script doit posséder les droit suffisants à la modifications des objets AD concernés (via une délégation par exemple).

Ici, la fonction Test-CertExpiration, est utilisée en mode suppression, cependant il est aussi possible de se servir du mode Export pour n'effectuer qu'un simple audit (logué dans un fichier) des objets concernés via la commande suivante :

$ADObjets est un tableau d'objets Active Directory.

Il est enfin possible de ne donner qu'un tableau d'objets AD à traiter sans spécifier le mode export ou suppression :

Dans ce cas, un tableau d'objets AD est retourné. Pour chaque objet, les attributs CertExpired et CertValid sont ajoutés.

Quelques points clés du fonctionnement de la fonction Test-CertExpiration :

Les paramètres Export et DeleteExpired sont de type switch et ne peuvent apparaître ensemble. Le paramètre ExportPath est dynamique et n'est disponible que si le paramètre Export a été choisi.

Pour information, il n'est pas nécessaire de paralléliser le processus de contrôle du certificat. Après un test effectué sur plus de 90000 contacts Active Directory, il s'avère que ce dernier a duré moins de 5 minutes. Utiliser du multi thread (workflow ou job Powershell) alourdirai le script et ralentirai le processus au lieu de l'accélérer.

Powershell : Connexion à Exchange Online

Introduction

Powershell est intégré dans tous les nouveaux produits et services de Microsoft. Grâce à ce langage de scripting il est tout naturellement possible d'administrer Exchange Online via le Remote Powershell. Au delà d'offrir des possibilités d'automatisation, certaines opérations ne sont réalisables que par ce biais.

La gestion d'Exchange Online se décompose en 2 parties :
L'installation d'un module Powershell pour la gestion des utilisateurs dans l'Active Directory Azure
La connexion à Exchange Online pour l'administration des paramètres de la messagerie et des boîtes aux lettres.

Cet article s'adresse donc aux personnes souhaitant administrer Exchange Online mais aussi à ceux qui utilisent Active Directory dans le cloud Azure.

Nous allons voir comment accéder à la gestion des utilisateurs sur Office 365, à leurs boîte email Exchange Online. Je montrerai aussi quelques erreurs courantes (problème d'installation et connexion derrière un proxy) que l'on peut rencontrer lors d'une interaction avec Office 365 ainsi que leurs résolutions.

A noter que, comme les sessions distantes Powershell sont apparues avec la version 2, il est nécessaire de posséder à minima cette version pour exécuter les opérations que nous allons voir.

Gestion des utilisateurs Microsoft Online (Azure Active Directory)

Installation :

L'administration des utilisateurs ne peut se faire que via l'installation d'un module Powershell. Ce dernier nécessite un prérequis : Microsoft Online Services Sign-In Assistant. Ci dessous, vous trouverez les liens de téléchargement de ce dernier :

Microsoft Online Services Sign-In Assistant– 32 bit version
http://go.microsoft.com/fwlink/?linkid=236299
Microsoft Online Services Sign-In Assistant – 64 bit version
http://go.microsoft.com/fwlink/?linkid=236300

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

Microsoft Online Services Module for Windows PowerShell (32-bit version)
http://go.microsoft.com/fwlink/?linkid=236298
Microsoft Online Services Module for Windows PowerShell (64-bit version)
http://go.microsoft.com/fwlink/?linkid=236297

Vérification de l'installation :

Pour vérifier que le module est opérationnel, il suffit de l'importer et de se connecter aux services MSOnline (en s'authentifiant lorsque c'est demandé) :
On peut ensuite utiliser les commandes comme :

Erreurs rencontrées :

1/ Lors de l'installation de Microsoft Online Services Sign-In Assistant, j'ai rencontré l'erreur suivante :

In order to install Windows Azure Active Directory Module for Windows PowerShell, you must have Microsoft Online Services Sign-In Assistant version 7.0 or greater installed on this computer.

Pour résoudre ce problème, il m'a fallu installer la beta de ce prérequis disponible dans le lien ci-dessous :
http://www.microsoft.com/en-us/download/details.aspx?id=39267

2/ Si un proxy est utilisé lors de la connexion au cloud de Microsoft, alors on obtient l'erreur suivante :

Erreur Proxy

Pour résoudre ce problème, il faut configurer le proxy ainsi que les paramètres d'authentification à utiliser :

Par défaut Powershell utilise le proxy d'Internet Explorer ; on peut reconfigurer le paramétrage du proxy avec la commande « netsh ».

On spécifie une URL de proxy (première ligne) ou on indique que l'on souhaite utiliser les paramètres présents dans Internet Explorer (seconde ligne) :
Aussi, on peut aussi supprimer toute configuration du proxy via la commande suivante :
Pour que Powershell puisse s'authentifier, il faut indiquer un couple login / mot de passe. En général, on utilisera ceux de la session actuellement ouverte. Pour effectuer cette opération, il suffit d'exécuter la commande suivante :

Connexion à Exchange Online

Implémentation :

Le but de l'opération est d’importer toutes les commandes que l’on connait sous Exchange comme « Get-Mailbox » qui existent aussi sous Exchange Online.
Voici les quelques lignes Powershell permettant d'ouvrir une PSSession vers Exchange Online en spécifiant un compte utilisateur pour s'authentifier puis d'importer les cmdlets Exchange. A noter que la liste des commandes disponibles variera en fonction des droits du compte utilisé (grâce à RBAC).

Erreur rencontrée :

Comme pour la gestion des utilisateurs Active Directory dans le cloud, une configuration particulière est attendue lorsque l'on essaie de se connecter en passant par un proxy. L'erreur générique suivante apparaît :

Erreur Proxy Exchange

Pour résoudre ce problème, il est possible d'utiliser la même méthode que précédemment. Cependant, on peut aussi définir les paramètres des sessions Powershell distantes et ainsi configurer un proxy. Dans l'exemple ci-dessous nous utiliserons le proxy défini dans Internet Explorer :

La variable $Credential contient les paramètres d’authentification.

Création de tableaux dynamique en Powershell

Nous disposons d’une variable de type tableau avec comme informations des utilisateurs et leurs villes.

Nous allons ici créer dynamiquement une variable pour chaque site présent dans la variable $users et y affecter les utilisateurs.

 

image

Nous allons créer une variable de type tableau dans lesquels nous allons récupérer tous les sites disponibles dans notre variable $users.

$sites=@()

Nous alimentons maintenant la variable $sites.

 

foreach ($user in $users)

{

$sites+=$user.extensionAttribute8

}

$sites=$sites |sort | Get-Unique

 

Résultats :

image

 

Maintenant nous allons créer pour chacun des sites récupérés une variable avec pour nom la valeur récupéré dans la variable $sites

$sites | %{New-Variable -Name $_ -value @() -ErrorAction SilentlyContinue; if ($? -eq $true){write-host "variable créé : $_"}}

Résultats :

image

 

 

Maintenant nous allons alimenter dans les variables créés précédemment dynamiquement les utilisateurs présents dans les sites

foreach ($user in $users)

{

$VariableValue = $Null

$user.extensionAttribute8 |%{$VariableValue = @(((Get-Variable $_).Value)+$user);Set-Variable -name $_ -value $VariableValue}

}

Résultats :

image

image

image

image

image

image

image

 

 

 

Audit de droits administrateurs manquant sur une liste de fichiers

Nous allons pour l’exemple créer un fichier n’ayant pas le droit administrateurs.

 

image

 

Les autres fichiers ont bien le droit administrateurs dans leurs ACL.

Maintenant à l’aide d’un script, nous allons détecter le/les fichiers n’ayant pas l’identité “administrateurs”

Positionnons nous dans le répertoire nous intéressant et récupérons les différents éléments


cd "C:\Users\ato\Dropbox\Divers"
dirs=get-item *

 

maintenant on créer un tableau ou seront ajoutés les différents éléments n’ayant pas le droits administrateurs

Ensuite à l’aide du code ci dessous, nous allons être capable de récupérer dans le tableau $acl les éléments de notre recherche:

foreach ($d in $dirs)
{
    $ID=(get-acl $d).access | %{$_.identityreference}
    if ($ID -match "administrateurs"){}  #c’est ici que l’on définit l’acl manquant que l’on recherche
    else
    {
        $d.fullname
        $acl=$d.fullname
    }
}

 

Apres exécution du script, on peut voir que la variable $acl a bien été définis avec le fichier n’ayant pas le droit administrateur

image

Suppression d’items antérieurs à X jours en Powershell

Imaginons que vous devez supprimer à un emplacement donné des répertoires et/ou fichiers n’ayant pas été modifiés depuis 30 jours.

Ce petit script va permettre d’identifier les éléments correspondant à notre critère de recherche.

Positionnons nous dans le répertoire nous intéressant

cd "C:\Users\ato\Google Drive"

 

On obtient tous les items à notre emplacement

$items= get-item *

Un petit compteur pour identifier le nbre d’éléments qui nous sera retourné

$i=0

Nous allons maintenant récupérer le chemin absolu des items n’ayant pas été modifié depuis au moins 30 jours.

foreach ($item in $items)

{

$days=($item |New-TimeSpan).days

if ($days -ge 30) # c’est ici que nous définissons le nbre de jours

{

$i++

$item.fullname

}

}

echo "Nbres item $i"

Il y a donc 83 items n’ayant pas été modifié depuis au moins 30 jours.

 

image

 

Sur un total de 114 items

 

image

 

Il ne vous reste plus qu’à ajouter un remove-item dans la boucle de traitement si vous souhaitez supprimer les items renvoyés.

Desired State Configuration (Partie 2) : LocalConfigurationManager et Mode Push

Introduction

Cet article fait partie d’une série de 5 billets sur Desired State Configuration :

Desired State Configuration est disponible comme Powershell 4.0 sur Windows 2012 R2/8.1, Winsows 2012/8 et Windows 2008 R2/7.

Il s’agit de la seconde partie qui traite de la configuration du mode Push. Pour rappel, il existe deux modes d’application d’une configuration avec la technologie DSC :

  • Push
  • Pull

Ainsi, nous verrons comment le mode Push fonctionne. Nous nous attarderons ensuite sur la configuration du mode push via une ressource. Enfin, j’expliquerai comment appliquer une configuration en mode Push à distance.

Fonctionnement

Le mode Push est le mode par défaut dans Desired State Configuration. Chaque configuration est poussé par l’utilisateur via ligne de commande ou script directement depuis le serveur concerné ou à distance depuis un autre serveur. L’intérêt de la deuxième option est de centraliser les fichiers “.mof” sur un seul serveur. Pour appliquer la configuration il faut utiliser la commande Start-DscConfiguration (comme vu dans la partie 1).

Ressource LocalConfigurationManager

L’une des nombreuses ressources disponibles lors d’une configuration est nommée : LocalConfigurationManager. Cette dernière permet de définir quand et comment seront appliquées les configurations. Elle est décrite dans le lien ci-dessous :

http://technet.microsoft.com/en-us/library/dn249922.aspx

NB : Au 16/12/2013, le lien comporte des erreurs. Nous allons donc voir ici les différents attributs qui peuvent nous intéresser pour le mode Push.

La ressource LocalConfigurationManager s’utilise comme toutes les autres ressources de DSC. Il va donc être nécessaire de générer un “.mof” contenant cette ressource, puis l’appliquer. Pour récupérer la configuration actuelle  du LocalConfigurationManager  du serveur, il faut utiliser la commande :

001
Get-DscLocalConfigurationManager

 

Le résultat par défaut est le suivant :image Les attributs intéressants pour le mode Push sont :

  • RefreshMode : La valeur doit être à PUSH.
  • ConfigurationMode : Apply, ApplyAndMonitor, ApplyAndAutoCorrect sont les valeurs possibles. Apply définit qu’il faut simplement appliquer la configuration. ApplyAndMonitor ajoute une phase de contrôle et loguera les éventuelles dérives de configuration (dans l’observateur d’événements). ApplyAndAutoCorrect réapplique la configuration après chaque nouveau test, s’il y a une dérive.
  • RefreshFrequencyMins : Il s’agit de l’intervalle de temps pour l’actualisation du fichier de configuration. La valeur minimal est 15 minutes.
  • ConfigurationModeFrequencyMins : C'est le temps entre chaque vérification de conformité.
  • RebootNodeIfNeeded : C’est un booléen autorisant ou non le redémarrage automatique de la machine si celui-ci est nécessaire.

    Voici un exemple de script configurant la ressource LocalConfigurationManager :

    001
    002
    003
    004
    005
    006
    007
    008
    009
    010
    011
    Configuration SetPushMode
    {
        Node WEBSRV01 {
           
            LocalConfigurationManager {
                ConfigurationMode = "ApplyandMonitor" 
                RefreshMode = "Push"
                RefreshFrequencyMins = 30
            }
        }
    }

    On invoque ensuite le bloc Configuration (ligne 1) et on l’applique (ligne 2) afin que la configuration soit prise en compte.

    001
    002
    SetPushMode -OutputPath C:\DSCConfig
    Set-DscLocalConfigurationManager -Path C:\dscconfig\ -ComputerName WEBSRV01 -Credential "WEBSRV01\Administrator" -Verbose

    Ici, les paramètres Credendial et ComputerName sont renseignés permettant d’appliquer la configuration de la ressource à distance.

    Pour que la connexion à distance fonctionne, il est nécessaire de pouvoir se connecter en WMI à distance à “root/Microsoft/Windows/DesiredStateConfiguration”. Pour configurer ce pré-requis, il faut se référer à l’article suivant : http://blog.piservices.fr/post/Powershell-Gestion-a-distance.aspx.

Application d’une configuration à distance

Nous avons vu l’application d’une configuration en mode Push lors de la partie 1. Nous verrons donc ici simplement un complément permettant d’appliquer une configuration à distance. On peut ainsi imaginer un script s’exécutant sur un serveur central possédant tout les fichiers “.mof”. Ce script bouclera sur l’ensemble des serveurs d’une liste et lance les commandes de configuration. Dans cet exemple, on considère qu’un fichier “.mof” a été généré dans “C:\DSCConfig”.

001
Start-DscConfiguration -ComputerName WEBSRV01 -Path C:\dscconfig -Verbose -Wait

Les paramètres utilisés ainsi que les pré requis sont les mêmes que précédemment, seul la cmdlet utilisée change.

Desired State Configuration (Partie 1) : Introduction et syntaxe

Introduction

Powershell 4.0 (introduit avec Windows 2012 R2) apporte son lot de nouveautés. La plus importante est : Desired State Configuration.

En entreprise, il existe deux problématiques récurrentes au sein d’un système d’informations :

  • L’augmentation du nombre de serveurs
  • Le changement

Desired State Configuration apporte une solution à ces questions en proposant une solution pour l’automatisation des déploiements et la maintenance des serveurs (contrôle et retour en conformité).

Avec cette fonctionnalité, il sera possible de déployer rapidement et à grande échelle des améliorations à une infrastructure, tout en s’assurant que les systèmes ne varient pas au cours du temps.

Par exemple, on peut vouloir s’assurer qu’un groupe de serveurs web possède :

  • le rôle adéquat correctement configuré,
  • les services nécessaires démarrés
  • les sources valides d’un site web copiées dans le bon répertoire
  • la bonne adresse IP pour chaque serveur.

DSC permet de configurer un serveur via un script au travers d’une syntaxe simple (similaire aux fonctions Powershell). Les possibilités de configuration sont infinies (rôles, groupes et utilisateurs locaux, registre…). Cette configuration peut se faire en local ou à distance. De plus, au delà de la première application de la configuration du serveur, il existe des mécanismes de contrôles. Avec Desired State Configuration, Windows peut automatiquement vérifier si sa configuration est correcte et la remettre à niveau s’il y a eu un changement anormal. Ainsi, les dérives de configuration sont évitées !

    Pour appliquer une configuration, il existe deux modes :

  • Push : La configuration est envoyé au serveur
  • Pull : La configuration est demandé par le serveur client vers un serveur centrale qui gère toutes les configurations possibles.

Grâce au scripting il va être possible d’appliquer des configuration à des groupes de serveurs.

DSC est basé sur les fichiers “.mof”. Il est possible de les générer de la façon que l’on souhaite (éditeur de texte par exemple). Powershell 4.0 permet de simplifier la génération de ses fichiers notamment grâce à l’auto complétion mais aussi avec syntaxe accessible. Via le module PSDesiredStateConfiguration, on peut créer ses fichiers et les utiliser pour appliquer une configuration.

Cet article fait partie d’une série de 5 billets sur Desired State Configuration :

Desired State Configuration est disponible comme Powershell 4.0 sur Windows 2012 R2/8.1, Winsows 2012/8 et Windows 2008 R2/7.

Les ressources

Les éléments que l’on va pouvoir configurer sont appelés ressources.

Voici quelques exemples de ressources disponibles nativement : l’exécution de services, de clés de registre, de scripts ou de variables d’environnement. Les groupes et utilisateurs locaux ainsi que la copie de fichiers sur un serveur est aussi gérable. Les possibilités sont infinies.

Il est aussi possible de créer ses propres ressources, en définissant la façon de réaliser la configuration sur le serveur et de tester la conformité. Ainsi on peut imaginer une ressource qui s’occupera de la gestion du fichier “hosts”, un autre peut gérer la configuration IP ou même la présence et l’activation de règle firewall.

La liste des ressources disponibles nativement est listé dans le lien suivant : http://technet.microsoft.com/en-us/library/dn249921.aspx

La syntaxe

La syntaxe Powershell implémentée se base sur le mot clé Configuration. Voici un exemple :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
Configuration TestDSC 
{ 

  Node WEBSRV01 #Nom du serveur
  { 
    WindowsFeature IIS 
    { 
      Ensure = “Present” #Vérifie que le rôle est présent
      Name = “Web-Server” #Nom du rôle ou de la fonctionnalité à vérifier
    } 

    File DirectoryCopy
    {
        Ensure = "Present" #Vérifie que les fichiers/dossiers sont présents
        Type = "Directory" #Type d'objet à vérifier
        Recurse = $true #Inclus les fichiers/dossiers enfants
        SourcePath = "\\FILESRV01\MyWebSite" #Chemin des sources
        DestinationPath = "C:\inetpub\wwwroot\MyWebsite" #Destination où doivent se trouver les données
    }
   
    Group ViewerGroup
    {
        Ensure = "Present" #Vérifie qu'un groupe est présent
        GroupName = "Viewer" #Nom du groupe
    }
  } 
}

La déclaration se fait donc via des blocs entre accolades. Dans un bloc de type Configuration, on a un ou plusieurs blocs Node. Pour chaque bloc Node, un fichier MOF sera généré. A côté de ce mot clé, on inscrit le nom du serveur qui possédera cette configuration. A l’intérieur de chacun de ses blocs se trouvent les ressources que l’on souhaitent configurer. Dans l’exemple précédent, on retrouve dans l’ordre les 3 ressources suivantes :

  • WindowsFeature : S’assure que le rôle IIS est installée.
  • File : Vérifie que les fichiers sont bien présents sur le répertoire de destination.
  • Group : Constate que le groupe local Viewer existe.

Dans le cas où l’une des ressources retournerait un résultat incorrect alors l’opération serait réalisée afin de mettre l’ordinateur en conformité. Par exemple, pour les sources du site web (Ressource WebsiteDirectory), le fichier de configuration possède le chemin source et la destination.

Pour générer le fichier MOF, il faut appeler notre configuration comme une fonction Powershell :

001
TestDSC -OutputPath c:\DSCConfig

Le paramètre OutputPath (facultatif) définie le dossier où vont être stockés les fichiers de configuration. Le fichier créé portera le nom de la machine portant cette configuration (ici WEBSRV01).

A l’instar des fonctions, on peut utiliser des paramètres. Voici, un exemple similaire au précédent où l’on spécifie la source et la destination des fichiers du site web ainsi qu’une liste de nom d’ordinateur auxquels appliquer cette configuration.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
Configuration TestDSC 
{ 
 
  param(
    [Parameter(Mandatory=$true)]
    [String[]]$Computers,
    [Parameter(Mandatory=$true)]
    [String]$SourceWeb,
    [Parameter(Mandatory=$true)]
    [String]$DestinationWeb 
  )

  Node $Computers 
  { 
    WindowsFeature IIS 
    { 
      Ensure = “Present” 
      Name = “IIS-Server” 
    } 

    File DirectoryCopy
    {
        Ensure = "Present"
        Type = "Directory"
        Recurse = $true 
        SourcePath = $SourceWeb
        DestinationPath = $DestinationWeb 
    }

  } 
}

Il y aura autant de fichiers MOF générés que de noms dans le paramètre Computers. Voici la commande pour créer les fichiers MOF :

001
002
003
TestDSC -Computers @("WEBSRV01","WEBSRV02","WEBSRV03") `
-SourceWeb "\\FILESRV01\MyWebSite" -DestinationWeb "C:\inetpub\wwwroot\MyWebsite"`
-OutputPath c:\DSCConfig

Application d’une configuration

Ici, nous allons aborder brièvement l’application d’une configuration en local via le mode Push. Le détail de ce mode est expliqué dans la partie 2 de l’article sur Desired State Configuration. On utilise la commande Start-DscConfiguration. Voici l’explication des paramètres utilisées dans la commande ci-dessous :

  • Wait : Ne rend pas la main à l’utilisateur tant que la commande est en cours d’exécution (Par défaut l’exécution de DSC se fait en arrière plan).
  • Verbose : Affiche les opérations effectuées.
  • Path : Le dossier où se toruve le fichier MOF (DSC choisi le fichier portant le nom de l’ordinateur).
001
Start-DscConfiguration -Wait -Verbose -Path C:\DSCConfig

Il ne peut y avoir qu’une configuration active par machine. Si une seconde configuration est appliquée, il n’y aura plus de contrôle de conformité sur les ressources non présentes dans la nouvelle configuration.

Powershell : Gestion à distance

Introduction

L’une des forces de Powershell est la gestion à distance de serveurs, de postes clients et d’applications (comme Exchange, Sharepoint,…). Communément appelée Remote Powershell, elle est apparue avec Powershell 2.0 et donc disponible à partir de Windows Server 2003 (R2) SP2. Cette fonctionnalité n’est pas activée par défaut sur les systèmes d’exploitation Windows hors Windows 2012 (R2). Pour réaliser cette opération il faut lancer la commande suivante en mode administrateur :

001
Enable-PSRemoting

Cette commande permet de démarrer le service WinRM et d’ouvrir les règles de firewall adéquates si celui-ci est activé (port 5985).

Dans cet article, nous verrons comment se connecter à une machine (qu’elle soit dans le même domaine ou dans un workgroup) ou à une application comme Exchange, comment donner la possibilité à un utilisateur de se connecter via Remote Powershell et enfin l’accès WMI distant.

Entre deux ordinateurs du domaine

Il s’agit du cas le plus simple. Pour se connecter à une machine du même domaine, il suffit d’utiliser la commande suivante :

001
Enter-PSSession -ComputerName SERVER01

Il est possible de spécifier l’utilisateur avec lequel on souhaite se connecter via le paramètre Credential :

001
Enter-PSSession -ComputerName SERVER01 -Credential SERVER01\Administrator

Ainsi, un prompt demandant le mot de passe apparaîtra.

Depuis un ordinateur d’un workgroup vers un ordinateur en domaine (et vice versa)

Pour se connecter à une machine appartenant à un domaine différent ou à un workgroup, il est nécessaire que le poste source contienne l’ordinateur distant dans sa liste de client de confiance. Pour ajouter une nouvelle machine, il faut utiliser la commande suivante en mode administrateur :

001
002
003
Set-Item WSMan:\localhost\Client\TrustedHosts -Value *
#OU
Set-Item WSMan:\localhost\Client\TrustedHosts -Value SERVER02

Le paramètre Value peut prendre les valeurs suivantes :

  • un nom explicit d’une machine (SERV01)
  • * : pour accepter toutes les machines (Ceci n’est pas recommandé)
  • *.myenterprise.com : pour accepter toutes les machines possédant le suffixe DNS myenterprise.com

Connexion à distance à une application (Exchange)

Via le couple de commande New-PSSession / Import-PSSession, il est possible de se connecter à une infrastructure Exchange et importer les commandes relatives à la messagerie de Microsoft sur son poste sans avoir à installer le snapin. De plus, seul les commandes accessibles à l’utilisateur seront chargées sur le poste utilisateur (grâce aux mécanismes de RBAC).

001
002
$Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri ` http://MYSERVER/powershell -Credential MYENTERPRISE\User_1
Import-PSSession $Session -AllowClobber | Out-Null

La première ligne de commande crée une session qui se connecte à l’infrastructure Exchange (Attention il faut modifier la valeur MYSERVER et le nom d’utilisateur avec vos valeurs) tandis que la seconde importe les commandes sur l’ordinateur initialisant la connexion.

Sessions distantes et permissions

Afin de se connecter à distance, il est nécessaire de faire partie du groupe Administrators (ou Remote Management Users pour Windows 2012 et supérieur) soit en étant connecté directement avec le bon compte (par exemple via un utilisateur administrateur du domaine) soit en s’authentifiant en tant qu’administrateur via le paramètre Credential vu précédemment. Il est aussi possible de donner l’accès à d’autres utilisateurs via la commande suivante :

001
002
003
Set-PSSessionConfiguration Microsoft.Powershell -ShowSecurityDescriptorUI -Force
#Si l'on est sur un système 64 bits.
Set-PSSessionConfiguration Microsoft.Powershell32 -ShowSecurityDescriptorUI -Force

Une fenêtre s’affiche et il est possible d’ajouter un utilisateur ou un groupe (via le bouton Add) ainsi que des permissions associées. La permission Execute est suffisante  pour se connecter à distance.

image

NB : Sur Windows 2012 et supérieur, il est nécessaire d’ajouter une clé de registre sur l’ordinateur distant pour que les groupes Administrators et Remote Management Users aient le droit de se connecter via Remote Powershell :

Dans le noeud : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system

Il faut ajouter la clé DWord : LocalAccountTokenFilterPolicy avec la valeur 1.

Cette clé de registre s’applique aussi au chapitre suivant.

Gestion WMI à distance

Pour gérer le WMI à distance (via la commande Set-WmiInstance par exemple). Il faut réunir les 3 conditions suivantes sur le serveur auquel on souhaite se connecter :

  • Faire partie du groupe Administrators ou Remote Management Users ou WinRMRemoteWMIUsers__.
  • Avoir les permissions suffisantes sur la classe WMI.
  • Autoriser l’utilisateur dans la configuration DCOM du serveur.

Les deux dernières conditions sont seulement utiles dans le cas d’un utilisateur qui ne fait pas partie du groupe Administrators (ce dernier possède déjà toutes les permissions nécessaires).

    Gestion des permissions via WMI Control :
Pour cette opération il faut lancer une console MMC et ajouter le composant WMI Control. Effectuer un clic droit et choissisez Properties puis naviguer dans l’onglet Security. Dans la MMC, on sélectionne l’espace de noms qui nous intéresse et on clique sur le bouton Security. Cliquez sur Advanced (cette option plus complète, permet éventuellement d’étendre les permissions au classes enfantes).

image image

On ajoute l’utilisateur ou le groupe avec au minimum les permissions Enable Account et Remote Enable. Il sera surement nécessaire d’ajouter d’autres droits suivants l’action que l’on souhaite réaliser.

image

Autorisation de l’utilisateur dans la configuration DCOM :

En lançant la console dcomcnfg, aller dans Component Services, Computers, My Computer et effectuer un clic droit et choisir Properties.

Dans l’onglet COM Security, choisir Edit Limits dans la section Launch and Activation Permissions. Ajoutez l’utilisateur ou le groupe souhaité et activez l’ensemble des permissions pour avoir accès en local et à distance en WMI via Powershell.

image image

Quelques astuces Powershell

Introduction

Lorsque l'on développe des scripts Powershell, il y a un certain nombres de commandes génériques que l'on réutilise très souvent. Nous verrons aussi quelques astuces qui peuvent être utiles dans de nombreux scripts.

Astuces

Retrouver le dossier d'exécution du script :

Souvent, il arrive que l'on crée une bibliothèque de scripts. Un script peut en appeler un autre parce qu'il contient des fonctions. On peut aussi vouloir faire appel à un fichier de configuration. Beaucoup de scripts contiennent alors le chemin d'exécution via une variable qu'il convient de changer manuellement dès que le répertoire est modifié. Cela n'est cependant pas très portatif. Il est nettement plus intéressant de retrouver ce chemin dynamiquement.

La commande ci-dessous permet de retourner le dossier où se situe le script qui est en train de s'exécuter.

001
002
$RootFolder = Split-Path -Path $MyInvocation.MyCommand.Path 

On peut ensuite retrouver nos fichiers additionnels via des chemins relatifs calculés depuis celui que l'on vient de récupérer.

"$MyInvocation.MyCommand.Path" retourne le chemin du fichier.
A partir de ce dernier la commande "Split-Path" nous retourne uniquement le dossier dans lequel est contenu le script.

Connaître le contexte d'exécution (32 ou 64 bits) :

Il peut arriver que l'on souhaite lancer un exécutable spécifiquement depuis une instance Powershell x86 ou x64 car celui-ci n'existe pas dans un autre contexte.

Pour cela, il existe une astuce permettant de savoir quelle édition de Powershell (x86 ou x64) est lancée :

001
002
[System.IntPtr]::Size 

Cette commande nous donne la taille d'un pointeur sous la forme d'un entier. Lorsque l'invite de commande Powershell est en x64, cette valeur vaut 8. Dans le cas contraire il s'agit de 4. On peut facilement imaginer une structure conditionnel permettant de relancer un script automatiquement en Powershell x86 qui intègre un exécutable ne tournant que sur cette version.

001
002
003
004
005
006
if( [System.IntPtr]::Size -ne 4) { 
    #Chemin du script
    $Path = $myInvocation.InvocationName 
    #Invocation de Powershell x86 avec le même script à exécuter comme paramètre
    $Return = &"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" $Path 
}

Le script est-il exécuté en mode administrateur :

Dans le même esprit, il est possible de savoir si un script a été lancé en mode administrateur. En effet, certaines opérations peuvent exiger ce mode de fonctionnement :

001
002
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")

Bien évidemment il n'existe pas de commande pour relancer le script dans ce mode. On peut cependant inviter l'utilisateur à le faire.

Tester son script pour une autre version de Powershell :

Il peut arriver que l'on développe son script Powershell sur son poste client qui est en version 3 alors que le serveur qui le lance est lui en version 2. Afin d'être certain que ce script est compatible, il est possible d'indiquer la version de Powershell à utiliser. En voici un exemple ci-dessous :

test version

En version 3 il n'est plus nécessaire de faire d'Import-Module pour utiliser les cmdlets Active Directory, ce qui n'est pas le cas en Powershell 2. Nous voyons donc clairement la différence entre les 2 exécutions.

Appeler une librairie .NET :

Il existe de nombreuses méthodes pour charger une librairie .NET (sous forme de dll ou directement de code C# par exemple). Ici, nous en verrons une qui utilise la commande Powershell Add-Type :

Pour utiliser les Windows forms pour les interfaces graphiques.

001
002
Add-Type -AssemblyName "System.Windows.Forms"

Pour administrer IIS, on charge une dll depuis son emplacement sur le disque

001
002
Add-Type -Path "c:\windows\system32\inetsrv\microsoft.web.administration.dll"

Intégrer directement du code C# (il est aussi possible de le faire avec du code VBScript)

001
002
003
004
005
006
007
008
009
010
011
012
Main; Add-Type -TypeDefinition @"
public class Test
{
    public string Name {get;set;}
    public int Size {get;set;}
    public Test(string Name, int Size){
        this.Name = Name;
        this.Size = Size;
    }
}
"@

Toutefois lorsque la commande Add-Type sera exécutée il n'est pas possible de recharger une librairie qui aurait été modifiée (Cela est dû à .NET). En effet une librairie ne peut être déchargée. Il faut alors changer de session Powershell (c'est à dire lancer une nouvelle instance de Powershell).

Lync 2013 – Meeting personnalisés

Lors de la création d’un meeting Lync (via Outlook), le contenu de la demande peut paraitre très simpliste. Surtout quand l’intégration à la téléphonie n’est pas réalisée:

image Dans lync 2013, de nouvelles options sont disponibles pour rendre la demande de meeting plus personnalisé et adapté via des “meeting configuration” particulière. Voici les 4 nouveaux paramètres:

    • Logo URL
    • Help URL
    • Legal Text URL
    • Custom Footer Text

      Pour configurer ses élément il suffit d’éditer la configuration des meeting par default ou encore de certaines politiques appliquer a un partie des utilisateurs:

      image
    Il est aussi possible d’utiliser le Lync Management Shell via la commande:

      set-CsmeetingConfiguration avec les paramètres –LogoURL –Legalurl –helpURL –CustomFooterText.
      Une fois la configuration réaliser, les champs sont appliquer et les demandes de meeting prennent en compte les paramètres fixés:
    image Vous pouvez stocker les images directement sur le server FrontEnd Lync Server.