Reputation: 2207
There are two parts to this question.
$password = ConvertTo-SecureString -String "password" -AsPlainText -Force $op = Get-LocalUser | Where-Object {$_.Name -eq "testuser1"} if ( -not $op) { New-LocalUser testuser1 -Password $password | Out-Null }
I tested this one out on my setup and it works fine for the most part without throwing any exception. Is there a better, quicker way to check if a user exists ? Also, is the script I'm using foolproof i.e. would it be better to handle it using ErrorAction or using try....catch ?
I'll be using this script for checking more than a couple of user accounts before I go ahead and create them.
CASE 1
CASE 2
I understand that Out-String is the reason behind this difference in output but I would've expected the output to have been more than just testuser1 in CASE 1.
I'm new to Powershell so can someone please help me understand why there's a difference in output ?
Upvotes: 6
Views: 53223
Reputation: 1784
The old style usage of [ADSI]
and WinNT:
is also a valid option even with PowerShell 7.
And it works equally well with local as well as with domain accounts.
But it's quite legacy.
$UserName = './TestUser'
$WinNtUser = [ADSI]"WinNT://$UserName,user"
if (! $WinNtUser.Name) {
throw "User $UserName was not found"
}
Upvotes: 0
Reputation: 115
The first line calls the Get-LocalUser commandlet and uses the Name parameter to Specify the user be searched for. If that user is found the assignment of the variable $UserID will happen. If Get-LocalUser cannot find the user then it errors out and no assignment happens. Specifying the ErrorAction "SilentlyContinue" will tell PowerShell not to stop or alert that there if there was an error making the assignment.
The If($UserID) test will return True if the assignment of the Variable happened successfully and False if did not.
$UserID = Get-LocalUser -Name 'UserName' -ErrorAction SilentlyContinue
if($UserID){
Write-Host 'User Found'
}else{
Write-Host 'User Not Found'
} #end if user exists
Upvotes: 4
Reputation: 601
Use Try/Catch, most of the time it's faster to just ask and let Powershell handle the searching ;)
Especially with Long User lists, retrieving all the users and then iterating trough all of them will slow things down, just asking for a specific user is much faster but you need to handle the error if the user does not exist.
See example below:
Clear-Host
$ErrorActionPreference = 'Stop'
$VerbosePreference = 'Continue'
#User to search for
$USERNAME = "TestUser"
#Declare LocalUser Object
$ObjLocalUser = $null
try {
Write-Verbose "Searching for $($USERNAME) in LocalUser DataBase"
$ObjLocalUser = Get-LocalUser $USERNAME
Write-Verbose "User $($USERNAME) was found"
}
catch [Microsoft.PowerShell.Commands.UserNotFoundException] {
"User $($USERNAME) was not found" | Write-Warning
}
catch {
"An unspecifed error occured" | Write-Error
Exit # Stop Powershell!
}
#Create the user if it was not found (Example)
if (!$ObjLocalUser) {
Write-Verbose "Creating User $($USERNAME)" #(Example)
# ..... (Your Code Here)
}
About outputting certain data, I recommend that you explicitly define what you want to output, this way their will be no surprises and it makes thing clearer in your code.
See the example below, I explicitly defined the 3 properties I wanted and then forced it into a Table-View, to finish I converted it to a string, so no surprises for me any more ;)
Get-LocalUser | Select Name, Enabled, PasswordLastSet | Format-Table | Out-String
Example output
Name Enabled PasswordLastSet
---- ------- ---------------
Administrator False
DefaultAccount False
Gast False
Test-Gebruiker True 24-12-2017 01:58:12
Upvotes: 9
Reputation: 101
You can use measure to check if user exist
$op = Get-LocalUser | where-Object Name -eq "yourusername" | Measure
if ($op.Count -eq 0) {
# DO SOMETHING
} else {
# REPORT SOMETHING
}
Upvotes: 5
Reputation: 3023
Write-Host
calls ToString()
method implementation of an object behind the scenes.
Write-Host $op
is equivalent to
Write-Host $op.ToString()
Get-LocalUser | Where-Object {$_.Name -eq "testuser1"}
returns a LocalUser
object. LocalUser.ToString()
implementation returns Name
property, that's why you see testuser1
as output.
Out-String
on the other hand, converts the whole output of the command, which is a table representation of LocalUser
object with 3 properties.
In Case 2, you can only use that output as a String
object, whereas in Case 1, $op
is a LocalUser
object that you can manipulate or access properties. For example, you can print more properties:
Write-Host $op.Name, $op.Enabled, $op.Description
In order to see all the properties/methods available on an object, run Get-Member
cmdlet:
$op | Get-Member
Upvotes: 1