Points à retenir
- Protocole de sécurité automatisé: Le script automatise l’identification des comptes d’utilisateurs inactifs, ce qui renforce la sécurité.
- Seuil personnalisable: Ajustez le seuil d’inactivité en fonction des politiques de l’organisation.
- Compatibilité multi-environnementale: Capable de gérer des comptes locaux, Active Directory et Azure AD.
- Efficace en termes de temps et de ressources: Automatise un processus manuel qui prendrait beaucoup de temps.
- Gestion proactive des risques: Permet d’éviter les failles de sécurité en gérant les vulnérabilités potentielles.
- Transparence et flexibilité: Comme il s’agit d’un script PowerShell, il est transparent et personnalisable pour répondre à des besoins spécifiques.
- Audits programmés: Il peut être configuré pour fonctionner à intervalles réguliers pour une surveillance continue.
- Desrapports complets: Génère des rapports détaillés sur les comptes inactifs, ce qui facilite la prise de décision.
- Intégration avec les outils de gestion: Complète et s’intègre à des solutions de gestion informatique telles que NinjaOne.
Dans le paysage dynamique de la gestion informatique, la sécurité et l’efficacité de la gestion des comptes utilisateurs restent primordiales. Contrôler et traiter régulièrement les comptes d’utilisateurs inactifs n’est pas seulement une bonne pratique, c’est aussi une nécessité pour maintenir un environnement informatique sûr. C’est là que les scripts PowerShell, comme celui dont nous parlons aujourd’hui, deviennent des outils inestimables pour les professionnels de l’informatique et les fournisseurs de services gérés (MSP).
Contexte
Le script en question est conçu pour identifier et alerter les administrateurs sur les comptes inactifs ou inutilisés dans un environnement Windows. Les comptes inactifs peuvent représenter un risque important pour la sécurité, en servant de points d’entrée potentiels pour un accès non autorisé s’ils sont compromis. Pour les professionnels de l’informatique et les MSP, ces scripts sont essentiels pour remédier de manière préventive aux failles de sécurité et garantir la conformité avec les différentes politiques et réglementations en matière d’informatique.
Le script :
<# .SYNOPSIS Alerts when there is an inactive / unused account that has not logged in or has not had their password set in the specified number of days. .DESCRIPTION Alerts when there is an inactive / unused account that has not logged in or has not had their password set in the specified number of days. .EXAMPLE -IncludeDisabled Action completed: Run Monitor Account Last Logon Result: FAILURE Output: Action: Run Monitor Account Last Logon, Result: Failed WARNING: Inactive accounts detected! Username PasswordLastSet LastLogon Enabled -------- --------------- --------- ------- Administrator 4/12/2023 9:05:18 AM 11/28/2023 10:31:06 AM True Guest 12/31/1600 4:00:00 PM False DefaultAccount 12/31/1600 4:00:00 PM False kbohlander 11/29/2023 1:49:51 PM 12/5/2023 1:09:43 PM True tuser1 12/1/2023 5:59:58 PM 12/4/2023 9:34:32 AM True krbtgt 11/27/2023 3:40:20 PM 12/31/1600 4:00:00 PM False tuser2 12/4/2023 3:40:27 PM 12/31/1600 4:00:00 PM True .EXAMPLE -Days 60 Action completed: Run Monitor Account Last Logon Result: FAILURE Output: Action: Run Monitor Account Last Logon, Result: Failed WARNING: Inactive accounts detected! Username PasswordLastSet LastLogon Enabled -------- --------------- --------- ------- Administrator 4/12/2023 9:05:18 AM 11/28/2023 10:31:06 AM True kbohlander 11/29/2023 1:49:51 PM 12/5/2023 1:09:43 PM True tuser1 12/1/2023 5:59:58 PM 12/4/2023 9:34:32 AM True tuser2 12/4/2023 3:40:27 PM 12/31/1600 4:00:00 PM True .OUTPUTS None .NOTES Minimum OS Architecture Supported: Windows 7, Windows Server 2012 Exit code 1: Found users that haven't logged in over X days and are enabled. Exit code 2: Calling "net.exe user" or "Get-LocalUser" failed. Release Notes: Renamed script, added Script Variable support, improved ad support, removed requires statement. By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA). #> [CmdletBinding()] param ( [Parameter()] [int]$Days = 90, [Parameter()] [switch]$IncludeDisabled = [System.Convert]::ToBoolean($env:includeDisabled) ) begin { # Use script variables if available. if ($env:days -and $env:days -notlike "null") { $Days = $env:Days } # Change negative days to the expected positive days if ($Days -lt 0) { $Days = 0 - $Days } # Date where an account is considered inactive. $InactivityCutOff = (Get-Date).AddDays(-$Days) function Test-IsDomainJoined { if ($PSVersionTable.PSVersion.Major -lt 5) { return $(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain } else { return $(Get-CimInstance -Class Win32_ComputerSystem).PartOfDomain } } function Test-IsDomainController { $OS = if ($PSVersionTable.PSVersion.Major -lt 5) { Get-WmiObject -Class Win32_OperatingSystem } else { Get-CimInstance -ClassName Win32_OperatingSystem } if ($OS.ProductType -eq "2") { return $true } } # We'll want to warn that we're unable to check the actual Azure AD account # (it requires O365 credentials and a powershell module both of which are not supported by this script). function Test-IsAzureJoined { try { $dsreg = dsregcmd.exe /status | Select-String "AzureAdJoined : YES" } catch { return $False } if ($dsreg) { return $True } } # For Non-Domain Controllers we'll check net user for the information we need. function Get-NetAccountInfo { [CmdletBinding()] param( [Parameter()] [string]$User, [Parameter()] [switch]$Domain ) process { # Get user info from net.exe user $netuser = if ($Domain) { net.exe user $user /Domain }else { net.exe user $user } $success = $netuser | Select-String 'The command completed successfully.' if (-not $success) { throw "Failed to retrieve account info for user $user!" } #Pre-formatted Object $Object = New-Object psobject -Property @{ Username = $User Name = "$(($netuser | Select-String 'Full Name') -split ' ' | Select-Object -Last 1)".Trim() Enabled = "$(($netuser | Select-String 'Account active') -split ' ' | Select-Object -Last 1)".Trim() LastLogon = "$(($netuser | Select-String 'Last logon') -split ' ' | Select-Object -Last 1)".Trim() PasswordLastSet = "$(($netuser | Select-String 'Password last set') -split ' ' | Select-Object -Last 1)".Trim() } # Formatted object using PowerShell datatypes (for easier parsing later). New-Object psobject -Property @{ Username = $Object.Username Name = $Object.Name Enabled = if ($Object.Enabled -eq "Yes") { $True }elseif ($Object.Enabled -eq "No") { $False }else { $Object.Enabled } LastLogon = try { Get-Date $Object.LastLogon }catch { $Object.LastLogon }; PasswordLastSet = try { Get-Date $Object.PasswordLastSet }catch { $Object.PasswordLastSet } } } } } process { # If it's an azure joined machine we should warn that we're not checking any of the Azure AD Accounts. if (Test-IsAzureJoined) { Write-Warning -Message "This script is unable to check Azure AD accounts however this script will check the local accounts on this machine." } $Report = New-Object System.Collections.Generic.List[object] # Warn if ad accounts are not able to be checked. if (-not (Test-IsDomainController) -and (Test-IsDomainJoined) -and -not (Test-ComputerSecureChannel)) { Write-Warning "Domain is not reachable! We'll be unable to check active directory accounts!" } # There are two ways this script will check for an inactive account one of which uses the Active Directory PowerShell module which is only availalbe on Domain Controllers / machines with RSAT installed. if (-not (Test-IsDomainController)) { # Compile a list of users to check. $Users = if ($PSVersionTable.PSVersion.Major -lt 5) { Get-WmiObject -Class "win32_UserAccount" } else { Get-CimInstance -Class "win32_UserAccount" } # Grab the account info using net user (which is slightly different if it's a domain account or not). $Accounts = foreach ($User in $Users) { if ($User.Domain -ne $env:COMPUTERNAME ) { Get-NetAccountInfo -User $User.Name -Domain } else { Get-NetAccountInfo -User $User.Name } } } else { # Older OS's need to have the module manually imported. try { Import-Module ActiveDirectory } catch { Write-Error -Message "[Error] Failed to import PowerShell Active Directory Module. Is RSAT installed?" -Category DeviceError -Exception (New-Object System.Exception) } # Compile a list of users with the relevant attributes $Users = Get-AdUser -Filter * -Properties SamAccountName, DisplayName, PasswordLastSet, lastLogonTimestamp, lastLogon, Enabled # Convert that into a more parseable object $Accounts = foreach ($User in $Users) { $LastLogon = [datetime]::FromFileTime($User.lastLogon) $LastLogonTimeStamp = [datetime]::FromFileTime($User.LastLogonTimestamp) New-Object psobject -Property @{ Username = $User.SamAccountName Name = $User.DisplayName Enabled = $User.Enabled LastLogon = if ($LastLogon -gt $LastLogonTimeStamp) { $LastLogon }else { $LastLogonTimeStamp } PasswordLastSet = $User.PasswordLastSet } } } # Compile a list of accounts that could be considered inactive $InactiveAccounts = $Accounts | Where-Object { ($_.LastLogon -eq "Never" -or $_.LastLogon -lt $InactivityCutOff) -and $_.PasswordLastSet -lt $InactivityCutOff } # Filter out disabled accounts if we're asked to. if ($IncludeDisabled) { $InactiveAccounts | ForEach-Object { $Report.Add($_) } } else { $InactiveAccounts | Where-Object { $_.Enabled -notlike $False } | ForEach-Object { $Report.Add($_) } } # If no inactive accounts exit if (-not $Report) { Write-Host "No inactive accounts detected!" exit 0 } Write-Warning "Inactive accounts detected!" $Report | Format-Table -AutoSize -Property Username, PasswordLastSet, LastLogon, Enabled | Out-String | Write-Host exit 1 } end { }
Accédez à plus de 700 scripts dans le Dojo NinjaOne
Description détaillée
Le script fonctionne en plusieurs étapes :
- Initialisation des paramètres: Il commence par définir des paramètres, notamment le nombre de jours pendant lesquels un compte est considéré comme inactif et une option permettant d’inclure les comptes désactivés.
- Contrôles de l’environnement: Le script vérifie si la machine est reliée à un domaine, à un contrôleur de domaine ou à Azure AD. Cela détermine l’étendue des vérifications de comptes – local, Active Directory ou Azure.
- Récupération de compte: Pour les contrôleurs non-domaines, il récupère les informations sur les comptes à l’aide de net.exe user ou d’instances WMI/CIM, tandis que pour les contrôleurs de domaines, il utilise le module Active Directory PowerShell.
- Évaluation de l’activité: La fonction principale consiste à évaluer les comptes d’utilisateurs sur la base de leurs dernières dates de connexion et de définition du mot de passe par rapport au seuil d’inactivité.
- Génération de rapports: Les comptes inactifs sont compilés dans un rapport, avec une option permettant d’exclure les comptes désactivés.
- Alertes et codes de sortie: Le script se termine en alertant les administrateurs de tout compte inactif et en sortant avec un code indiquant la présence ou l’absence de tels comptes.
Cas d’utilisation potentiels
Prenons l’exemple d’un administrateur informatique d’une grande entreprise qui utilise ce script pour vérifier régulièrement les comptes d’utilisateurs. Ils peuvent programmer l’exécution du script une fois par mois, afin d’être alertés des comptes qui n’ont pas été actifs depuis plus de 90 jours. Cela permet une gestion proactive des comptes d’utilisateurs, réduisant ainsi le risque de failles de sécurité dues à des comptes dormants.
Comparaisons
Il existe d’autres approches, telles que les audits manuels ou l’utilisation d’outils tiers. Toutefois, ce script PowerShell offre une solution plus directe, plus personnalisable et plus économique. Contrairement aux contrôles manuels, il automatise le processus, ce qui permet de gagner du temps et de réduire les erreurs humaines. Par rapport aux outils tiers, il offre transparence et flexibilité, les professionnels de l’informatique pouvant modifier le script en fonction de leurs besoins spécifiques.
FAQ
Q1 : Le script peut-il faire la distinction entre les différents types de comptes d’utilisateurs ?
A1 : Oui, il peut faire la distinction entre les comptes locaux, Active Directory et Azure AD.
Q2 : Est-il possible de programmer l’exécution automatique de ce script ?
A2 : Absolument, cela peut être fait en utilisant le planificateur de tâches de Windows ou des outils d’automatisation similaires.
Q3 : Ce script gère-t-il les comptes dans un environnement en nuage ?
A3 : Il est principalement conçu pour les comptes locaux et Active Directory ; les comptes Azure AD nécessitent des modules et des informations d’identification supplémentaires.
Implications
Les implications de l’utilisation de ce script sont considérables. En identifiant les comptes inactifs, il réduit considérablement la surface d’attaque pour les failles de sécurité potentielles. Toutefois, les professionnels de l’informatique doivent gérer les résultats de manière responsable, en veillant à ce que la désactivation ou la suppression des comptes soit conforme aux politiques de l’organisation et aux besoins des utilisateurs.
Recommandations
- Audits réguliers: Programmez l’exécution du script à intervalles réguliers.
- Personnalisation: Adaptez les paramètres du script aux politiques de l’organisation.
- Actions de suivi: Établissez un protocole pour le traitement des comptes inactifs.
Conclusion :
En conclusion, les scripts de ce type, lorsqu’ils sont utilisés efficacement, contribuent de manière significative à la sécurité et à l’efficacité globales des opérations informatiques. Ils complètent des solutions telles que NinjaOne, qui fournit des outils de gestion informatique complets, aidant les administrateurs à garder le contrôle de leurs environnements informatiques. La capacité de NinjaOne à s’intégrer aux scripts PowerShell renforce son utilité, ce qui en fait un choix idéal pour une gestion informatique proactive.