Share via


Cannot bind argument to parameter 'Password' because it is null.

Question

Thursday, February 11, 2016 2:33 PM

i am trying to reset the local administrator account password on remote machines via powershell.  I open powershell and type in the following command: Get-Content ComputerList.txt |   Reset-LocalAdminPassword.ps1 -Password $secureString

I pasted the Reset-LocalAdminPassword.ps1 script below.  However, i get the below message after running the command. anyone have any advice on how to resolve this error message so i can get the script to work.

Error message:

Cannot bind argument to parameter 'Password' because it is null.   At line:1 char: 73

Reset-LocalAdminPassword.ps1

<#
.SYNOPSIS
Resets the local Administrator password on one or more computers.

.DESCRIPTION
Resets the local Administrator password on one or more computers. The local Administrator account is determined by its RID (-500), not its name.

.PARAMETER ComputerName
Specifies one or more computer names. The default is the current computer.

.PARAMETER Password
Specifes the password to use for the local Administrator account. If you don't specify this parameter, you will be prompted to enter a password.
#>

[CmdletBinding(SupportsShouldProcess=$TRUE)]
param(
  [parameter(ValueFromPipeline=$TRUE)]
    $ComputerName=[System.Net.Dns]::GetHostName(),
  [parameter(Mandatory=$TRUE)]
    [System.Security.SecureString] $Password
)

begin {
  $ScriptName = $MyInvocation.MyCommand.Name
  $PipelineInput = (-not $PSBoundParameters.ContainsKey("ComputerName")) -and (-not $ComputerName)

  # Returns a SecureString as a String.
  function ConvertTo-String {
    param(
      [System.Security.SecureString] $secureString
    )
    $marshal = [System.Runtime.InteropServices.Marshal]
    try {
      $intPtr = $marshal::SecureStringToBSTR($secureString)
      $string = $marshal::PtrToStringAuto($intPtr)
    }
    finally {
      if ( $intPtr ) {
        $marshal::ZeroFreeBSTR($intPtr)
      }
    }
    $string
  }

  # Writes a custom error to the error stream.
  function Write-CustomError {
    param(
      [System.Exception] $exception,
      $targetObject,
      [String] $errorID,
      [System.Management.Automation.ErrorCategory] $errorCategory="NotSpecified"
    )
    $errorRecord = new-object System.Management.Automation.ErrorRecord($exception,
      $errorID,$errorCategory,$targetObject)
    $PSCmdlet.WriteError($errorRecord)
  }

  # Resets the local Administrator password on the specified computer.
  function Reset-LocalAdminPassword {
    param(
      [String] $computerName,
      [System.Security.SecureString] $password
    )
    $adsPath = "WinNT://$computerName,Computer"
    try {
      if ( -not [ADSI]::Exists($adsPath) ) {
        $message = "Cannot connect to the computer '$computerName' because it does not exist."
        $exception = [Management.Automation.ItemNotFoundException] $message
        Write-CustomError $exception $computerName $ScriptName ObjectNotFound
        return
      }
    }
    catch [System.Management.Automation.MethodInvocationException] {
      $message = "Cannot connect to the computer '$computerName' due to the following error: '$($_.Exception.InnerException.Message)'"
      $exception = new-object ($_.Exception.GetType().FullName)($message,$_.Exception.InnerException)
      Write-CustomError $exception $computerName $ScriptName
      return
    }
    $computer = [ADSI] $adsPath
    $localUser = $NULL
    $localUserName = ""
    foreach ( $childObject in $computer.Children ) {
      if ( $childObject.Class -ne "User" ) {
        continue
      }
      $childObjectSID = new-object System.Security.Principal.SecurityIdentifier($childObject.objectSid[0],0)
      if ( $childObjectSID.Value.EndsWith("-500") ) {
        $localUser = $childObject
        $localUserName = $childObject.Name[0]
        break
      }
    }
    if ( -not $PSCmdlet.ShouldProcess("'$computerName\localUserName'","Reset password") ) {
      return
    }
    try {
      $localUser.SetPassword((ConvertTo-String $password))
    }
    catch [System.Management.Automation.MethodInvocationException] {
      $message = "Cannot reset password for '$computerName\localUserName' due the following error: '$($_.Exception.InnerException.Message)'"
      $exception = new-object ($_.Exception.GetType().FullName)($message,$_.Exception.InnerException)
      Write-CustomError $exception "$computerName\user" $ScriptName
    }
  }
}

process {
  if ( $PipelineInput ) {
    Reset-LocalAdminPassword $_ $Password
  }
  else {
    $ComputerName | foreach-object {
      Reset-LocalAdminPassword $_ $Password
    }
  }
}

All replies (8)

Tuesday, February 16, 2016 6:37 AM ✅Answered

Hello,

As we can see in the description of the script:

PARAMETER Password
Specifes the password to use for the local Administrator account. If you don't specify this parameter, you will be prompted to enter a password.

As others suggestion, please define the variable $secureString before running the script.

Regards,

Yan Li

Please remember to mark the replies as answers if they help and unmark them if they provide no help. If you have feedback for TechNet Subscriber Support, contact [email protected].


Tuesday, February 16, 2016 7:19 AM ✅Answered

Best method of doing this is go with LAPS:

https://technet.microsoft.com/en-us/library/security/3062591.aspx

Regards, MC Manikandan


Thursday, February 11, 2016 2:50 PM

Hi Hulkster,

that's probably because you didn't put anything into the $secureString variable. A typo somewhere before?

Either way, it want's a valid Password object before the script itself does any work. Thus the script isn't necessarily wrong, it's a usage issue.

Cheers,
Fred

There's no place like 127.0.0.1


Thursday, February 11, 2016 2:53 PM

Hi Fred, Thanks for your quick response.  I am a powershell newbie so where exactly do I do that?


Thursday, February 11, 2016 3:08 PM | 4 votes

Hi,

The error occurs in line 97. You try to convert the secure string object to a string, but this does not work.

$localUser.SetPassword((ConvertTo-String $password))

What you can do, is pass a PSCredential object to the script:

$cred = Get-Credential

This way you have access to the plain text password via following command:

$cred.GetNetworkCredential().Password

Also, take a look at following resources:

Reset local admin password

Decrypt PowerShell Secure String Password

Wim Beck | IS4U FIM/MIM Expert Blog: blog.is4u.be

If you found my post helpful, please give it a Helpful vote. If it answered your question, remember to mark it as an Answer. Thank you!


Thursday, February 11, 2016 3:20 PM | 2 votes

Hi Hulkster,

that's probably because you didn't put anything into the $secureString variable. A typo somewhere before?

Either way, it want's a valid Password object before the script itself does any work. Thus the script isn't necessarily wrong, it's a usage issue.

Cheers,
Fred

There's no place like 127.0.0.1

I don't think it is a usage issue. Even if you pass a valid SecureString object to the script, it will not work because the SetPassword call is expecting a string.

Wim Beck | IS4U FIM/MIM Expert Blog: blog.is4u.be

If you found my post helpful, please give it a Helpful vote. If it answered your question, remember to mark it as an Answer. Thank you!


Thursday, February 11, 2016 3:25 PM

I don't think it is a usage issue. Even if you pass a valid SecureString object to the script, it will not work because the SetPassword call is expecting a string.

Wim Beck | IS4U FIM/MIM Expert Blog: blog.is4u.be

If you found my post helpful, please give it a Helpful vote. If it answered your question, remember to mark it as an Answer. Thank you!

Actually, the error thrown was thrown because the password is empty. The script may be right or wrong, but check out the line the error is thrown on - Line 1, char: 73, that's the calling line at the position of the Password Parameter.

There may be more than one thing wrong with the entire thing, but the initial error is definitely the call itself.

There's no place like 127.0.0.1


Thursday, February 11, 2016 3:28 PM

Hi Fred, Thanks for your quick response.  I am a powershell newbie so where exactly do I do that?

Welcome to the world of PowerShell :)

Try running this in your console before running this script:

$secureString = (Get-Credential).Password

Enter the password in the popup window, the name does not matter.

Cheers,
Fred

There's no place like 127.0.0.1