<# .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) and Thom Schumacher (@driberif) Forked by: @crshnbrn66, then @pjh (2018-11-08). See https://gist.github.com/pjh/9753cd14400f4e3d4567f4553ba75f1d/revisions Date: 24MAR2017 Location: https://gist.github.com/crshnbrn66/7e81bf20408c05ddb2b4fdf4498477d8 Contact: https://github.com/MSAdministrator MSAdministrator.com https://github.com/crshnbrn66 powershellposse.com #> # IMPORTANT PLEASE NOTE: # Any time the file structure in the `windows` directory changes, `windows/BUILD` # and `k8s.io/release/lib/releaselib.sh` must be manually updated with the changes. # We HIGHLY recommend not changing the file structure, because consumers of # Kubernetes releases depend on the release structure remaining stable. #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 Get-Win32LastError { [CmdletBinding()] [Alias()] [OutputType([int])] Param($typeName = 'LastError') if (-not ([System.Management.Automation.PSTypeName]$typeName).Type) { $lasterrorCode = $script:lasterror | ForEach-Object{ '[DllImport("kernel32.dll", SetLastError = true)] public static extern uint GetLastError();' } Add-Type @" using System; using System.Text; using System.Runtime.InteropServices; public static class $typeName { $lasterrorCode } "@ } } #function to add native method function Add-NativeMethods { [CmdletBinding()] [Alias()] [OutputType([int])] Param($typeName = 'NativeMethods') $nativeMethodsCode = $script:nativeMethods | ForEach-Object { " [DllImport(`"$($_.Dll)`")] public static extern $($_.Signature); " } Add-Type @" using System; using System.Text; using System.Runtime.InteropServices; public static class $typeName { $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 $UserName -password $Password; } catch { Write-Error $_.Exception.Message; break; } $methodName = 'UserEnvCP' $script:nativeMethods = @(); if (-not ([System.Management.Automation.PSTypeName]$MethodName).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 -typeName $MethodName; } $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 { [UserEnvCP]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null; } catch { Write-Error $_.Exception.Message; break; } } function New-ProfileFromSID { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$UserName, [string]$domain = 'PHCORP' ) $methodname = 'UserEnvCP2' $script:nativeMethods = @(); if (-not ([System.Management.Automation.PSTypeName]$methodname).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 -typeName $methodname; } $sb = new-object System.Text.StringBuilder(260); $pathLen = $sb.Capacity; Write-Verbose "Creating user profile for $Username"; #$SID= ((get-aduser -id $UserName -ErrorAction Stop).sid.value) if($domain) { $objUser = New-Object System.Security.Principal.NTAccount($domain, $UserName) $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) $SID = $strSID.Value } else { $objUser = New-Object System.Security.Principal.NTAccount($UserName) $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) $SID = $strSID.Value } Write-Verbose "$UserName SID: $SID" try { $result = [UserEnvCP2]::CreateProfile($SID, $Username, $sb, $pathLen) if($result -eq '-2147024713') { $status = "$userName already exists" write-verbose "$username Creation Result: $result" } elseif($result -eq '-2147024809') { $staus = "$username Not Found" write-verbose "$username creation result: $result" } elseif($result -eq 0) { $status = "$username Profile has been created" write-verbose "$username Creation Result: $result" } else { $status = "$UserName unknown return result: $result" } } catch { Write-Error $_.Exception.Message; break; } $status } Function Remove-Profile { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$UserName, [string]$ProfilePath, [string]$domain = 'PHCORP' ) $methodname = 'userenvDP' $script:nativeMethods = @(); if (-not ([System.Management.Automation.PSTypeName]"$methodname.profile").Type) { add-type @" using System.Runtime.InteropServices; namespace $typename { public static class UserEnv { [DllImport("userenv.dll", CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)] public static extern bool DeleteProfile(string sidString, string profilePath, string computerName); [DllImport("kernel32.dll")] public static extern uint GetLastError(); } public static class Profile { public static uint Delete(string sidString) { //Profile path and computer name are optional if (!UserEnv.DeleteProfile(sidString, null, null)) { return UserEnv.GetLastError(); } return 0; } } } "@ } #$SID= ((get-aduser -id $UserName -ErrorAction Stop).sid.value) if($domain) { $objUser = New-Object System.Security.Principal.NTAccount($domain, $UserName) $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) $SID = $strSID.Value } else { $objUser = New-Object System.Security.Principal.NTAccount($UserName) $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]) $SID = $strSID.Value } Write-Verbose "$UserName SID: $SID" try { #http://stackoverflow.com/questions/31949002/c-sharp-delete-user-profile $result = [userenvDP.Profile]::Delete($SID) } catch { Write-Error $_.Exception.Message; break; } $LastError } Export-ModuleMember Create-NewProfile