ive hit a roadblock. sometimes i get an "Insufficient memory to continue the execution of the program." when running a simple script to change a user's AD password using the ChangePassword method of the UserPrincipal class of the System.DirectoryServices.AccountManagement namespace in Powershell.
i cannot seem predict when it will occur. I know the following code in the script is the cause. Specifically, when i try to do the ChangePassword method on the $user object. the $user object is built fine every time.
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, $DomainServer, $Username, $OldPassword)
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, $Username)
$user.ChangePassword($OldPassword, $NewPassword)
the full error:
PSMessageDetails :
Exception : System.Management.Automation.MethodInvocationException: Exception calling "ChangePassword" with "2" argument(s): "Insufficient memory to continue the execution of
the program." ---> System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
at System.DirectoryServices.AccountManagement.SDSUtils.ChangePassword(DirectoryEntry de, String oldPassword, String newPassword)
at System.DirectoryServices.AccountManagement.ADStoreCtx.ChangePassword(AuthenticablePrincipal p, String oldPassword, String newPassword)
at CallSite.Target(Closure , CallSite , Object , String , String )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : OutOfMemoryException
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at Change-ADCredentials, <No file>: line 21
at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
The Context: the script would be running on a regular user's computer so no admin rights. windows 10 computers with 32 GB of RAM. These computers aredomain joined to Domain A but the script is for changing the password on Domain B. The computer running the script is never close to running out of memory. Ive tested on many machines and it seems to be something like 1 in 5 computers will get this. the computers are all imaged with the same stuff then of course vary over time with user customization. Take for example my own computer. sometimes i have had no issue with the script testing various password changes of test users and then another day i will get the error.
Here is a computer's memory usage when getting the error: screen grab
i know about other methods of changing passwords for example even in the same user principle class there is SetPassword method but you have to have certain rights for that and the regular users dont have it. There is the AD module cmdlet for changing password but that requires installing the AD module , a no go for my purposes. CTRL -ALT -Del change password wont work here because of the cross domain situation. Last but not least there is the netapi32.dll NetUserChangePassword function but it is old and not recommended. What im doing uses Kerberos.
Of course there is always RDP to a Domain B server and doing Ctrl - alt - End to change password for Domain B but i am trying to avoid that and focus on this.
I have tried:
- run the script as admin - no effect
- run that function/portion of the script as a job ( start-job -scriptblock {do thing} ) so as to spawn off a new powershell process of its own. but that didnt fix it either.
- i have rebooted the computer that gets the error, then try to run the script again right after reboot and still will receive the error. then sometime later boom it works.
- tried using: [System.GC]::Collect() and/or [System.GC]::GetTotalMemory($true) right before running that portion of the script. but still no.