Audit Active Directory : Part 3 – les comptes utilisateurs

Sommaire

 

 

Introduction

Autant d’un point de vue sécurité qu’à titre informatif, il peut être intéressant d’auditer vos comptes utilisateurs Active Directory.

Pour cela, j’ai réalisé un script PowerShell qui va vous permettre de générer un rapport Excel tel que présenté ci-dessous.

{gallery}78-AUDITAD-USERS{/gallery}

 

 

 

 

 

Le script disponible depuis le lien suivant : http://gallery.technet.microsoft.com/scriptcenter/Generate-Excel-report-48c3f3b4

L’objectif de cet article est donc de vous expliquer la méthodologie appliquée pour la réalisation de ce script. Cela vous permettra de comprendre son fonctionnement et d’analyser les données présentées.

 

 

Collecter les informations nécessaires

La première étape est bien entendu de collecter tous les comptes utilisateurs depuis votre annuaire Active Directory. L’information collectée devra nous permettre de quantifier les objets utilisateurs, d’en définir l’état et d’énumérer les différentes configurations existantes.

Le but n’est pas de collecter toutes les propriétés de chaque utilisateur sachant que cela peut s’avérer très consommateur et par forcément très pertinent.

Nous allons simplement nous focaliser sur les propriétés standards nécessaires à l’identification de chaque compte utilisateur (distinguishedName, sAMAccountName…). Je m’appuie également sur certains attributs spécifiques me permettant donc de qualifier la configuration et l’état de chaque compte utilisateur :

  • pwdLastSet : indique la date du dernier changement du mot de passe. Cet attribut va permettre d’identifier les comptes ayant un mot de passe de plus de XX jours.
  • lastLogonTimestamp : une fois le niveau fonctionnel de domaine Windows Server 2003 activé au sein de votre infrastructure Active Directory, les contrôleurs de domaine utilisent cet attribut pour identifier la date de dernière ouverture de session. L’attribut n’est pas 100% fiable sachant que certains comptes utilisateurs sont exclusivement utilisés via des portails Web qui ne vont pas permettre de mettre à jour cet attribut. Toutefois, il reste le meilleur moyen pour identifier si un  compte utilisateur est inactif ou non.
  • accountexpires : cet attribut contient la date d’expiration d’un compte utilisateur. Il permettra donc d’identifier les comptes ayant expirés.
  • userAccountControl : cet attribut est particulièrement riche en information car il contient de nombreux indicateurs sur la configuration de chaque utilisateur (http://support.microsoft.com/kb/305144/fr).

 

Depuis Windows Server 2003, certains indicateurs de l’attribut userAccountControl ont été remplacé par l’attribut construit « msds-user-account-control-computed ». Nous trouverons entre autres les informations de verrouillage du compte te de l’expiration du mot de passe. Nous devrons donc également l’exploiter.

Le script génère donc un fichier CSV avec les informations suivantes :

  • displayName, distinguishedname, samaccountname, userPrincipalName : la valeur de chacun de ces attributs pour identifier le compte utilisateur. La liste n’est pas exhaustive. Il est possible que vous ayez besoin d’autres attributs…
  • useraccountcontrol: la valeur cet attribut est fournie uniquement à titre indicatif sachant que durant la collecte, l’attribut est déjà traité.
  • isPreAuthNotRequired: si l’option est activée, cela induit que le compte peut s’affranchir de la pré-authentification Kerberos et donc de mécanismes de sécurité supplémentaires.
  • isActive: indique que le compte est actif depuis une période spécifique (par défaut depuis 180 jours). La valeur de la période peut être changée grâce à paramètre « InactiveDays » du script.
  • isDESKeyOnly: permet d’utiliser la norme DES pour l’option de chiffrement qui est considéré comme obsolète.
  • isDisabled: spécifie si le compte est désactivé.
  • isExpired: informe que le compte est expiré.
  • isLocked: signale que le compte est verrouillé. Bien entendu, si vous avez une politique de déverrouillage de compte, l’information ne sera pertinente qu’au moment de la collecte.
  • isPwdNotRequired: indique si le compte peut utiliser un mot de passe vide. Cette option peut représenter un risque en termes de sécurité.
  • isPwdEncryptedTextAllowed: autorise le stockage de mots de passe par le biais d’un chiffrement réversible et donc n’assure nullement la protection du mot de passe.
  • isPwdOld: indique si le mot de passe est considéré comme étant obsolète (par défaut 120 jours). La durée d’obsolescence peut être modifiée via le paramètre « PasswordAge » du script.
  • isPwdNeverExpires: informe que le mot de passe n’a pas d’expiration. Un mot de passe qui n’expire jamais peut représenter une faille de sécurité.
  • isPwdExpired: permet de savoir si le mot de passe du compte utilisateur est expire.

Le rapport Excel s’appuie donc exclusivement sur la collecte de ces données. Afin de vous faciliter la vie, le script stocke ces données dans un fichier CSV afin de permettre soit de le traiter selon vos besoins ou tout simplement de pouvoir collecter les données et de générer les informations de manière séparée.

Le paramètre « CollectOnly » du script va permettre de collecter uniquement les données sans générer le fichier Excel. Le paramètre « ExistingData », quant à lui, va permettre de générer le  rapport Excel à partir d’un fichier de collecte existant.

 

 

Informations utiles sur le rapport Excel

Comme vous avez pu le voir en introduction, le rapport Excel contient trois graphiques différents :

Volumetry of user accounts : ce graphique permet d’avoir le nombre total d’objets utilisateur de votre domaine. Il permet également de voir le pourcentage de comptes actifs/inactifs. Plus le pourcentage de comptes inactifs est élevé plus cela indique qu’il faudra intégrer une stratégie de cycle de vie sur les comptes utilisateurs.

Status of user accounts : le deuxième tableau liste les différents états possibles de vos comptes utilisateurs actifs et inactifs. J’ai décidé de scinder l’information entre les utilisateurs actifs et inactifs sachant qu’elle n’est pas forcément très pertinente pour des comptes inactifs… Le graphique se focalise sur l’état des comptes actifs. Notez également qu’un compte peut être dans plusieurs états simultanément… hormis pour l’état dit « standard » qui est exclusif.

Configuration of user accounts : à la manière du deuxième tableau, il liste les différentes configurations de vos comptes utilisateurs actifs et inactifs et fourni un graphique uniquement sur les utilisateurs actifs. Un compte utilisateur peut avoir plusieurs paramètres associés.

 

 

Conclusion

Avec cette troisième partie sur l’audit d’Active Directory, je vous ai proposé une solution rapide et simple pour collecter et traiter les informations de l’ensemble de vos comptes utilisateurs. Le prochain article se focalisera plus spécifiquement sur les comptes disposant de privilèges.

Manipuler Excel avec PowerShell : Part 4 – Ajouter un graphique

Dans l’article précédent, je vous ai montré comment mettre en forme votre tableau sous Excel à l’aide de PowerShell.

Nous avions obtenu le résultat ci-dessous.

 

Dans cet article, je vais vous montrer comment ajouter un graphique.

 

On commence par instancier notre objet de type « Chart ».

{codecitation style= »brush: PowerShell »}

$Chart = $WorkSheet.Shapes.AddChart().Chart

{/codecitation}

 

On va maintenant définir le type de notre graphique. Pour cela, il faut choisir parmi la longue liste que propose Excel. Ils sont énumérés depuis le lien http://msdn.microsoft.com/en-us/library/office/bb241008(v=office.12).aspx avec la valeur correspondante. Je vais partir sur un « histogramme 3D groupé ».

{codecitation style= »brush: PowerShell »}

$Chart.ChartType = 54

{/codecitation}

 

On peut spécifier également un style à notre graphique via la propriété « ChartStyle ». Il est assez dur de les identifier et d’ailleurs la documentation Microsoft parle d’une valeur possible comprise entre 1 et 48 mais j’ai pu définir mon style à une valeur bien plus élevée… J’ai donc fait un petit try-catch au cas où…

{codecitation style= »brush: PowerShell »}

try

{

$Chart.ChartStyle = 288

}

catch

{

$chart.ChartStyle = 1

}

{/codecitation}

 

On va continuer sur la mise en forme. On va désactiver les légendes à l’aide de la propriété « HasLegend ». On va activer le titre avec les propriétés « HasTitle » et « Text ».

{codecitation style= »brush: PowerShell »}

$Chart.HasLegend = $false

$Chart.HasTitle = $true

$Chart.ChartTitle.Text = « Production de bananes (en tonnes) »

{/codecitation}

 

Nous en avons terminé avec la mise en forme… On va s’attaquer aux données. On va ajouter une nouvelle série avec les années en abscisse (propriété « XValues ») et les tonnes en ordonnée (propriété « Values »). Pour cela on va utiliser des étendues.

{codecitation style= »brush: PowerShell »}

$Chart.SeriesCollection(1).XValues = $WorkSheet.Range($WorkSheet.Cells.Item(4,1),$WorkSheet.Cells.Item(7,1))

$Chart.SeriesCollection(1).Values = $WorkSheet.Range($WorkSheet.Cells.Item(4,2),$WorkSheet.Cells.Item(7,2))

{/codecitation}

 

Il y a différentes solutions en fonction des données à traiter, le nombre de séries ou le type de graphique mais vous avez déjà un bon exemple à votre disposition.

La toute dernière étape est le positionnement du graphique… A ma connaissance, la meilleure solution est de s’appuyer sur une étendue pour définir le positionnement et la taille. Ça pourrait paraitre plus compliqué mais au final vous verrez que s’est nettement plus pratique, surtout si vous êtes maniaque…

On créée donc une nouvelle étendue.

{codecitation style= »brush: PowerShell »}

$RangePositionChart = $WorkSheet.Range($WorkSheet.Cells.Item(10,1),$WorkSheet.Cells.Item(25,4))

{/codecitation}

 

On va ensuite utiliser l’objet parent contenant le graphique et définir la taille et le positionnement par rapport à notre étendue définie préalablement.

{codecitation style= »brush: PowerShell »}

$ChartObj = $Chart.Parent

$ChartObj.Height = $RangePositionChart.Height

$ChartObj.Width = $RangePositionChart.Width

$ChartObj.Top = $RangePositionChart.Top

$ChartObj.Left = $RangePositionChart.Left

{/codecitation}

 

Et voila le résultat !

 

Et le script au complet:

{codecitation style= »brush: PowerShell »}

[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo] « en-US »

 

$Excel = New-Object -ComObject « Excel.Application »

 

$WorkBook = $Excel.Workbooks.Add()

 

$WorkSheet = $WorkBook.WorkSheets.Add()

$WorkSheet.Name = « Production de bananes »

$WorkSheet.Select()

 

$WorkSheet.Cells.Item(1,1) = « Production annuelle de bananes »

 

$ArrProduction = @((‘2010’,’4.5’),(‘2011’,’12’),(‘2012’,’11.5’),(‘2013’,’15’))

 

$WorkSheet.Cells.Item(3,1) = « Année »

$WorkSheet.Cells.Item(3,2) = « Production (en tonnes) »

 

$InitialRow = 4

 

for ( $i=0; $i -lt $ArrProduction.Count; $i++ )

{

$WorkSheet.Cells.Item($InitialRow,1) = $ArrProduction[$i][0]

$WorkSheet.Cells.Item($InitialRow,2) = [decimal] $ArrProduction[$i][1]

$InitialRow++

}

 

$RangeTitle = $WorkSheet.Range($WorkSheet.Cells.Item(1,1),$WorkSheet.Cells.Item(1,2))

$RangeTitle.MergeCells = $true

$RangeTitle.Style = ($WorkBook.Styles.Item(43)).Name

$RangeTitle.HorizontalAlignment = [Microsoft.Office.Interop.Excel.XlHAlign]::xlHAlignCenter

$RangeTitle.ColumnWidth = 20

 

$RangeTable = $WorkSheet.Range($WorkSheet.Cells.Item(3,1),$WorkSheet.Cells.Item(7,2))

$ListObject = $WorkSheet.ListObjects.Add(1,$RangeTable,$null,1,$null)

$ListObject.TableStyle = « TableStyleLight6 »

 

$ListObject.ShowTotals = $true

$ListObject.ShowHeaders = $true

$ListObject.ShowAutoFilterDropDown = $false

 

$RangeSort = $WorkSheet.Range($WorkSheet.Cells.Item(4,1).Address($False,$False))

$WorkSheet.Sort.SortFields.Add($RangeSort,0,1) | Out-Null

$WorkSheet.Sort.SetRange($RangeTable)

$WorkSheet.Sort.Header = 1

$WorkSheet.Sort.Apply()

 

$Chart = $WorkSheet.Shapes.AddChart().Chart

$Chart.ChartType = 54

 

try

{

$Chart.ChartStyle = 288

}

catch

{

$chart.ChartStyle = 1

}

 

$Chart.HasLegend = $false

$Chart.HasTitle = $true

$Chart.ChartTitle.Text = « Production de bananes (en tonnes) »

 

$Chart.SeriesCollection(1).XValues = $WorkSheet.Range($WorkSheet.Cells.Item(4,1),$WorkSheet.Cells.Item(7,1))

$Chart.SeriesCollection(1).Values = $WorkSheet.Range($WorkSheet.Cells.Item(4,2),$WorkSheet.Cells.Item(7,2))

 

$RangePositionChart = $WorkSheet.Range($WorkSheet.Cells.Item(10,1),$WorkSheet.Cells.Item(25,4))

$ChartObj = $Chart.Parent

$ChartObj.Height = $RangePositionChart.Height

$ChartObj.Width = $RangePositionChart.Width

$ChartObj.Top = $RangePositionChart.Top

$ChartObj.Left = $RangePositionChart.Left

 

$WorkBook.SaveAs(« c:\temp\MaProductionDeBananes.xlsx »)

$Excel.Visible = $true

{/codecitation}

 

Grâce à cette séries d’articles, v devriez avoir bonnes bases pour commencer à générer vos tableaux et graphiques sur Excel à l’aide de Powershell.

Si vous voulez un exemple plus complexe, vous pouvez également consulter le code d’un de mes scripts depuis le lien technet suivant : http://gallery.technet.microsoft.com/scriptcenter/Generate-Excel-report-48c3f3b4

Il y a également de très nombreux exemples en VBA sur Internet qui vous permettra de vous guider sur les différentes méthodes et propriétés à utiliser.

Enfin, vous avez également le site MSDN dont j’ai fait assez souvent référence et qui est plutôt bien documenté !

Pour les autres articles sur le sujet:

Manipuler Excel avec PowerShell : Part 3 – Mettre en forme un tableau

Dans l’article précédent, je vous ai montré comment appliquer un style à une cellule pour obtenir le fichier Excel suivant:

 

Maintenant, on va aller un peu plus loin et on va manipuler le tableau et lui appliquer un style.  On va définir l’étendue de notre tableau (dans notre exemple de A3 à B7) :

{codecitation style= »brush: PowerShell »}

$RangeTable = $WorkSheet.Range($WorkSheet.Cells.Item(3,1),$WorkSheet.Cells.Item(7,2))

{/codecitation}

 

On va définir notre tableau en un type « ListObjects » (http://msdn.microsoft.com/en-us/library/ff196851(v=office.14).aspx)  et en utilisant la méthode « add() » (http://msdn.microsoft.com/en-us/library/office/bb211863(v=office.12).aspx). Ceci va nous permettre de profiter de l’ensemble des fonctions.

{codecitation style= »brush: PowerShell »}

$ListObject = $WorkSheet.ListObjects.Add(1,$RangeTable,$null,1,$null)

{/codecitation}

Nous n’avons plus qu’à appliquer un style de tableau Excel existant. Pour obtenir la liste complète, vous pouvez utiliser la commande « $WorkBook.TableStyles | ft name ». Il s’agit de la liste disponible depuis « Mettre sous forme de tableau » sous Excel.

 

Je vais appliquer le style « TableStyleLight6 »:

{codecitation style= »brush: PowerShell »}

$ListObject.TableStyle = « TableStyleLight6 »

{/codecitation}

Comme c’était le cas pour les styles de cellules, on peut appeler un style de tableau par son nom ou par son index. Il semblerait toutefois que les noms des styles de tableau ne soient pas traduits dans la langue locale… Par contre, certains styles peuvent avoir le même nom et être différents entre les versions d’Excel. C’est le cas du style « TableStyleLight6 » qui n’est pas le même entre Excel 2007 et Excel 2013… Je n’ai pas de solution miracle sachant que la création d’un style de tableau est beaucoup complexe que la création d’un style de cellules.

 

On pourrait affiner la mise en forme en permettant, par exemple, l’affichage de la ligne des totaux :

{codecitation style= »brush: PowerShell »}

$ListObject.ShowTotals = $true

{/codecitation}

…ou en désactivant le filtrage automatique :

{codecitation style= »brush: PowerShell »}

$ListObject.ShowAutoFilterDropDown = $false

{/codecitation}

C’est un exemple parmi tant d’autres… mais voici ce que l’on peut déjà obtenir visuellement.

 

Pour conclure cet article, on va corser un peu tout cela et on va essayer de trier les données. L’objectif est de classer par ordre croissant la production de manière automatique. Je ne vous cache que j’ai eu pas mal de difficultés pour y arriver et qu’il y a peut-être plus simple…

Premièrement, je défini l’étendue sur laquelle portera le tri. Je désigne simplement la première cellule concernée soit la cellule B4.

{codecitation style= »brush: PowerShell »}

$RangeSort = $WorkSheet.Range(« B4 »)

{/codecitation}

J’aurai pu très bien utiliser la valeur numérique pour identifier la position de la cellule. Ça peut être très pratique lorsque l’on veut améliorer l’automatisation. Par contre, comme la fonction « Range » ne peut pas interpréter la position d’une cellule par sa valeur numérique seule, il faut la convertir.

{codecitation style= »brush: PowerShell »}

$RangeSort = $WorkSheet.Range($WorkSheet.Cells.Item(4,2).Address($False,$False))

{/codecitation}

On utilise ensuite la méthode SortFields.Add() pour la création de notre tri (http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.sortfields.add.aspx). La syntaxe est .Add(MonEtendue, SortOn, Order, CustomOrder, DataOption) (consulter les liens pour obtenir les différentes valeurs possibles).

{codecitation style= »brush: PowerShell »}

$WorkSheet.Sort.SortFields.Add($RangeSort,0,1) | Out-Null

{/codecitation}

On définit l’étendue affectée par le tri. En l’occurrence il s’agit de notre tableau.

{codecitation style= »brush: PowerShell »}

$WorkSheet.Sort.SetRange($RangeTable)

{/codecitation}

Il nous reste plus qu’à exclure l’entête du triage à l’aide la propriété « Header » de l’objet « Sort ». Pour la liste des valeurs possibles consulter le lien http://msdn.microsoft.com/fr-fr/library/office/ff838812.aspx.

{codecitation style= »brush: PowerShell »}

$WorkSheet.Sort.Header = 1

{/codecitation}

Nous achevons le tri via la méthode Apply().

{codecitation style= »brush: PowerShell »}

$WorkSheet.Sort.Apply()

{/codecitation}

Et voila le résultat!

 

Et le script au complet:

{codecitation style= »brush: PowerShell »}

[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo] « en-US »

 

$Excel = New-Object -ComObject « Excel.Application »

 

$WorkBook = $Excel.Workbooks.Add()

 

$WorkSheet = $WorkBook.WorkSheets.Add()

$WorkSheet.Name = « Production de bananes »

$WorkSheet.Select()

 

$WorkSheet.Cells.Item(1,1) = « Production annuelle de bananes »

 

$ArrProduction = @((‘2010’,’4.5’),(‘2011’,’12’),(‘2012’,’11.5’),(‘2013’,’15’))

 

$WorkSheet.Cells.Item(3,1) = « Année »

$WorkSheet.Cells.Item(3,2) = « Production (en tonnes) »

 

$InitialRow = 4

 

for ( $i=0; $i -lt $ArrProduction.Count; $i++ )

{

$WorkSheet.Cells.Item($InitialRow,1) = $ArrProduction[$i][0]

$WorkSheet.Cells.Item($InitialRow,2) = [decimal] $ArrProduction[$i][1]

$InitialRow++

}

 

$RangeTitle = $WorkSheet.Range($WorkSheet.Cells.Item(1,1),$WorkSheet.Cells.Item(1,2))

$RangeTitle.MergeCells = $true

$RangeTitle.Style = ($WorkBook.Styles.Item(43)).Name

$RangeTitle.HorizontalAlignment = [Microsoft.Office.Interop.Excel.XlHAlign]::xlHAlignCenter

$RangeTitle.ColumnWidth = 20

 

$RangeTable = $WorkSheet.Range($WorkSheet.Cells.Item(3,1),$WorkSheet.Cells.Item(7,2))

$ListObject = $WorkSheet.ListObjects.Add(1,$RangeTable,$null,1,$null)

$ListObject.TableStyle = « TableStyleLight6 »

 

$ListObject.ShowTotals = $true

$ListObject.ShowHeaders = $true

$ListObject.ShowAutoFilterDropDown = $false

 

$RangeSort = $WorkSheet.Range($WorkSheet.Cells.Item(4,2).Address($False,$False))

$WorkSheet.Sort.SortFields.Add($RangeSort,0,1) | Out-Null

$WorkSheet.Sort.SetRange($RangeTable)

$WorkSheet.Sort.Header = 1

$WorkSheet.Sort.Apply()

 

$WorkBook.SaveAs(« c:\temp\MaProductionDeBananes.xlsx »)

$Excel.Visible = $true

{/codecitation}

Nous avons donc vu dans cette troisième partie comme manipuler et mettre en forme notre tableau Excel. Dans la quatrième partie, on va s’attaquer à la création du graphique.

Pour les autres articles sur le sujet:

Manipuler Excel avec PowerShell : Part 2 – Appliquer un style à vos cellules

Dans le premier article, je vous ai montré comment créer votre premier fichier Excel et l’alimenter avec PowerShell pour obtenir le résultat suivant :

 

Dans cet article, on va s’attarder un peu plus sur la mise en forme.

On va commencer par fusionner les cellules A1 et B1. Pour cela, il va falloir définir une étendue ou un « Range » correspondant à ces deux cellules :

{codecitation style= »brush: PowerShell »}

$RangeTitle = $WorkSheet.Range($WorkSheet.Cells.Item(1,1),$WorkSheet.Cells.Item(1,2))

{/codecitation}

 

Une fois l’étendue définie, on va faire appel à la propriété « MergeCells » pour fusionner les deux cellules :

{codecitation style= »brush: PowerShell »}

$RangeTitle.MergeCells = $true

{/codecitation}

 

On peut également appliquer un style à une cellule ou à une étendue. Pour cela, il suffit simplement d’associer un style Excel existant à la propriété « Style » de notre étendue. Par contre, cela nécessite d’avoir la liste des styles existants dans Excel et de savoir à quoi ils correspondent…

Pour obtenir la liste des styles, il suffit simplement de saisir la commande « $WorkBook.Styles | ft name » qui nous retourne la liste des styles à disposition et qui est disponible également depuis « Styles de Cellules » dans Excel.

 

On va appliquer le style « Titre 2 ». Pour cela deux solutions :

{codecitation style= »brush: PowerShell »}

#Solution 1

$RangeTitle.Style = « Titre 2 »

#Solution 2

$RangeTitle.Style = ($WorkBook.Styles.Item(43)).Name

{/codecitation}

 

La première solution est la plus simple, par contre, vous aurez sans doute noté que le nom du style est en français dans mon exemple. En fait, le titre du style est traduit, il n’y a aucune solution pour y remédier (en tout cas je n’ai pas trouvé !).

La deuxième solution est donc plus adaptée sauf que les styles n’ont pas la même indexation entre les différentes versions d’Excel…

Troisième solution… Créer son propre style en s’appuyant sur un style existant. Si dessous, un nouveau style s’appuyant sur le style Excel « Titre 2 ».

{codecitation style= »brush: PowerShell »}

$Style = $WorkBook.Styles.Add(« MonTitre »)

$Style.IncludeAlignment = $false

$Style.IncludeNumber = $false

$Style.IncludePatterns = $false

$Style.IncludeProtection = $false

 

# Style de police

$Style.Font.Bold = $true

$Style.Font.Color = 6968388

$Style.Font.ColorIndex = 50

$Style.Font.Size = 11

$Style.Font.ThemeColor = 4

 

# style des bordures

$Style.Borders.item(4).Color = 15123099

$Style.Borders.item(4).ColorIndex = 37

$Style.Borders.item(4).ThemeColor = 5

$Style.Borders.item(4).LineStyle = 1

$Style.Borders.item(4).Weight = -4138

$Style.Borders.item(4).TintAndShade = +0.4

 

$Style.IncludeBorder = $true

{/codecitation}

 

Vous pouvez vous appuyer sur cet exemple de style personnalisé pour appliquer une police ou une bordure particulière directement à une cellule ou à une étendue. Les propriétés sont les mêmes.

 

On peut également centrer le titre (voir la liste des valeurs possibles depuis http://msdn.microsoft.com/en-us/library/office/bb241313(v=office.12).aspx) :

{codecitation style= »brush: PowerShell »}

$RangeTitle.HorizontalAlignment = -4108

{/codecitation}

 

Si vous avez consulté le lien ci-dessus, nous aurions pu également appeler la valeur par son nom pour un résultat équivalent.

{codecitation style= »brush: PowerShell »}

$RangeTitle.HorizontalAlignment = [Microsoft.Office.Interop.Excel.XlHAlign]::xlHAlignCenter

{/codecitation}

 

C’est un point intéressant car de nombreuses méthodes la classe Office Interop Excel s’appuie sur ce genre d’énumération. Vous en avez la liste complète depuis http://msdn.microsoft.com/en-us/library/office/bb259481(v=office.12).aspx.

 

Pour conclure, on va définir la taille de nos colonnes sur notre étendue, histoire que le titre ne soit pas trop écrasé.

{codecitation style= »brush: PowerShell »}

$RangeTitle.ColumnWidth = 20

{/codecitation}

 

Et voila le résultat!

 

Et le script au complet:

{codecitation style= »brush: PowerShell »}

[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo] « en-US »

 

$Excel = New-Object -ComObject « Excel.Application »

 

$WorkBook = $Excel.Workbooks.Add()

 

$WorkSheet = $WorkBook.WorkSheets.Add()

$WorkSheet.Name = « Production de bananes »

$WorkSheet.Select()

 

$WorkSheet.Cells.Item(1,1) = « Production annuelle de bananes »

 

$ArrProduction = @((‘2010’,’4.5’),(‘2011’,’12’),(‘2012’,’11.5’),(‘2013’,’15’))

 

$WorkSheet.Cells.Item(3,1) = « Année »

$WorkSheet.Cells.Item(3,2) = « Production (en tonnes) »

 

$InitialRow = 4

 

for ( $i=0; $i -lt $ArrProduction.Count; $i++ )

{

$WorkSheet.Cells.Item($InitialRow,1) = $ArrProduction[$i][0]

$WorkSheet.Cells.Item($InitialRow,2) = [decimal] $ArrProduction[$i][1]

$InitialRow++

}

 

$RangeTitle = $WorkSheet.Range($WorkSheet.Cells.Item(1,1),$WorkSheet.Cells.Item(1,2))

$RangeTitle.MergeCells = $true

$RangeTitle.Style = ($WorkBook.Styles.Item(43)).Name

$RangeTitle.HorizontalAlignment = [Microsoft.Office.Interop.Excel.XlHAlign]::xlHAlignCenter

$RangeTitle.ColumnWidth = 20

 

$WorkBook.SaveAs(« c:\temp\MaProductionDeBananes.xlsx »)

$Excel.Visible = $true

{/codecitation}

 

On a vu dans ce deuxième article comment appliquer un style Excel existant et même créer une étendue. On verra dans le prochain article comment mettre en forme un tableau.

 

Vous pouvez consulter également mes autres articles sur le sujet:

Manipuler Excel avec PowerShell : Part 1 – Créer un classeur, un feuillet et un tableau

Dans cette série d’articles, je vais vous montrer les bases pour générer un fichier Excel à l’aide de PowerShell.

Au préalable et surtout afin d’éviter d’obtenir une erreur de type « Old format or invalid type library » (http://support.microsoft.com/kb/320369), nous allons définir les informations culturelles sur l’anglais avant d’instancier Excel :

{codecitation style= »brush: PowerShell »}

[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo] « en-US »

{/codecitation}

 

Nous pouvons, dès-lors, instancier notre objet Excel :

{codecitation style= »brush: PowerShell »}

$Excel = New-Object -ComObject « Excel.Application »

{/codecitation}


Avec notre objet Excel, nous allons créer notre classeur:

{codecitation style= »brush: PowerShell »}

$WorkBook = $Excel.Workbooks.Add()

{/codecitation}


Un classeur étant constitué de feuillets, ajoutons maintenant un feuillet:

{codecitation style= »brush: PowerShell »}

$WorkSheet = $WorkBook.WorkSheets.Add()

{/codecitation}

 

Donnons-lui un nom :

{codecitation style= »brush: PowerShell »}

$WorkSheet.Name = « Production de bananes »

{/codecitation}

 

Définissons le titre de notre futur tableau en position A1 :

{codecitation style= »brush: PowerShell »}

$WorkSheet.Cells.Item(1,1) = « Production annuelle de bananes »

{/codecitation}

 

Remarque : Le premier chiffre correspond au numéro de ligne et le deuxième chiffre au numéro de colonne.

 

Maintenant, nous allons créer notre tableau Excel. Mais, pour cela, on va déjà commencer par stocker les éléments de notre tableau:

{codecitation style= »brush: PowerShell »}

$ArrProduction = @((‘2010’,’4.5’),(‘2011’,’12’),(‘2012’,’11.5’),(‘2013’,’15’))

{/codecitation}

 

Nous déclarons les entêtes de notre tableau :

{codecitation style= »brush: PowerShell »}

$WorkSheet.Cells.Item(3,1) = « Année »

$WorkSheet.Cells.Item(3,2) = « Production (en tonnes) »

{/codecitation}

 

… et les données :

{codecitation style= »brush: PowerShell »}

$WorkSheet.Cells.Item(4,1) = $ArrProduction[0][0]

$WorkSheet.Cells.Item(4,2) = [decimal] $ArrProduction[0][1]

$WorkSheet.Cells.Item(5,1) = $ArrProduction[1][0]

$WorkSheet.Cells.Item(5,2) = [decimal] $ArrProduction[1][1]

$WorkSheet.Cells.Item(6,1) = $ArrProduction[2][0]

$WorkSheet.Cells.Item(6,2) = [decimal] $ArrProduction[2][1]

$WorkSheet.Cells.Item(7,1) = $ArrProduction[3][0]

$WorkSheet.Cells.Item(7,2) = [decimal] $ArrProduction[3][1]

{/codecitation}


Un autre méthode pour alimenter les cellules plus efficacement, dirons-nous…

{codecitation style= »brush: PowerShell »}

$InitialRow = 4

for ( $i=0; $i -lt $ArrProduction.Count; $i++ )

{

$WorkSheet.Cells.Item($InitialRow,1) = $ArrProduction[$i][0]

$WorkSheet.Cells.Item($InitialRow,2) = [decimal] $ArrProduction[$i][1]

$InitialRow++

}

{/codecitation}

 

Pour visualiser le fichier Excel, il faut simplement saisir la commande suivante:

{codecitation style= »brush: PowerShell »}

$Excel.Visible = $true

{/codecitation}

 

Si vous voulez sauvegarder le classeur Excel :

{codecitation style= »brush: PowerShell »}

$WorkBook.SaveAs(« c:\temp\MaProductionDeBananes.xlsx »)

{/codecitation}


Et voila le résultat!

 

Et le script au complet:

{codecitation style= »brush: PowerShell »}

[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo] « en-US »

$Excel = New-Object -ComObject « Excel.Application »

$WorkBook = $Excel.Workbooks.Add()

$WorkSheet = $WorkBook.WorkSheets.Add()

$WorkSheet.Name = « Production de bananes »

$WorkSheet.Select()

$WorkSheet.Cells.Item(1,1) = « Production annuelle de bananes »

$ArrProduction = @((‘2010’,’4.5’),(‘2011’,’12’),(‘2012’,’11.5’),(‘2013’,’15’))

 

$WorkSheet.Cells.Item(3,1) = « Année »

$WorkSheet.Cells.Item(3,2) = « Production (en tonnes) »


$InitialRow = 4

for ( $i=0; $i -lt $ArrProduction.Count; $i++ )

{

$WorkSheet.Cells.Item($InitialRow,1) = $ArrProduction[$i][0]

$WorkSheet.Cells.Item($InitialRow,2) = [decimal] $ArrProduction[$i][1]

$InitialRow++

}


$WorkBook.SaveAs(« c:\temp\MaProductionDeBananes.xlsx »)

$Excel.Visible = $true

{/codecitation}

 

On a vu dans ce premier article comment créer notre premier classeur, un feuillet et comment l’alimenter. Dans l’article suivant, nous nous attarderons un peu plus longuement sur la mise en forme.

Ci-dessous, les autres articles sur le sujet: