'Testing if a user exist locally always return false
I'm trying to write a custom powershell script that will create a local user if no user exists with the specified name.
I have this script :
function Ensure-LocalUser
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $userName,
[Parameter(Mandatory=$true)]
[string] $passWord
)
process{
$objOu = [ADSI]"WinNT://${env:Computername}"
$localUsers = $objOu.Children | where {$_.SchemaClassName -eq 'user'} | Select {$_.name[0].ToString()}
if($localUsers -NotContains $userName)
{
$objUser = $objOU.Create("User", $userName)
$objUser.setpassword($password)
$objUser.SetInfo()
$objUser.description = "CMM Test user"
$objUser.SetInfo()
return $true
}
else
{
return $false
}
}
}
The part related to the creation of the user works, but my -NotContains verification always return false. This leads to a failing attempt to create a user because the user already exists. Using a debugger, I can see that $localusers actually contains the username I'm looking for.
How can I correct my script to reach my goal ?
Solution 1:[1]
You're doing it wrong ;) You really want this (which will create an array of strings):
$ou.Children | where {$_.SchemaClassName -eq 'user'} | foreach {
$_.name[0].tostring() }
Your code is creating a custom object with a property called "$_.name[0].ToString()"
Solution 2:[2]
In PowerShell 5.1 (available in Windows 10) and later, there are two cmdlets we can use for checking the existence of a local user and creating a new local user: Get-LocalUser and New-LocalUser.
So we can rewrite the above function in a more compact way:
function Ensure-LocalUser
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $userName,
[Parameter(Mandatory=$true)]
[string] $passWord
)
process{
$out = Get-LocalUser -Name $userName -ErrorAction SilentlyContinue
if($out -eq $null)
{
$passEnc = ConvertTo-SecureString -String $passWord -AsPlainText -Force
New-LocalUser -Name $userName -Password $passEnc -AccountNeverExpires -PasswordNeverExpires
return $true
}
else
{
write-host ("User '"+ $userName + "' already exists")
return $false
}
}
}
then call the function like this:
Ensure-LocalUser "john" "p@ssw0rd"
Solution 3:[3]
I know I am late to the party, but here is an easy way to find local users and output their current state.
# Find User Account to change
$usercheck = Get-WmiObject Win32_UserAccount -Filter "LocalAccount='true' and Name='Administrator'"
if($usercheck.disabled -eq $false){write-host "Account has been found"}
elseif($usercheck.disabled -eq $true){write-host "Account has been found, but disabled"}
else{write-host "Account has not been found."}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | x0n |
| Solution 2 | Vlad S. |
| Solution 3 | Danishan |
