Advertisement
Guest User

Untitled

a guest
Mar 7th, 2017
741
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.95 KB | None | 0 0
  1. # Reset-LocalAccountPassword.ps1
  2. # Written by Bill Stewart (bstewart@iname.com)
  3.  
  4. #requires -version 2
  5.  
  6. <#
  7. .SYNOPSIS
  8. Resets the built-in Administrator account or a named local account password on one or more computers.
  9.  
  10. .DESCRIPTION
  11. Resets the built-in Administrator account or a named local account password on one or more computers. The Administrator account is determined by its RID (500), not its name.
  12.  
  13. .PARAMETER ComputerName
  14. Specifies one or more computer names. The default is the current computer. Wildcards are not permitted.
  15.  
  16. .PARAMETER AccountName
  17. Specifies that you want to reset the password for the specified local account.
  18.  
  19. .PARAMETER AdminAccount
  20. Specifies that you want to reset the password for the built-in Administrator account.
  21.  
  22. .PARAMETER Password
  23. Specifes the new password for the account. If you omit this parameter (recommended), you will be prompted to enter the new password twice (for confirmation).
  24.  
  25. .PARAMETER Credential
  26. Specifies credentials that have permission to reset the password on the computer(s). If you omit this parameter, the current logon account must have permission to reset the password.
  27.  
  28. .EXAMPLE
  29. PS C:\> Reset-LocalAccountPassword -AdminAccount
  30. This command will reset the built-in Administrator password on the current computer.
  31.  
  32. .EXAMPLE
  33. PS C:\> Reset-LocalAccountPassword COMPUTER1,COMPUTER2 -AdminAccount -Confirm:$false
  34. This command will reset the built-in Administrator password on two different computers without prompting for confirmation.
  35.  
  36. .EXAMPLE
  37. PS C:\> Reset-LocalAccountPassword -AccountName Manager
  38. This command will reset the password for the local account named 'Manager' on the current computer.
  39.  
  40. .EXAMPLE
  41. PS C:\> Reset-LocalAccountPassword PC3,PC4 -AccountName Supervisor -Confirm:$false
  42. This command will reset the password of the local account named 'Supervisor' on two different computers without prompting for confirmation.
  43.  
  44. .EXAMPLE
  45. PS C:\> Get-Content Computers.txt | Reset-LocalAccountPassword -AdminAccount -Confirm:$false
  46. This command will reset the built-in Administrator password for the computers named in the file Computers.txt without prompting for confirmation.
  47.  
  48. .EXAMPLE
  49. PS C:\> "WG1","WG2" | Reset-LocalAccountPassword -AdminAccount -Credential (Get-Credential)
  50. This command will prompt to reset the built-in Administrator passwords on two computers. Before the command runs, it will prompt for credentials that have permission to reset the passwords.
  51. #>
  52.  
  53. [CmdletBinding(DefaultParameterSetName="NamedAccount",SupportsShouldProcess=$true,ConfirmImpact="High")]
  54. param(
  55. [Parameter(ParameterSetName="AdminAccount",Position=0,ValueFromPipeline=$true)]
  56. [Parameter(ParameterSetName="NamedAccount",Position=0,ValueFromPipeline=$true)]
  57. [String[]] $ComputerName=[Net.Dns]::GetHostName(),
  58. [Parameter(ParameterSetName="NamedAccount",Mandatory=$true)]
  59. [String] $AccountName,
  60. [Parameter(ParameterSetName="AdminAccount",Mandatory=$true)]
  61. [Switch] $AdminAccount,
  62. [Parameter(ParameterSetName="AdminAccount")]
  63. [Parameter(ParameterSetName="NamedAccount")]
  64. [Security.SecureString] $Password,
  65. [Parameter(ParameterSetName="AdminAccount")]
  66. [Parameter(ParameterSetName="NamedAccount")]
  67. [Management.Automation.PSCredential] $Credential
  68. )
  69.  
  70. begin {
  71. $ScriptName = $MyInvocation.MyCommand.Name
  72.  
  73. # Reset password for built-in Administrator account, not a named account.
  74. $AdminAccount = $PSCmdlet.ParameterSetName -eq "AdminAccount"
  75.  
  76. # Safely compares two SecureString objects without decrypting them. Returns
  77. # $true if they are equal, or $false otherwise.
  78. function Compare-SecureString {
  79. param(
  80. [Security.SecureString] $secureString1,
  81. [Security.SecureString] $secureString2
  82. )
  83. try {
  84. $bstr1 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString1)
  85. $bstr2 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString2)
  86. $length1 = [Runtime.InteropServices.Marshal]::ReadInt32($bstr1, -4)
  87. $length2 = [Runtime.InteropServices.Marshal]::ReadInt32($bstr2, -4)
  88. if ( $length1 -ne $length2 ) {
  89. return $false
  90. }
  91. for ( $i = 0; $i -lt $length1; ++$i ) {
  92. $b1 = [Runtime.InteropServices.Marshal]::ReadByte($bstr1, $i)
  93. $b2 = [Runtime.InteropServices.Marshal]::ReadByte($bstr2, $i)
  94. if ( $b1 -ne $b2 ) {
  95. return $false
  96. }
  97. }
  98. return $true
  99. }
  100. finally {
  101. if ( $bstr1 -ne [IntPtr]::Zero ) {
  102. [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr1)
  103. }
  104. if ( $bstr2 -ne [IntPtr]::Zero ) {
  105. [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr2)
  106. }
  107. }
  108. }
  109.  
  110. # Reads two SecureString objects (passwords), securely compares them, and
  111. # returns the confirmed password.
  112. function Read-PasswordWithConfirmation {
  113. if ( $AdminAccount ) {
  114. $name = "built-in Administrator account"
  115. }
  116. else {
  117. $name = "local account '$AccountName'"
  118. }
  119. do {
  120. $pass1 = Read-Host -Prompt ("Enter new password for {0}" -f $name) -AsSecureString
  121. $pass2 = Read-Host -Prompt ("Confirm new password for {0}" -f $name) -AsSecureString
  122. $equal = Compare-SecureString $pass1 $pass2
  123. if ( -not $equal ) {
  124. Write-Host "Passwords do not match"
  125. }
  126. } until ( $equal )
  127. return $pass1
  128. }
  129.  
  130. # Decrypts and returns a SecureString as a String. Required for the
  131. # DirectoryEntry constructor and SetPassword methods because these API calls
  132. # use clear-text passwords. Even though the clear-text passwords will be
  133. # temporarily available in local memory, Windows does not send clear-text
  134. # passwords over the network.
  135. function ConvertTo-String {
  136. param(
  137. [Security.SecureString] $secureString
  138. )
  139. try {
  140. $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
  141. return [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
  142. }
  143. finally {
  144. if ( $bstr -ne [IntPtr]::Zero ) {
  145. [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
  146. }
  147. }
  148. }
  149.  
  150. # Writes a custom error to the error stream.
  151. function Write-CustomError {
  152. param(
  153. [Exception] $exception,
  154. $targetObject,
  155. [String] $errorID,
  156. [Management.Automation.ErrorCategory] $errorCategory="NotSpecified"
  157. )
  158. $errorRecord = New-Object Management.Automation.ErrorRecord($exception,$errorID,$errorCategory,$targetObject)
  159. $PSCmdlet.WriteError($errorRecord)
  160. }
  161.  
  162. # If the -Password parameter is not present, read it interactively.
  163. if ( -not $Password ) {
  164. $Password = Read-PasswordWithConfirmation
  165. }
  166.  
  167. # Set up the process action string.
  168. if ( $AdminAccount ) {
  169. $ProcessAction = "Reset password for built-in Administrator account"
  170. }
  171. else {
  172. $ProcessAction = "Reset password for local account '$AccountName'"
  173. }
  174.  
  175. # Called from script's process block: Resets the requested local account
  176. # password (either built-in Administrator account or a named account).
  177. function Reset-LocalAccountPassword {
  178. [CmdletBinding(ConfirmImpact="High")]
  179. param(
  180. [Parameter(ValueFromPipeline=$true)]
  181. [String[]] $computerName
  182. )
  183. process {
  184. $computerAdsPath = "WinNT://$computerName,Computer"
  185. if ( -not $Credential ) {
  186. $computer = [ADSI] $computerAdsPath
  187. }
  188. else {
  189. $computer = New-Object DirectoryServices.DirectoryEntry($computerAdsPath,$Credential.UserName,(ConvertTo-String $Credential.Password))
  190. }
  191. try {
  192. # Piping to Format-List forces PowerShell to connect to the computer
  193. # (we're only interested in a possible exception).
  194. [Void] ($computer | Format-List)
  195. }
  196. catch {
  197. $message = "Unable to connect to computer '$computerName' due to the following error: '{0}'" -f ($_.Exception.InnerException.Message -replace '\n+$', '')
  198. $exception = New-Object ($_.Exception.GetType().FullName)($message,$_.Exception)
  199. Write-CustomError $exception $computerName $ScriptName
  200. return
  201. }
  202. $localUser = $null
  203. $localUserName = ""
  204. $dirEntries = $computer.Children
  205. if ( $AdminAccount ) {
  206. try {
  207. foreach ( $childObject in $dirEntries ) {
  208. if ( $childObject.Class -eq "User" ) {
  209. $childObjectSID = New-Object Security.Principal.SecurityIdentifier($childObject.objectSid[0],0)
  210. if ( $childObjectSID.Value.EndsWith("-500") ) {
  211. $localUser = $childObject
  212. break
  213. }
  214. }
  215. }
  216. }
  217. catch {
  218. $message = "Unable to connect to computer '$computerName' due to the following error: '{0}'" -f ($_.Exception.InnerException.Message -replace '\n+$', '')
  219. $exception = New-Object ($_.Exception.GetType().FullName)($message,$_.Exception)
  220. Write-CustomError $exception $computerName $ScriptName
  221. return
  222. }
  223. }
  224. else {
  225. try {
  226. $localUser = $dirEntries.Find($AccountName, "User")
  227. }
  228. catch [Management.Automation.MethodInvocationException] {
  229. $message = "Unable to perform operation `"$ProcessAction`" on target `"$computerName`" due to the following error: '{0}'" -f ($_.Exception.InnerException.Message -replace '\n+$', '')
  230. $exception = New-Object ($_.Exception.GetType().FullName)($message,$_.Exception)
  231. Write-CustomError $exception $computerName $ScriptName
  232. return
  233. }
  234. }
  235. $localUserName = $localUser.Name[0]
  236. try {
  237. $localUser.SetPassword((ConvertTo-String $Password))
  238. }
  239. catch [Management.Automation.MethodInvocationException] {
  240. $message = "Unable to perform operation `"$ProcessAction`" on target `"$computerName`" due to the following error: '{0}'" -f ($_.Exception.InnerException.Message -replace '\n+$', '')
  241. $exception = New-Object ($_.Exception.GetType().FullName)($message,$_.Exception.InnerException)
  242. Write-CustomError $exception $computerName $ScriptName
  243. }
  244. }
  245. }
  246. }
  247.  
  248. process {
  249. foreach ( $computerNameItem in $ComputerName ) {
  250. if ( $PSCmdlet.ShouldProcess($computerNameItem, $ProcessAction) ) {
  251. Reset-LocalAccountPassword $computerNameItem
  252. }
  253. }
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement