WSUS by powershell part 2 – Reporting des clients WSUS

Bonjour à tous,

dans mon premier article sur WSUS et Powershell Wsus industrialisation du déploiement des mises à jour je vous suggérai un ensemble de script afin de gérer le déploiement de vos mises à jour ainsi que le traitement des indicateurs WSUS.

Je vais maintenant vous montrer comment lister l’ensemble des serveurs:

– en attente de redémarrage
– en erreur suite à l’installation de mise à jours
– n’ayant pas contacté WSUS depuis plusieurs jours

Je ne m’attarderai donc pas sur certaines commandes Powershell que nous pourrions déjà avoir vu ensemble lors de mon premier article lié à WSUS

Clients WSUS en attente de redémarrage Lire la suite « WSUS by powershell part 2 – Reporting des clients WSUS »

Publicités

Remove Skype contacts – Manage and Remove Internal Contacts with Script and Powershell

Bonjour à tous,

si vous ne le saviez pas déjà, il est possible d’automatiser l’ajout de contacts Skype à l’ensemble de vos utilisateurs Skype.
Merci Michael LaMontagne -> https://gallery.technet.microsoft.com/office/Invoke-SFBContacts-3b3ad2ef

En revanche une fois le contact Skype ajouté, si celui ci ne fait plus parti de la société il restera malgré tout dans votre liste car il n’existe pas de processus de purge.

Je vais vous montrer ici comment récupérer la liste de vos utilisateurs Skype et pour chacun d’eux, purger complètement la liste des contacts internes afin d’avoir une liste de contact régulièrement remise à zéro et du coup « Up to Date ».

Ce premier script sera exécuté depuis votre serveur Skype Lire la suite « Remove Skype contacts – Manage and Remove Internal Contacts with Script and Powershell »

WSUS by Powershell. Industrialisation du déploiement des mises à jour et Indicateurs

Bonjour à tous,

j’avais envie aujourd’hui de vous montrer comment automatiser et industrialiser l’approbation automatique et donc l’application de patch Microsoft pour vos serveurs Windows.

en effet, suite à l’arriver des différents Cryptolocker qui nous menace maintenant quotidiennement, j’ai due, au sein de l’entreprise pour laquelle je travaille, passer des semaines, pour améliorer la gestion des patch Microsoft et surtout faire en sorte que ce qui était fait à la main auparavant ne le soit plus afin de diminuer le risque d’erreur humaine. Effectivement, nous nous sommes rendu compte que le fait d’oublier d’approuver des patch de sécurité Microsoft par mégarde ou parceque le process n’est pas assez clair, pouvait mettre en péril les données d’un nombre conséquent de serveur que l’on héberge.

Cet article ne sera pas porté sur l’installation ni même le paramétrage WSUS mais sur la gestion des mises à jours et leur distribution au sein de votre parc informatique. Cet article sera donc plus compréhensible par un administrateur connaissant déjà bien l’outil et qui le manipule de façon régulière.

Les scripts powershell que je vais vous présenter sont spécifiques à mon entreprise, à notre infra et aussi à notre besoin mais ils vous permettront, d’avoir une bonne base s’il s’avère que vous puissiez être amené à utiliser powershell pour gérer WSUS; ce que je vous conseille fortement pour avoir toute la souplesse que l’on va découvrir ensemble par la suite.

Je vais vous montrer:

  • comment lancer une synchronisation WSUS, récupérer les informations de synchronisation et les injecter dans une page web ou dans un fichier excel
  • comment récupérer la liste des mises à jours et les indicateurs du Tuesday Patch
  • comment approuver des mises à jours pour des groupes WSUS spécifiques
  • comment exporter le résultat de vos filtres dans un fichier au format CSV
  • comment envoyer des mails avec contenu au format HTM

Dans un premier temps, je voulais vous préciser pourquoi je ne me suis pas servi de la fonction « Règle d’approbation automatique » que l’on retrouve dans la console de gestion WSUS pour approuver les patch Microsoft. Puisque tous mes scripts parte de ce qui va suivre, j’aurai finalement plus appeler cet article « Règles d’Approbation automatique versus Powershell approbation ».

La raison est double,

  • d’une part, lorsque vous synchronisez votre serveur WSUS à Windows update, vous récupérer une liste de nouvelles mises à jours. Si la règle d’approbation automatique que vous avez créée « match » avec l’une des nouvelles mises à jours récupérées, alors celle ci sera automatique approuvée une fois la synchronisation terminée et donc mis à disposition des serveurs impactés par la Règle d’approbation automatique.

Cela me dérange dans le sens où je souhaite pouvoir synchroniser mon WSUS à Windows Update sans forcément lancer une processus d’approbation dans la foulé. En effet je souhaite décider quand approuver les patch et donc leur téléchargement.

  • D’autre part, si vous avez une infra WSUS multi serveurs comme la notre, avec un serveur WSUS parent et un ou plusieurs serveurs WSUS enfants, vous devez déjà savoir que les informations des serveur WSUS enfants seront à jour coté WSUS parent uniquement après synchronisation de deux parties.

En effet si vous ne synchronisez par souvent, vous verrez régulièrement un décalage entre le WSUS parent et le WSUS enfant. Par exemple des clients wsus absents, des groupes non présents, des dates de dernier rapport fausses etc…un peu à la manière de la console SCVMM et des host Hyper-V, si vous n’actualisez pas les hosts\machines virtuelles régulièrement pas votre console n’est pas à jour!

L’idéal est donc de tout gérer à partir du serveur parent, d’utiliser une seule console WSUS.

Venons en maintenant au premier script celui qui va lancer la synchronisation de notre WSUS

#récupération des informations WSUS via la commande Get-Wsusserver puis lancement de la synchro avec « StartSynchronization() »

(Get-WsusServer).GetSubscription().StartSynchronization()

# on créée une Variable qui va récupérer la date du jour au format français

$startTime = (get-date -f dd-MM-yyyy)

#on force l’encoding en UTF8 pour gérer les accents dans le mail

$encoding=[System.Text.Encoding]::UTF8

# envoi d’un e-mail avec send-mailmessage

Send-MailMessage -From "wsus@masociete.fr" -To "equipe.microsoft@masociete.fr" -Subject "WSUS - Synchro hebdo lancée $startTime" -SmtpServer "mail.masociete.fr" -Body "WSUS - Synchronisation hebdo lancée" -Encoding $encoding

Ce petit script permet sans avoir à se connecter nulle part, d’être avertit que la synchronisation a été lancé. Pour notre part, nous synchronisons deux fois par semaine WSUS. Le mardi et le vendredi. Le mardi soir permet de récupérer les KB du Tuesday Patch Microsoft (2eme mardi du mois) le plus tôt possible et le vendredi afin d’avoir au moins deux synchronisation par semaine avec les WSUS Downstream.

Regardons maintenant via un second script comment récupérer les informations de synchronisation.
J’entends par là le nombre de nouvelles mises à jours, celles révisées et celles expirées également.

# On récupère dans la variable $Lastsync les informations de la dernières synchronisation WSUS

$lastSync = (Get-WsusServer).GetSubscription().GetLastSynchronizationInfo()

# On va définir un scope afin de récupérer uniquement les mises à jours de cette synchro

$UpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope

# Définir un créneau horaire afin de récupérer uniquement les mises à jours de la dernière synchronisation avec une date de début et une date de fin

$UpdateScope.FromArrivalDate = $lastSync.StartTime
$UpdateScope.ToArrivalDate = $lastSync.EndTime

# On récupère cette liste de KB en fonction de l’UpdateScope que l’on vient de configurer.

$SyncUpdates = (Get-WsusServer).GetUpdates($UpdateScope)

# On récupère depuis la variable $SyncUpdates les nouvelles Mises à jours et on les compte

$published = $SyncUpdates | where {($_.publicationstate -like "Published")}
$published.count

# On récupère depuis cette liste les Mises à jours révisées et on les compte

$revised = $SyncUpdates | where {($_.publicationstate -like "revised")}
$revised.count

# On récupère depuis cette liste les Mises à jours expirées et on les compte

$expired = $SyncUpdates | where {($_.publicationstate -like "expired")}
$expired.count

# On récupère la liste de tous les clients WSUS rattachés à nos WSUS (serveurs Wsus parent et enfants grâce à IncludeDownstreamComputerTargets) et on fait le compte

$wsus = Get-WsusServer
$computers = $wsus | Get-WsusComputer -IncludeDownstreamComputerTargets
$computers.count

Pour l’envoi de nos mails nous utilisons en body un fichier HTM. Cette base de format nous permet de réaliser des ajouts à chaud ou simplement d’écrire des choses en dure et de le laisser static.
Le rendu est agréable à visionner (enfin je trouve ^^)

J’ai du coup un fichier HTM par besoin\fonction – Si le fichier HTM est temporaire c’est à dire avec des données que j’injecte seulement à l’instant T comme c’est le cas dans notre exemple je pars d’un Template que je copie, que je complète, que j’envoie puis que je supprime.

# Copie du fichier HTM Temporaire

xcopy /s "C:\Scripts\HTM\IndicateurWSUS\TEMPLATE\*.*" "C:\Scripts\HTM\IndicateurWSUS\"

# Une fois le fichier copié, on déclare le chemin correspondant à notre fichier temporaire.

$Filehtm = "C:\Scripts\HTM\IndicateurWSUS\WSUS.htm"

# On récupère via get-content le contenu du HTM et on y injecte les données des variables précédemment récupérées. L’ajout de donnée se fait vers des numéros de lignes biens spécifique que l’on a préparée en amont.

$fileContent = Get-Content $Filehtm
$fileContent[966] += $computers.count
$fileContent[979] += $published.count
$fileContent[993] += $revised.count
$fileContent[1008] += $expired.count
$fileContent[1023] += $update.count
$fileContent | Set-Content $filehtm

# Une fois notre fichier HTM « mis à jour » avec les données qui vont biens on configure le body du mail comme étant le contenu du fichier HTM.

$body = Get-Content -Path $filehtm | Out-String

# on se positionne en encoding UTF8 afin de gérer les accents que ce soit dans le Subject ou le Body du mail que l’on va envoyer.

$encoding=[System.Text.Encoding]::UTF8

# On positionne la date dans une variable avec le format qui nous intéresse

$startTime = (get-date -f dd-MM-yyyy)

# Envoi du mail via send-mailmessage, l’option -bodyashtml permet d’indiquer que l’envoi de mail utilise un body en mode HTML afin qu’il puisse être correctement interprété

Send-MailMessage -From "wsus@societe.fr" -To "equipe.microsoft@societe.fr","m.jouan@societe.fr" -Subject "Indicateur WSUS - Etat Synchro du Tuesday Patch datant du $startTime" -SmtpServer "mail.masociete.fr" -Encoding $encoding -Body $body -bodyashtml

# On peut exécuter une pause de 5s si besoin via la commande ping.

ping -n 5 127.0.0.1

# Comme expliqué un peu plus haut on supprime le fichier HTM qui a été généré à partir du template

rm "C:\Scripts\HTM\IndicateurWSUS\WSUS_fichiers\" -r -force
rm "C:\Scripts\HTM\IndicateurWSUS\WSUS.htm"

Comment trouvez vous le résultat ? J’ai masqué nos photos mais je vous assure que ce système de communication est appréciable en plus d’être assez simple à prendre en main

Nous pourrions nous arrêter là mais j’ai eu envie d’aller plus loin :), nous allons maintenant pousser ces indicateurs dans un fichier excel
Mais qui dit fichier Excel dit arborescence Windows, la notre ressemble à beaucoup d’autres: « \\Production\Qualité\2018\Indicateurs-2018-02.xls », vous l’aurez compris il va donc falloir jouer avec les mois et les années.
Nous utilisons un seul et même fichier mensuel pour l’ensemble des indicateurs de la société, WSUS on a donc sa propre feuille Excel nommée « WSUS »

Avant de pouvoir remplir mensuellement mon Excel de façon automatisé, j’ai d’abord fait en sorte de gérer le mois et l’année que ce soit dans le path comme dans le nom du fichier lui-même.

# Je déclare donc plusieurs variables afin de récupérer ces deux valeurs

$startTime = get-date
$startTime.Year
$startTime.Month

# Je continue dans la déclaration de variable afin d’être sur ce qu’on appelle du long terme…

if($startTime.Year -like '2018'){$year='2018'}
if($startTime.Year -like '2019'){$year='2019'}
if($startTime.Year -like '2020'){$year='2020'}
if($startTime.Year -like '2021'){$year='2021'}
if($startTime.Year -like '2022'){$year='2022'}
if($startTime.Year -like '2023'){$year='2023'}
if($startTime.Year -like '2024'){$year='2024'}
if($startTime.Year -like '2025'){$year='2025'}
if($startTime.Year -like '2026'){$year='2026'}
if($startTime.Year -like '2027'){$year='2027'}
if($startTime.Year -like '2028'){$year='2028'}
if($startTime.Year -like '2029'){$year='2029'}
if($startTime.Year -like '2030'){$year='2030'}

if($startTime.Month -like '1'){$month='01'}
if($startTime.Month -like '2'){$month='02'}
if($startTime.Month -like '3'){$month='03'}
if($startTime.Month -like '4'){$month='04'}
if($startTime.Month -like '5'){$month='05'}
if($startTime.Month -like '6'){$month='06'}
if($startTime.Month -like '7'){$month='07'}
if($startTime.Month -like '8'){$month='08'}
if($startTime.Month -like '9'){$month='09'}
if($startTime.Month -like '10'){$month='10'}
if($startTime.Month -like '11'){$month='11'}
if($startTime.Month -like '12'){$month='12'}

# Je peux maintenant déclarer mon chemin correspondant au mois et à l’année en cours

$path = "\\Production\Qualité\$year\tdb_"+$year+"_"+$month+".xls"

# Je vérifie via test-path si le fichier excel que je veux remplir existe, si ce n’est pas le cas je viens copier celui du mois précédent.

if (Test-Path $path){} else {
$monthlessnew = $month - 1
$monthlessnew = "{0:D2}" -f $monthlessnew
$pathless = "\\Production\Qualité\$year\tdb_"+$year+"_"+$monthlessnew+".xls"
copy $pathless $path
}

# On récupère la valeur qui vérifie si le fichier Excel est verrouillé ou accessible (true ou False)

$FILE = try { [IO.File]::OpenWrite($path).close();$true }catch {$false}

# Si inaccessible car déjà ouvert, on envoi un mail pour informer que les indicateurs n’ont pu être ajouté automatiquement, sinon on les ajoute au fichier excel

if ($FILE -like "False"){

# J'ai créée un fichier txt avec le chiffre indiquant le numéro de la colonne sur laquelle je vais compléter mes cellules
# Je vous rappelle avoir souhaité tout automatiser, c'était auparavant fait manuellement, je sais cependant aujourd'hui que les indicateurs du mois en cours 02/2017 devront arriver dans la colonne 27
# Avec Excel pour cibler la bonne colonne vous devez retirer 1, dans mon cas je dois donc utiliser 26. Si vous avez bien suivi c'est pourtant la colonne Excel qui à ce jour est déjà complétée et comporte les valeurs du mois de Janvier 2018.
# Je récupère donc la valeur actuelle de mon fichier txt qui est "26"
# Nous nous situons dans la partie du script où le fichier excel est actuellement verrouillé, j’envoie donc simplement un mail pour signaler le blocage et j'incrémente également mon numéro de colonne pour l'exécution de ce script le mois prochain

$colonn = get-content C:\Scripts\colonne.txt
$colonne = [int]$colonn + 1
$colonne > C:\Scripts\colonne.txt
$startTime = (get-date -f MM/yy)

Send-MailMessage -From "wsus@masociete.fr" -To "equipe.microsoft@masociete.fr","m.jouan@masociete.fr" -Subject "Indicateur WSUS - Fichier Excel verrouillé - $startTime" -SmtpServer "mail.masociete.fr" -Encoding $encoding -bodyashtml

} else {

# On est dans la section ou le fichier excel est accessible
# Je peux configurer mes variables qui vont me permettre d'ouvrir mon fichier Excel en indiquant bien via WorkSheets.item la feuille Excel sur laquelle je souhaite travailler.
$xl=New-Object -ComObject Excel.Application
$wb=$xl.WorkBooks.Open($path)
$ws=$wb.WorkSheets.item("Wsus")
$xl.Visible=$true

$startTime = (get-date -f MM/yy)

# on Récupère la valeur de la colonne à traiter
$colonn = get-content C:\Scripts\colonne.txt

# Je peux maintenant positionner les valeurs dans les cellules correspondantes à la bonne colonne.
$ws.Cells.Item(2,$colonn)=$startTime
$ws.Cells.Item(3,$colonn)=$computers.count
$ws.Cells.Item(4,$colonn)=$published.count
$ws.Cells.Item(5,$colonn)=$revised.count
$ws.Cells.Item(6,$colonn)=$expired.count
$ws.Cells.Item(7,$colonn)=$update.count

# J'ajoute maintenant '1' à la valeur précédente qui était "26"
$colonne = [int]$colonn + 1
# Je viens ensuite réinjecter cette nouvelle valeur dans mon fichier d'origine afin que l’exécution du script le mois prochain utilise la colonne suivante
$colonne > C:\Scripts\colonne.txt

# Nous reste plus qu'à sauvegarder nos modifications puis à quitter.
$wb.Save()
$wb.close()
$xl.Quit()

# On termine en indiquant par mail que le fichier excel a bien été complété

Send-MailMessage -From "wsus@societe.fr" -To "equipe.microsoft@societe.fr","m.jouan@societe.fr" -Subject "Indicateur WSUS - Fichier Excel complété - $startTime" -SmtpServer "mail.masociete.fr" -Encoding $encoding -bodyashtml

Avec cette méthode, les indicateurs WSUS mensuel sont automatiquement complétés dans le fichier Excel.

Voyons maintenant comment approuver ces kb récupérées juste avant part la synchronisation du Tuesday Patch! Celle du 2ème mardi du mois.

# on récupère les info du serveur, le script s'exécutant localement, pas besoin de préciser le nom, le port, si ssl.
$wsus = Get-WsusServer
# on récupère la date du jour
$startTime = (get-date -f MM-dd-yyyy)
# A laquelle on va retirer environ 25 jours, l'idée étant de ratisser large, c'est à dire récupérer l'ensemble des patch des différentes synchro entre ce Tuesday Patch et celui du mois précédent.
$startTime2 = (get-date).AddDays(-25).ToString("MM-dd-yyyy")

# dans la variable $update on récupère toutes les mises à jour de sécurité de tous les produits datant au maximum de plus de 25j, nous excluons également certaines KB via l'option "$_.Title -notlike"
$update = $wsus.GetUpdates() | where {((($_.UpdateClassificationTitle -like "Mises à jour de définitions") -and ($_.ProductTitles -like "windows defender")) -or (($_.UpdateClassificationTitle -like "Mise à jour de la sécurité") -and ($_.ProductTitles -like "*"))) -and ($_.CreationDate -gt $startTime2) -and ($_.IsDeclined -ne "True") -and (($_.Title -notlike "*4056892*") -and ($_.Title -notlike "*4056891*"))}

# Petit rappel des différents types de mises à jour possibles
# Applications
# Ensemble de mises à jour
# Feature Pack
# Jeux de pilotes
# Mise à jour critique
# Mise à jour de la sécurité
# Mise à jour
# Mises à jour de définitions
# Outil
# Pilote
# Service Pack
# Upgrades
# On récupère l'identifiant des groupes que l'on souhaite traiter "Serveurs PREPROD" et "Serveurs Recette"
$group = $wsus.GetComputerTargetGroups() | where {($_.Name -like '*Serveurs PREPROD*' -or $_.Name -like '*Serveurs Recette*')}

# On approuve maintenant pour cette liste de groupe l'installation de toutes les KB récupérées précédemment via $update
foreach ($Member in $group) {
foreach ($Approval in $update) {
  $Approval[0].Approve(“Install”,$Member)}
   }

# Déclaration de deux chemins au format .csv qui viendront accueillir la liste des serveurs membres des groupes pour l'un et la liste des KB pour l'autre.
$file1 = "\\Fileshare\WSUS-Preprod-Recette-$startTime.csv"
$file2 = "\\FileShare\WSUSKB-Preprod-Recette-$startTime.csv"

# On pousse dans $file1 les serveurs impactés, on oublie pas IncludeDownstreamComputerTargets = $true, ca ne pourra jamais vous desservir
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
$computerScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope;
$computerScope.IncludeDownstreamComputerTargets = $true
# On sélectionne le FullDomainName la date de dernière synchro WSUS LastReportedStatusTime et l'appartenance à son groupe RequestedTargetGroupName
$wsus.GetComputerTargets($computerScope) | Where-Object {($_.RequestedTargetGroupName -like "*Serveur PREPROD*" -or $_.RequestedTargetGroupName -like '*Serveurs Recette*')} | select FullDomainName,LastReportedStatusTime,RequestedTargetGroupName | Sort-Object -Property RequestedTargetGroupName | Export-Csv -Path $file1 -Delimiter ";" -append


# On export ensuite la liste des KB approuvées dans $file2
$update | select Title,UpdateClassificationTitle,ProductTitles,LegacyName,CreationDate,ArrivalDate | Out-File $file2 -append -Width 300

# On peut maintenant préparer le mail à envoyer, on déclare un fichier HTM comme vu précédemment, celui est en revanche simplement statique.
$file3 = "C:\Scripts\HTM\ApprobationQual\WSUS.htm"

# On déclare ce fichier HTM en tant que Body du mail
$body = Get-Content -Path $file3 | Out-String

# On modifie l'encoding afin de gérer correctement les accents
$encoding=[System.Text.Encoding]::UTF8

# Puis envoi du mail avec les deux pièces jointes
Send-MailMessage -From "wsus@ma-societe.fr" -To "equipe.microsoft@ma-societe.fr" -Subject "WSUS - Mise à jour Microsoft sur environnement PRE PROD ET Recette - fait le $startTime" -SmtpServer "mail.ma-societe.fr" -Encoding $encoding -Body $body -bodyashtml -Attachments "$file1","$file2"

Le résultat de tout ceci ressemblant à cela:

A travers ces quelques explications et lignes de scripts, je vous invite fortement à utiliser powershell pour préparer\gérer vos serveurs WSUS.
Alors oui, cela nous a pris du temps pour peaufiner tout ca mais le résultat est plus que convainquant aujourd’hui.

Je réaliserai un nouvel article sur WSUS mais cette fois autour du reporting, cela vous permettra de savoir quels serveurs:
– est en attente de redémarrage
– est en erreur suite à l’installation de mise à jours
– n’a pas contacté son serveur WSUS depuis plusieurs jours

Mise à jour -> Wsus – Reporting des clients

A+

Maxime

Automatisation de l’ Ajout\Suppression des comptes locaux – Script Powershell

Bonjour,

pour des besoins métier, nous avons du élaborer un script powershell nous permettant le maintien à jour des comptes locaux de plusieurs serveurs.
ce script est poussé toutes les 30min par un agent puppet installé sur nos centaines de serveur.

Ses fonctions:

– Création d’un groupe qui sera membre du groupe administrateur
– Ajout de compte et ajout au groupe précédemment créée.
– Suppression automatique de compte en cas de départ de la société
– Suppression automatique de compte si l’ajout n’a pas été fait via le fichier CSV
– N’empêche pas l’utilisateur déjà présent de changer de mot de passe.

Le script utilise un fichier csv pour récupérer la liste à jour des utilisateurs.


# Déclaration groupe admin local
$group = "Administrateurs"
$group2 = "Administrators"
$group3 = "Admins-Astreinte"

# Création du groupe Admins-Astreinte
net localgroup $group3 /add /comment:"Groupe Administrateurs Astreinte - ne pas ajouter manuellement d'utilisateur risque fort de suppression automatique via Puppet"

# Ajout du groupe Admins-Astreinte au groupe administrateur\administrator peut importe la langue installée.

net localgroup $group /add $group3
net localgroup $group2 /add $group3

# déclaration date
$date = (get-date).ToString("dd-MM-yyyy")

# récupération du nom du serveur
$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"

# récupération du contenu de la liste à jour des utilisateurs
$userfile = get-content "C:\Liste-a-jours.csv"

# récupération liste utilisateur actuellement présent dans le groupe
$Astreintemembers = NET LOCALGROUP $group3

# pour tous les membres actuels du groupe Admins-Astreinte
foreach ($user in $Astreintemembers){
if (!$user){}
else{
# S'il est également présent dans le fichier CSV alors on ne fait rien, sinon il est supprimé
if ($userfile | select-string -pattern $user){
}
else {
NET USER $User /delete
# J'incrémente également un fichier afin de pouvoir historiser les suppressions si besoin de comprendre ce qui s'est passé.
$del = (-join ($user," - ",$date))
$del >> c:\Suppression-groupe-Astreinte.txt
}}}

# On s'occupe ensuite des nouveaux arrivants
foreach ($user in $userfile){
# On vérifie si l'utilisateur existe localement
$existing = $adsi.Children | where {$_.SchemaClassName -eq 'user' -and $_.Name -eq $user}
# Si inexistant alors création du mot de passe et création du compte
if ($existing -eq $null) {
$year="2018"
$Pass = (-join ("*!",$env:COMPUTERNAME,$user,$year,"*!"))
$SecurePassword = $Pass | ConvertTo-SecureString -AsPlainText -Force

    Write-Host "Creation d'un nouvel utilisateur."
    & NET USER $user $SecurePassword /add /y /FULLNAME:$user /comment:"Utilisateur Astreinte"
    WMIC USERACCOUNT $user SET PasswordExpires=FALSE

    Write-Host "Ajout du compte $user au groupe $group3."
    & NET LOCALGROUP $group3 $user /add
   
        }
else {}
}

En espérant que ce petit script ou en tout cas une partie de celui ci puisse vous aider\aiguiller lors d’un besoin similaire!

Maxime

RDS 2008R2\2012R2 – PowerShell Script de Maintenance.

Bonjour,

rapidement je vous mets à disposition un petit script Powershell qui nous a permis d’automatiser les reboots des serveurs RDS2008R2 d’un client en pleine journée de production.
En effet celui ci rencontre des problèmes d’ouverture de session parfois dans la journée, plus personne ne peut se connecter sur l’un des serveurs de la ferme, avec des chargements de bureau Windows interminable. De plus si le broker décide que c’est ce serveur qui a le moins de session alors il continuera d’envoyer toutes nouvelles ouverture de session dessus.

Nous avons constaté que lorsque ce phénomène ce produit, plusieurs Event ID, le 6004 6005 et 6006 remplissaient le journal d’application.

Pour pallier à cela, une tâche planifiée se déclenche lorsque l’un des Event ID apparait et exécute un script PowerShell qui est le suivant:

La commande exécutée est la suivante:

powershell.exe -ImportSystemModules C:\Scripts\mon-script.ps1

Ci joint le contenu du script:

# On autorise le système d'exploitation à exécuter ce script
set-executionpolicy -executionpolicy unrestricted -force

# configuration de la variable starttime pour correspondre à l'instant T moins 5min
$ts = New-TimeSpan -Minutes 5
$startTime = (get-date) - $ts

# On récupère le nom du serveur
$name = $env:computername

# configuration de la variable Endtime à l'instant T
$endTime = (get-date)

# récupération des erreurs concernant les problèmes d'ouverture de session sur les 5 dernières minutes
$TSE = Get-EventLog -LogName "Application" -source Wlclntfy -After $startTime -before $endTime | where {$_.eventID -eq 6004 -or $_.eventID -eq 6005 -or $_.eventID -eq 6006}

# Je récupère ici la valeur présente dans le fichier. Elle est sensé être à 1 en cas de problème voir plus bas, cela me permet de ne pas continuer le script si un redémarrage est déjà enclenché.
$file3 = get-content C:\Scripts-CIS\plantage-en-cours.txt

if ($file3 -ieq '1'){}
	else {
                # on va ensuite compter le nombre d'erreur dans ce créneau de 5min via $TSE.count
		if ($TSE.count -gt '10'){
                # si plus grand que 10, alors on met en maintenance le serveur
                # on prévient toutes les sessions ouvertes via la fonction msg
		msg * "Vous êtes actuellement connecté sur $name qui va redémarrer pour maintenance d'ici 20min, merci de bien vouloir fermer votre session. L'équipe informatique."
		cd RDS:
		cd .\RDSConfiguration
		cd .\ConnectionBrokerSettings
                # une fois dans l’arborescence de la configuration RDS, on retire le serveur de la fonction LoadBalancing
		Set-Item .\LoadBalancingState 0
                # et on programme le redémarrage de celui ci
		shutdown /r /t 1200 /c "Ce serveur va redémarrer d'ici 20min pour des raisons de maintenance"
                # De cette façon, le problème d'ouverture de session est détecté tôt, le serveur redémarré au bout de 20min laissant le temps aux utilisateurs de fermer leur session.
                # J'en profite pour incrémenter un fichier afin de vérifier après plusieurs jour\semaines combien de fois il s'est auto redémarré.
		$file = get-content C:\Scripts-CIS\count-plantage.txt
		$file2 = [int]$file + 1
		$file2 > C:\Scripts-CIS\count-plantage.txt
                # Je pousse ensuite la valeur 1 au fichier "plantage-en-cours.txt"
                # Ce qui évitera au script de refaire la procédure si un autre Event ID arrivait entre temps.
		echo 1 > C:\Scripts-CIS\plantage-en-cours.txt
		exit
		}
			else {
                # Si $TSE.count plus petit que 10 je ne sors pas encore le serveur de la ferme RDS
                # J'en profite même pour forcer le Loab Balancing à 1. Cette partie est néanmoins facultative.
			cd RDS:
			cd .\RDSConfiguration
			cd .\ConnectionBrokerSettings
			Set-Item .\LoadBalancingState 1
			exit
}}

Il existe un dernier script powershell a ne surtout pas oublier, qui s’exécute au démarrage du serveur et qui a toute mon attention le voici:

# On remet le compteur plantage-en-cours.txt à zero
echo 0 > C:\Scripts-CIS\plantage-en-cours.txt
# On replace le serveur dans le LoadBalancing de la ferme RDS
cd RDS:
cd .\RDSConfiguration
cd .\ConnectionBrokerSettings
Set-Item .\LoadBalancingState 1
exit

Alors certes, on peut voir cela comme un arrêt de production, mais s’agissant d’une ferme RDS, une réouverture de session par l’utilisateur et celui-ci se reconnecte sur un autre RDS de la ferme.
Ce que j’apprécie est que le client n’a plus à nous appeler en urgence parce que ses utilisateurs n’arrivent plus à se connecter; et mine de rien, la plateforme RDS vie toute seule.

En espérant que vous puissiez vous aider de cela pour une problématique similaire, que sais-je !

ps: je vous rassure, nous nous sommes également penchés sur la réelle cause du problème de chargement de session et il semblerait qu’il existe une ou deux KB (KB2575077 et KB2265716) capables de résoudre ces problèmes, à tester …

Maxime

Créez un site Web ou un blog gratuitement sur WordPress.com.

Retour en haut ↑

%d blogueurs aiment cette page :