Je pensais que j'étais assez bon en PowerShell, mais je n'ai jamais eu à travailler avec les informations d'identification des utilisateurs. Cependant, maintenant je suis dans une recherche d'emploi et lors d'une des entrevues, j'ai eu une tâche de test pour écrire un script qui était censé:
- Vérifiez la disponibilité et l'état (activé / désactivé) du compte utilisateur.
- Vérifiez si le compte est inclus dans le groupe Administrateurs
- S'il n'y a pas de compte, créez un compte et ajoutez-le au groupe d'administrateurs, cochez les cases «Interdire la modification du mot de passe utilisateur» et «Le mot de passe n'est pas expiré»
- Si le compte existe, mais est désactivé ou n'est pas inclus dans le groupe Administrateurs, activez le compte et ajoutez-le au groupe Administrateurs, cochez les cases en regard de «Refuser le changement de mot de passe par utilisateur» et «Le mot de passe n'est pas expiré»
- Le script ne doit pas dépendre de la langue du système d'exploitation.
Je pensais qu'il n'y avait rien de compliqué, et la première chose que j'ai décidé de vérifier était l'utilisateur Admin sur mon ordinateur. Sans réfléchir à deux fois, j'ai conduit une commande:
Get-User admin
Et puis j'ai eu une erreur
Get-User : "Get-User" , , .
Un peu surpris car je n'ai pas reconnu une commande aussi utile et j'ai constaté que la commande
Get-User ne fonctionne que dans la console Powershell pour Exchange. Pour travailler avec des utilisateurs locaux, vous devez utiliser
Get-Localuser et pour les
utilisateurs du domaine
Get-Aduser . Réalisant mon erreur, j'ai conduit:
Get-Localuser admin
Et j'ai une réponse
Name Enabled Description
Bon, maintenant ce n’est plus un problème de vérifier si l’utilisateur est là ou pas, mais là encore j’attendais une autre prise. L'utilisation de l'instruction conditionnelle if else ne s'est pas avérée si facile.
Le fait est que si l'utilisateur est dans le système, la sortie n'est pas la valeur true, mais tout un ensemble de données, avec le nom et la description de l'utilisateur, est ce compte activé ou non. Et s'il n'y a pas d'utilisateur, powershell lance une erreur. Après avoir erré sur Internet, j'ai trouvé qu'à ces fins, il est préférable d'utiliser l'opérateur
try catch .
$user = 'admin' try { Get-LocalUser $user -ErrorAction Stop | Out-Null write-host $user -foregroundcolor Green } Catch { write-host $user -foregroundcolor Red }
J'ai ajouté la variable $ user pour faciliter la modification des noms d'utilisateur dans l'ensemble du script. ErrorAction Stop est nécessaire pour que le script ne s'interrompe pas à cette étape en raison d'une erreur. Signe | sépare les étapes du pipeline et Out-Null masquera la sortie du texte d'erreur. J'ai également ajouté une sortie texte avec surlignage, pour la commodité de vérifier le script.
Ensuite, je voulais vérifier si le compte était activé ou désactivé. Comme je l'ai déjà dit, la commande Get-LocalUser produit un ensemble complet de données et pour la vérification, je devais sélectionner un seul paramètre activé avec une valeur true ou false. Pour ce faire, j'ai utilisé la commande suivante:
(Get-LocalUser $user).enabled
Après m'être assuré que cela fonctionne, j'ai effectué la vérification suivante et ajouté une commande d'activation de l'utilisateur.
$user = 'admin' if ((Get-LocalUser $user).enabled -eq "True") { write-host -foregroundcolor Green } else { write-host -foregroundcolor Red Enable-LocalUser $user write-host -foregroundcolor Green }
Pour activer l'utilisateur, il est naturellement nécessaire d'exécuter la console avec des droits d'administrateur.
Dans le deuxième paragraphe de la tâche, il était nécessaire de déterminer si l'utilisateur est membre du groupe d'administrateurs. Pour vérifier si un utilisateur se trouve dans un groupe particulier, il existe une commande Get-LocalGroupMember. Cependant, le nom du groupe d'administrateurs varie de la langue du système d'exploitation. Par conséquent, j'ai dû utiliser le SID standard S-1-5-32-544. J'ai également vérifié par une prise d'essai.
$user = 'admin' try { Get-LocalGroupMember -SID S-1-5-32-544 -Member $user -ErrorAction Stop | Out-Null write-host $user -foregroundcolor Green } Catch { write-host $user -foregroundcolor Red Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host $user -foregroundcolor Green }
Si l'utilisateur n'est pas membre du groupe, des administrateurs y seront ajoutés.
À l'étape suivante, j'ai eu la tâche de déterminer si l'utilisateur a désactivé ou non le paramètre de changement de mot de passe. Puis je suis tombé sur un autre piège. Le fait est que si l'utilisateur a un mot de passe illimité, le paramètre PasswordExpires ne renvoie aucune valeur. Et si cette case est désactivée, différents utilisateurs auront une date de changement de mot de passe différente. J'ai toujours trouvé un moyen de sortir de cette situation:
if ((Get-LocalUser $user).PasswordExpires -eq $null) { write-host -foregroundcolor Green } else { write-host -foregroundcolor Red set-LocalUser $user -PasswordNeverExpires:$true write-host -foregroundcolor Green }
Ensuite, je devais créer un utilisateur. Je ne m'attendais pas non plus à ce qu'une prise m'attende ici. Lors de la création d'un utilisateur avec la commande
new-LocalUser -User $user -password P@ssW0rD!
Erreur renvoyée:
"Password". "P@ssW0rD!" "System.String" "System.Security.SecureString".
Le fait est que le paramètre -password doit utiliser SecureString, au lieu de la chaîne de texte habituelle. Pour ce faire, j'ai créé la variable $ password et l'ai convertie en chaîne de sécurité.
$password = convertto-securestring "P@ssW0rD!" -asplaintext -force
Et le script lui-même pour créer un utilisateur et l'ajouter au groupe d'administrateurs
new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user
Le script fini qui prend en compte toutes les conditions que j'ai obtenues de cette façon:
$user = 'admin' $password = convertto-securestring "P@ssW0rD!" -asplaintext -force try { Get-LocalUser $user -ErrorAction Stop | Out-Null cls write-host $user -foregroundcolor Green if ((Get-LocalUser $user).enabled -eq "True") { write-host -foregroundcolor Green } else { write-host -foregroundcolor Red Enable-LocalUser $user write-host -foregroundcolor Green } if ((Get-LocalUser $user).PasswordExpires -eq $null) { write-host -foregroundcolor Green } else { write-host -foregroundcolor Red set-LocalUser $user -PasswordNeverExpires:$true write-host -foregroundcolor Green } try { Get-LocalGroupMember -SID S-1-5-32-544 -Member $user -ErrorAction Stop | Out-Null write-host $user -foregroundcolor Green } Catch { write-host $user -foregroundcolor Red Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host $user -foregroundcolor Green } } Catch { cls write-host $user -foregroundcolor Red new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host $user -foregroundcolor Green }
Post scriptum
Cependant, le stockage du mot de passe administrateur dans un script n'est pas la meilleure pratique de sécurité. Pour ce faire, vous pouvez utiliser le hachage de mot de passe, pas le mot de passe lui-même.
$user = 'admin1' $hash = "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000048baf1b47a72d845b4eeda8659da9fd70000000002000000000010660000000100002000000004d2a3bf03aac92c2e172dc002d1fe8759da4655850462aface5c25f52921e05000000000e8000000002000020000000bfa652b6f7cc6845e3cee1831b54ab93dc272d0b2203024c3de8bc4789a2698a10000000923fb50dcf01125913534d0c1ba6d827400000002757df7d8a8b39c8e84b81323acff1d72419580a0022cf610926e5f081a2e895320088d482eb407f8157aad82f091abee7427b357e871d12238a8f74131238e7" $hash $password = ConvertTo-SecureString -String $hash $password new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user
Pour obtenir un hachage de mot de passe, vous pouvez utiliser le script suivant
$Secure = Read-Host -AsSecureString $Secure $hash = ConvertFrom-SecureString -SecureString $Secure $hash
Qui demande un mot de passe au clavier.
Et un petit bonus pour afficher tous les enregistrements désactivés
Get-LocalUser | Where-Object {$_.enabled -eq $false}
J'espère que le temps que j'ai passé aide quelqu'un dans son travail. Et pour vous, il sera utile de ne pas oublier cette expérience inestimable.