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