user-profile.psm1 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <#
  2. .Synopsis
  3. Rough PS functions to create new user profiles
  4. .DESCRIPTION
  5. Call the Create-NewProfile function directly to create a new profile
  6. .EXAMPLE
  7. Create-NewProfile -Username 'testUser1' -Password 'testUser1'
  8. .NOTES
  9. Created by: Josh Rickard (@MS_dministrator) and Thom Schumacher (@driberif)
  10. Forked by: @crshnbrn66, then @pjh (2018-11-08). See
  11. https://gist.github.com/pjh/9753cd14400f4e3d4567f4553ba75f1d/revisions
  12. Date: 24MAR2017
  13. Location: https://gist.github.com/crshnbrn66/7e81bf20408c05ddb2b4fdf4498477d8
  14. Contact: https://github.com/MSAdministrator
  15. MSAdministrator.com
  16. https://github.com/crshnbrn66
  17. powershellposse.com
  18. #>
  19. # IMPORTANT PLEASE NOTE:
  20. # Any time the file structure in the `windows` directory changes, `windows/BUILD`
  21. # and `k8s.io/release/lib/releaselib.sh` must be manually updated with the changes.
  22. # We HIGHLY recommend not changing the file structure, because consumers of
  23. # Kubernetes releases depend on the release structure remaining stable.
  24. #Function to create the new local user first
  25. function New-LocalUser
  26. {
  27. [CmdletBinding()]
  28. [Alias()]
  29. [OutputType([int])]
  30. Param
  31. (
  32. # Param1 help description
  33. [Parameter(Mandatory=$true,
  34. ValueFromPipelineByPropertyName=$true,
  35. Position=0)]
  36. $userName,
  37. # Param2 help description
  38. [string]
  39. $password
  40. )
  41. $system = [ADSI]"WinNT://$env:COMPUTERNAME";
  42. $user = $system.Create("user",$userName);
  43. $user.SetPassword($password);
  44. $user.SetInfo();
  45. $flag=$user.UserFlags.value -bor 0x10000;
  46. $user.put("userflags",$flag);
  47. $user.SetInfo();
  48. $group = [ADSI]("WinNT://$env:COMPUTERNAME/Users");
  49. $group.PSBase.Invoke("Add", $user.PSBase.Path);
  50. }
  51. #function to register a native method
  52. function Register-NativeMethod
  53. {
  54. [CmdletBinding()]
  55. [Alias()]
  56. [OutputType([int])]
  57. Param
  58. (
  59. # Param1 help description
  60. [Parameter(Mandatory=$true,
  61. ValueFromPipelineByPropertyName=$true,
  62. Position=0)]
  63. [string]$dll,
  64. # Param2 help description
  65. [Parameter(Mandatory=$true,
  66. ValueFromPipelineByPropertyName=$true,
  67. Position=1)]
  68. [string]
  69. $methodSignature
  70. )
  71. $script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
  72. }
  73. function Get-Win32LastError
  74. {
  75. [CmdletBinding()]
  76. [Alias()]
  77. [OutputType([int])]
  78. Param($typeName = 'LastError')
  79. if (-not ([System.Management.Automation.PSTypeName]$typeName).Type)
  80. {
  81. $lasterrorCode = $script:lasterror | ForEach-Object{
  82. '[DllImport("kernel32.dll", SetLastError = true)]
  83. public static extern uint GetLastError();'
  84. }
  85. Add-Type @"
  86. using System;
  87. using System.Text;
  88. using System.Runtime.InteropServices;
  89. public static class $typeName {
  90. $lasterrorCode
  91. }
  92. "@
  93. }
  94. }
  95. #function to add native method
  96. function Add-NativeMethods
  97. {
  98. [CmdletBinding()]
  99. [Alias()]
  100. [OutputType([int])]
  101. Param($typeName = 'NativeMethods')
  102. $nativeMethodsCode = $script:nativeMethods | ForEach-Object { "
  103. [DllImport(`"$($_.Dll)`")]
  104. public static extern $($_.Signature);
  105. " }
  106. Add-Type @"
  107. using System;
  108. using System.Text;
  109. using System.Runtime.InteropServices;
  110. public static class $typeName {
  111. $nativeMethodsCode
  112. }
  113. "@
  114. }
  115. #Main function to create the new user profile
  116. function Create-NewProfile {
  117. [CmdletBinding()]
  118. [Alias()]
  119. [OutputType([int])]
  120. Param
  121. (
  122. # Param1 help description
  123. [Parameter(Mandatory=$true,
  124. ValueFromPipelineByPropertyName=$true,
  125. Position=0)]
  126. [string]$UserName,
  127. # Param2 help description
  128. [Parameter(Mandatory=$true,
  129. ValueFromPipelineByPropertyName=$true,
  130. Position=1)]
  131. [string]
  132. $Password
  133. )
  134. Write-Verbose "Creating local user $Username";
  135. try
  136. {
  137. New-LocalUser -username $UserName -password $Password;
  138. }
  139. catch
  140. {
  141. Write-Error $_.Exception.Message;
  142. break;
  143. }
  144. $methodName = 'UserEnvCP'
  145. $script:nativeMethods = @();
  146. if (-not ([System.Management.Automation.PSTypeName]$MethodName).Type)
  147. {
  148. Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
  149. [MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
  150. [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
  151. Add-NativeMethods -typeName $MethodName;
  152. }
  153. $localUser = New-Object System.Security.Principal.NTAccount("$UserName");
  154. $userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
  155. $sb = new-object System.Text.StringBuilder(260);
  156. $pathLen = $sb.Capacity;
  157. Write-Verbose "Creating user profile for $Username";
  158. try
  159. {
  160. [UserEnvCP]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null;
  161. }
  162. catch
  163. {
  164. Write-Error $_.Exception.Message;
  165. break;
  166. }
  167. }
  168. function New-ProfileFromSID {
  169. [CmdletBinding()]
  170. [Alias()]
  171. [OutputType([int])]
  172. Param
  173. (
  174. # Param1 help description
  175. [Parameter(Mandatory=$true,
  176. ValueFromPipelineByPropertyName=$true,
  177. Position=0)]
  178. [string]$UserName,
  179. [string]$domain = 'PHCORP'
  180. )
  181. $methodname = 'UserEnvCP2'
  182. $script:nativeMethods = @();
  183. if (-not ([System.Management.Automation.PSTypeName]$methodname).Type)
  184. {
  185. Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
  186. [MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
  187. [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
  188. Add-NativeMethods -typeName $methodname;
  189. }
  190. $sb = new-object System.Text.StringBuilder(260);
  191. $pathLen = $sb.Capacity;
  192. Write-Verbose "Creating user profile for $Username";
  193. #$SID= ((get-aduser -id $UserName -ErrorAction Stop).sid.value)
  194. if($domain)
  195. {
  196. $objUser = New-Object System.Security.Principal.NTAccount($domain, $UserName)
  197. $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
  198. $SID = $strSID.Value
  199. }
  200. else
  201. {
  202. $objUser = New-Object System.Security.Principal.NTAccount($UserName)
  203. $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
  204. $SID = $strSID.Value
  205. }
  206. Write-Verbose "$UserName SID: $SID"
  207. try
  208. {
  209. $result = [UserEnvCP2]::CreateProfile($SID, $Username, $sb, $pathLen)
  210. if($result -eq '-2147024713')
  211. {
  212. $status = "$userName already exists"
  213. write-verbose "$username Creation Result: $result"
  214. }
  215. elseif($result -eq '-2147024809')
  216. {
  217. $staus = "$username Not Found"
  218. write-verbose "$username creation result: $result"
  219. }
  220. elseif($result -eq 0)
  221. {
  222. $status = "$username Profile has been created"
  223. write-verbose "$username Creation Result: $result"
  224. }
  225. else
  226. {
  227. $status = "$UserName unknown return result: $result"
  228. }
  229. }
  230. catch
  231. {
  232. Write-Error $_.Exception.Message;
  233. break;
  234. }
  235. $status
  236. }
  237. Function Remove-Profile {
  238. [CmdletBinding()]
  239. [Alias()]
  240. [OutputType([int])]
  241. Param
  242. (
  243. # Param1 help description
  244. [Parameter(Mandatory=$true,
  245. ValueFromPipelineByPropertyName=$true,
  246. Position=0)]
  247. [string]$UserName,
  248. [string]$ProfilePath,
  249. [string]$domain = 'PHCORP'
  250. )
  251. $methodname = 'userenvDP'
  252. $script:nativeMethods = @();
  253. if (-not ([System.Management.Automation.PSTypeName]"$methodname.profile").Type)
  254. {
  255. add-type @"
  256. using System.Runtime.InteropServices;
  257. namespace $typename
  258. {
  259. public static class UserEnv
  260. {
  261. [DllImport("userenv.dll", CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)]
  262. public static extern bool DeleteProfile(string sidString, string profilePath, string computerName);
  263. [DllImport("kernel32.dll")]
  264. public static extern uint GetLastError();
  265. }
  266. public static class Profile
  267. {
  268. public static uint Delete(string sidString)
  269. { //Profile path and computer name are optional
  270. if (!UserEnv.DeleteProfile(sidString, null, null))
  271. {
  272. return UserEnv.GetLastError();
  273. }
  274. return 0;
  275. }
  276. }
  277. }
  278. "@
  279. }
  280. #$SID= ((get-aduser -id $UserName -ErrorAction Stop).sid.value)
  281. if($domain)
  282. {
  283. $objUser = New-Object System.Security.Principal.NTAccount($domain, $UserName)
  284. $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
  285. $SID = $strSID.Value
  286. }
  287. else
  288. {
  289. $objUser = New-Object System.Security.Principal.NTAccount($UserName)
  290. $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
  291. $SID = $strSID.Value
  292. }
  293. Write-Verbose "$UserName SID: $SID"
  294. try
  295. {
  296. #http://stackoverflow.com/questions/31949002/c-sharp-delete-user-profile
  297. $result = [userenvDP.Profile]::Delete($SID)
  298. }
  299. catch
  300. {
  301. Write-Error $_.Exception.Message;
  302. break;
  303. }
  304. $LastError
  305. }
  306. Export-ModuleMember Create-NewProfile