Skip to content

Instantly share code, notes, and snippets.

@MSAdministrator
Last active February 21, 2024 21:09
Show Gist options
  • Save MSAdministrator/41df43e780993e48bf637a4ccd0e4c68 to your computer and use it in GitHub Desktop.
Save MSAdministrator/41df43e780993e48bf637a4ccd0e4c68 to your computer and use it in GitHub Desktop.
PowerShell functions to create a new user profile
<#
.Synopsis
Rough PS functions to create new user profiles
.DESCRIPTION
Call the Create-NewProfile function directly to create a new profile
.EXAMPLE
Create-NewProfile -Username 'testUser1' -Password 'testUser1'
.NOTES
Created by: Josh Rickard (@MS_dministrator)
Date: 24MAR2017
Location: https://gist.github.com/MSAdministrator/41df43e780993e48bf637a4ccd0e4c68
Contact: https://github.com/MSAdministrator
MSAdministrator.com
#>
#Function to create the new local user first
function New-LocalUser
{
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$userName,
# Param2 help description
[string]
$password
)
$system = [ADSI]"WinNT://$env:COMPUTERNAME";
$user = $system.Create("user",$userName);
$user.SetPassword($password);
$user.SetInfo();
$flag=$user.UserFlags.value -bor 0x10000;
$user.put("userflags",$flag);
$user.SetInfo();
$group = [ADSI]("WinNT://$env:COMPUTERNAME/Users");
$group.PSBase.Invoke("Add", $user.PSBase.Path);
}
#function to register a native method
function Register-NativeMethod
{
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string]$dll,
# Param2 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[string]
$methodSignature
)
$script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
}
#function to add native method
function Add-NativeMethods
{
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param()
$nativeMethodsCode = $script:nativeMethods | % { "
[DllImport(`"$($_.Dll)`")]
public static extern $($_.Signature);
" }
Add-Type @"
using System;
using System.Text;
using System.Runtime.InteropServices;
public static class NativeMethods {
$nativeMethodsCode
}
"@
}
#Main function to create the new user profile
function Create-NewProfile {
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string]$UserName,
# Param2 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[string]
$Password
)
Write-Verbose "Creating local user $Username";
try
{
New-LocalUser $UserName $Password;
}
catch
{
Write-Error $_.Exception.Message;
break;
}
$script:nativeMethods = @();
if (-not ([System.Management.Automation.PSTypeName]'NativeMethods').Type)
{
Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
[MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
[Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
Add-NativeMethods;
}
$localUser = New-Object System.Security.Principal.NTAccount("$UserName");
$userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
$sb = new-object System.Text.StringBuilder(260);
$pathLen = $sb.Capacity;
Write-Verbose "Creating user profile for $Username";
try
{
[NativeMethods]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null;
}
catch
{
Write-Error $_.Exception.Message;
break;
}
}
@crshnbrn66
Copy link

I'm looking for a means to create a profile for a Domain user on a host before they login. Thus speeding up their login process when they are remote.

@crshnbrn66
Copy link

added function to what you have and it seems to work

function New-ProfileFromSID {

[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
    # Param1 help description
    [Parameter(Mandatory=$true,
               ValueFromPipelineByPropertyName=$true,
               Position=0)]
    [string]$UserName,

    # Param2 help description
    [Parameter(Mandatory=$true,
               ValueFromPipelineByPropertyName=$true,
               Position=1)]
    [string]
    $SID
)

$script:nativeMethods = @();

if (-not ([System.Management.Automation.PSTypeName]'NativeMethods').Type)
{
    Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
     [MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
     [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";

    Add-NativeMethods;
}

$sb = new-object System.Text.StringBuilder(260);
$pathLen = $sb.Capacity;

Write-Verbose "Creating user profile for $Username";

try
{
    [NativeMethods]::CreateProfile($SID, $Username, $sb, $pathLen) | Out-Null;
}
catch
{
    Write-Error $_.Exception.Message;
    break;
}

}

@batchenr
Copy link

Hey, Do you know why i cannot make this work for me ? copied all functions to ps and when i write user and password i get this error:

PS C:\Users\Joshua> Create-NewProfile

cmdlet Create-NewProfile at command pipeline position 1
Supply values for the following parameters:
UserName: test
Password: 123456789
Create-NewProfile : A positional parameter cannot be found that accepts argument '123456789'.
At line:1 char:1
+ Create-NewProfile
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Create-NewProfile

powershell version:

PS C:\Users\Joshua> (Get-Host).Version

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      18362  145

Windows10 Enterprise

@b1naryzer0
Copy link

Sorry for commenting this old post, but I think I know why this doesn't work. Powershell 5.1 already provides a New-LocalUser commandlet so

  1. comment out the whole New-LocalUser function
  2. in the Create-NewProfile function, change 'New-LocalUser $UserName $Password' to the following:
    $SecurePwd = ConvertTo-SecureString $Password -AsPlainText -Force
    New-LocalUser -Name $UserName -password $SecurePwd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment