Creating Local Users
I’m helping some of our test teams more and more. In one case, we need to create local users in bulk.
I’m surprised PSH doesn’t have something for this.
function New-LocalUser
{
<#
.syopsis
Creates a local user account
.parameter UserName
Username of local user to be created. Ignored if -Credential specified.
Legal username characters are A-Z, a-z, 0-9, _, and - characters.
If length is greater than 15, it will be truncated to 15 characters.
Defaults to [DateTime].ToString('_yyyyMMddHHmmss').
If username already exists on local machine, script will generate a warning.
.parameter Password
Password for local user to be created. Ignored if -Credential specified.
Legal password characters are [char]33 until [char]126.
If length is less than 8, function will stop.
Defaults to randomly generated string of length specified by -PasswordLength.
.parameter FullName
String to populate "Full Name" property. "Description" property will be populated with "$FullName (Created [DateTime])";
Defaults to "Test User."
.parameter PasswordLength
Auto-generated password length. Ignored if -Credential specified.
Defaults to 24 characters.
.parameter Credential
PSCredential to add to local computer.
.parameter IsAdministrator
Add specified user to the local administrators group.
.inputs
None
.outputs
PSCredential
.links
https://gallery.technet.microsoft.com/scriptcenter/504cf1a7-c5e3-4a8f-b734-488b90a5965b
https://blogs.technet.com/b/heyscriptingguy/archive/2008/05/22/how-can-i-use-windows-powershell-to-determine-whether-a-local-user-account-exists.aspx
#>
param (
[string]$UserName = $null,
[string]$Password = $null,
[string]$FullName = "Test User",
[int]$PasswordLength = 24,
[System.Management.Automation.PSCredential]$Credential = $null,
[switch]$IsAdministrator
);
$timeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss';
# get / create password
if ($Credential)
{
$UserName = $Credential.UserName;
$Password = [System.Runtime.InteropServices.marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.marshal]::SecureStringToBSTR($Credential.Password)
);
} # if ($Credential)
if (!$Password)
{
$rand = New-Object System.Random;
1..$PasswordLength |
ForEach-Object -begin { $Password = $null; } -process { $Password = $Password + [char]$rand.next(33,127); }
} # if (!$Password)
if ($Password.Length -lt 8)
{
Write-Warning "$($MyInvocation.MyCommand.Name) supplied password must e at least 8 characters long. Stopping";
return;
} # if ($Password.Length -lt 8)
$securePass = ConvertTo-SecureString -AsPlainText $password -Force;
# get / create username (note: -Credential if test above gets username
if (!$UserName) { $userName = "_$($timeStamp -replace '\D')"; }
$UserName = $UserName -replace "[^\w-]";
if ($UserName.Length -gt 15) { $UserName = $UserName.Substring(0,15); }
$adsiComputerObject = [ADSI]("WinNT://$env:ComputerName,computer")
if (
$adsiComputerObject.Children |
? {
$_.SchemaClassName -eq 'User' -and
$_.Name -eq $UserName
}
)
{
Write-Warning "$($MyInvocation.MyCommand.Name) -UserName '$UserName' exists.";
} # if ($adsiComputerObject.Children ...
else
{
$localAdminGroup = $adsiComputerObject.Children |
? { ($_.SchemaClassName -eq 'User') -and ($_.Name -eq 'Administrator'); } |
Select-Object -First 1;
& {
$userObject = $adsiComputerObject.Create("User", $UserName);
$userObject.SetPassword($Password);
$userObject.Put("Description", "$FullName (Created $timeStamp)");
$userObject.Put("FullName", "$FullName");
$userObject.SetInfo();
} | Out-Null
} # if ($adsiComputerObject.Children ... else
if ($IsAdministrator) { ([ADSI]"WinNT://$Env:ComputerName/Administrators,group").Add("WinNT://$UserName"); }
New-Object System.Management.Automation.PSCredential $Username, $SecurePass;
} # function New-LocalUser