Blog/Active Directory/computer_user.ps1
2023-12-16 17:17:13 +01:00

118 lines
5.4 KiB
PowerShell

#Script créé par Nicolas Lang - Sous licence CC-BY-SA
#https://nicolaslang.fr
#Requires -version 3
#Ce script requiert Powershell V3 ou supérieur pour fonctionner correctement, car l'export vers un fichier HTML ne fonctionnera pas correctement si c'est une version 2.
#Pensez à faire correspondre le chemin du fichier a ce que vous avez dans les .bat mis en GPO
$filename = "\\storage\logs$\loginout.TXT"
$logs = Get-Content $filename
# Cette partie est utilisée pour éviter d'avoir un trop gros fichier. Au dessus de 20000 entrées, il sauvegardera le contenu dans un autre fichier, puis réecrira le fichier avec les 10000 dernières. Vous pouvez changer ces valeurs à volonté.
if ($logs.count -gt 20000)
{
Copy-Item $filename $($filename + "_archive_" + $(Get-Date -Format dd_MM_yy) + ".txt")
$logs[-10000..-1] | Out-File $filename -Force utf8
}
$tableau = new-object System.Collections.ArrayList
$tableau2 = new-object System.Collections.ArrayList
#L'outil RSAT avec le module Active Directory n'est nécessaire que si vous lancer le script depuis un poste client. Si vous vous en servez depuis le serveur, ce doit être, celui ci doit être au moins un 2008 R2.
ipmo activedirectory
# Obtient la liste des utilisateurs depuis le controlleur de domaine. Necessaire pour retrouver le nom complet à partir du Sam Account Name.
$userlist = get-aduser -filter * | Select-Object -Property samaccountname,name
# Lisons le fichier ligne par ligne!
foreach ($log in $logs)
{
# J'utilise une REGEX pour retrouver les diverses informations de chaque ligne du fichier
if ($log -match "(?<date>\d+/\d+/\d+);(?<heure>.+:\d+:\d+[,.]\d+);(?<compte>\S+);(?<pc>\S+);(?<serveur>\W{2}\w+);(?<action>.*$)")
{
# Dans certains cas, le format de date diffère et affiche l'année en premier. Je vérifie juste si le format correspond à un format étranger, et le cas écheant, je réorganise le tout.
$date = $Matches.date -split("/")
if ($date[0].length -le 2)
{
$matches.date = [string]$($date[1]+"/"+$date[0]+"/"+$date[2])
}
$object = [pscustomobject]@{
"Date" = $([datetime]$Matches.date)
"Time" = $($($Matches.heure) -replace(",\d+",""))
"Account" = $Matches.compte
"Pc" = $matches.pc
"Action" = $Matches.action
"Server" = $Matches.serveur
}
$tableau.add($object) | Out-Null
}
}
# Je trie le tableau récapitulatif, par date en descendant, puis je regroupe tout par nom d'ordinateur
$tableaugroupe = $tableau | sort-object -property @{Expression="Date";descending=$true} | Group-Object -Property "PC"
# Comme certains ordinateurs n'ont pas d'information de login / logout en fonction de leur utilisation (travail par VPN par exemple), je crée un objet avec des valeurs pré-définies pour ces cas
$itemsansvaleur = [pscustomobject]@{
"Date" = $([datetime]"01/01/1901")
"Time" = "00:00:00"
}
# Pour chaque entrée dans le tableau trié, je prends le premier login et logout (qui sont les valeurs les plus récentes), puis je retrouve les informations dessus.
foreach ($entree in $tableaugroupe)
{
$lastlogin = $lastlogout = [PSCustomObject]
try
{
$lastlogin = $($entree.group | Where-Object {$_.action -like "*login*"})[0]
}
catch
{
Write-Host "Erreur login sur $($entree.Name)"
$lastlogin = $itemsansvaleur
}
try
{
$lastlogout = $($entree.group | Where-Object {$_.action -like "*logout*"})[0]
}
catch
{
Write-Host "Erreur logout sur $($entree.Name)"
$lastlogout = $itemsansvaleur
}
# Je retrouve le nom complet
$nom = $userlist | where-object {$_.samaccountname -eq $($lastlogin.account)} | Select-Object -ExpandProperty "Name"
# Puis je crée l'objet.
$object = [pscustomobject]@{
"Compte" = $lastlogin.account
"Name" = $nom
"PC" = $entree.group[0].pc
"Dernier Login" = get-date $(($lastlogin.Date).ToShortDateString()+" "+$lastlogin.heure) -Format "dd/MM/yy HH:mm:ss"
"Serveur Login" = $lastlogin.server
"Dernier Logout" = get-date $(($lastlogout.Date).ToShortDateString()+" "+$lastlogout.heure) -Format "dd/MM/yy HH:mm:ss"
"Serveur Logout" = $lastlogout.server
}
$tableau2.Add($object) | out-null
}
$date = Get-Date
# Je trie le tableau par ordinateur, puis je le convertit au format HTML. J'ai rajouté un fichier CSS pour rendre le tout plus joli. Si vous voulez donner un look plus sympa à votre fichier, créez juste un fichier nommé "tableaux.css" dans le même répertoire que le fichier HTML et laissez votre créativité travailler :D
$tableau2 | sort-object -Property "PC" | ConvertTo-Html -title "$($date.ToShortDateString()) $($date.ToShortTimeString())" -CssUri "tableaux.css" | Out-File "\\storage\logs$\logintohtml.html" -Encoding utf8 -Force
#Après cela, j'uploade le fichier sur un serveur web en me servant de .NET et en passant via le FTP. Ce n'est pas utile si vous stockez la page localement.
# Le login / password est en clair ici. Je ne le recommande pas, mais c'est uniquement à but d'exemple. Vous pouvez le rendre plus sur, mais ce n'est pas le but de ce script.
$credentials = new-object System.Net.NetworkCredential("username","password")
$webclient = new-object System.Net.WebClient
$webclient.Credentials = $credentials
$uri = New-Object System.Uri("ftp://webserver/www/logintohtml.html")
$webclient.uploadFile($uri,'\\storage\log$\logintohtml.html')