Powershell service account logon failure

I am trying to use a powershell script that allows me to change the user account and password in which a particular service runs.

$account="domain\account" $password="password" $svc=gwmi win32_service -filter "name='MyService'" $svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null) 

I could verify that the account was changed, but when I tried to start the service from the Service.msc GUI, it failed with a login failure.

If I use to start the service from the script itself, I get the following error.

 $svc.StartService() __GENUS : 2 __CLASS : __PARAMETERS __SUPERCLASS : __DYNASTY : __PARAMETERS __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : ReturnValue : 0 PSComputerName : __GENUS : 2 __CLASS : __PARAMETERS __SUPERCLASS : __DYNASTY : __PARAMETERS __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : ReturnValue : 15 PSComputerName : 

According to microsoft, this is an input error: The return value is 15.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa384901%28v=vs.85%29.aspx

I checked the password millions of times, and when I copy and paste the password using the GUI, it just works.

Maybe I missed something in my script. (SecurityPolicy on this computer is not limited)

+7
powershell
source share
6 answers

Not quite suitable for this topic, but may be useful for those who are looking for this type of script.

PowerShell script to scan the computer / server, find the service running under a specific account and stop the service, change the password and then start the service.

I used the ListServices.psm1 module, http://gallery.technet.microsoft.com/scriptcenter/How-to-Clear-Printing-21d59516 to facilitate the task. One quick note that took me a good 15 minutes to troubleshoot seems to be if you are trying to set a password with a dollar symbol ($) in it, insert it in “single quotes” rather than “double quotes”

 Import-Module "C:\Tools\ListServices.psm1" $pass = 'H:5Th7$!pc' $Username = "abcservice" $compName = gc env:computername $newpass = [ADSI]"WinNT://$compName/$Username,user" $newpass.SetPassword($pass) $newpass.SetInfo() Get-OSCServiceList -ComputerName "$compName" -UserName "$Username" | select Name | foreach { $_.Name} | Out-file -FilePath "C:\servicelist\service.txt" foreach ($name in (Get-Content -Path "C:\servicelist\service.txt")) { Write-Host "$name" Stop-Service "$name" Set-OSCServicePSW -ComputerName "$compName" -ServiceName $name -UserName ".\$Username" - NewPassWord $pass Start-Service "$name" } 

Hth is there someone.

+1
source share

If you just update the password for the service account and do not change which account starts this service, you might be lucky to just change the password. I had success with this call to Win32_Service.Change ():

 $service.Change($Null,$Null,$Null,$Null,$Null,$Null,$Null,$Password) 

This constantly worked for me to update passwords.

0
source share

Did you try to stop the service before changing the password?

The following works for me

 $account="domain\account" $password="password" $svc=gwmi win32_service -filter "name='MyService'" $svc.StopService(); $result = $svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null) if ($result.ReturnValue -eq '0') {write-host "Password changed"} else {write-host "Error: $result.ReturnValue"}; $svc.StartService(); 
0
source share

Before setting up a service account, you need to set the SeServiceLogonRight privilege.

 Set-Privileges $account "SeServiceLogonRight" $svc=gwmi win32_service -filter "name='MyService'" $svc.change($null,$null,$null,$null,$null,$false,$account,$password,$null,$null,$null) 

An example of a Set-Privileges function that uses LSA:

 function Set-Privileges { param( $username, $Privilege ) # C# code from http://www.codeproject.com/Articles/4863/LSA-Functions-Privileges-and-Impersonation $Source = @" using System; using System.Text; using System.Runtime.InteropServices; namespace Privileges { public class LsaUtility { // Import the LSA functions [DllImport("advapi32.dll", PreserveSig=true)] private static extern UInt32 LsaOpenPolicy( ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, Int32 DesiredAccess, out IntPtr PolicyHandle ); [DllImport("advapi32.dll", SetLastError=true, PreserveSig=true)] private static extern int LsaAddAccountRights( IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, int CountOfRights); [DllImport("advapi32")] public static extern void FreeSid(IntPtr pSid); [DllImport( "advapi32.dll", CharSet=CharSet.Auto, SetLastError=true, PreserveSig=true)] private static extern bool LookupAccountName( string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName, ref int cbdomainLength, ref int use ); [DllImport( "advapi32.dll")] private static extern bool IsValidSid(IntPtr pSid); [DllImport("advapi32.dll")] private static extern int LsaClose(IntPtr ObjectHandle); [DllImport("kernel32.dll")] private static extern int GetLastError(); [DllImport("advapi32.dll")] private static extern int LsaNtStatusToWinError(int status); // define the structures [StructLayout(LayoutKind.Sequential)] private struct LSA_UNICODE_STRING { public UInt16 Length; public UInt16 MaximumLength; public IntPtr Buffer; } [StructLayout(LayoutKind.Sequential)] private struct LSA_OBJECT_ATTRIBUTES{ public int Length; public IntPtr RootDirectory; public LSA_UNICODE_STRING ObjectName; public UInt32 Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService;} // enum all policies private enum LSA_AccessPolicy : long{ POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L, POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L, POLICY_GET_PRIVATE_INFORMATION = 0x00000004L, POLICY_TRUST_ADMIN = 0x00000008L, POLICY_CREATE_ACCOUNT = 0x00000010L, POLICY_CREATE_SECRET = 0x00000020L, POLICY_CREATE_PRIVILEGE = 0x00000040L, POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L, POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L, POLICY_AUDIT_LOG_ADMIN = 0x00000200L, POLICY_SERVER_ADMIN = 0x00000400L, POLICY_LOOKUP_NAMES = 0x00000800L, POLICY_NOTIFICATION = 0x00001000L } /// <summary>Adds a privilege to an account</summary> /// <param name="accountName">Name of an account - "domain\account" or only "account"</param> /// <param name="privilegeName">Name ofthe privilege</param> /// <returns>The windows error code returned by LsaAddAccountRights</returns> public static int SetRight(String accountName, String privilegeName){ int winErrorCode = 0; //contains the last error //pointer an size for the SID IntPtr sid = IntPtr.Zero; int sidSize = 0; //StringBuilder and size for the domain name StringBuilder domainName = new StringBuilder(); int nameSize = 0; //account-type variable for lookup int accountType = 0; //get required buffer size LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); //allocate buffers domainName = new StringBuilder(nameSize); sid = Marshal.AllocHGlobal(sidSize); //lookup the SID for the account bool result = LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); //say what you're doing for debug //Console.WriteLine("LookupAccountName result = "+result); //Console.WriteLine("IsValidSid: "+IsValidSid(sid)); //Console.WriteLine("LookupAccountName domainName: "+domainName.ToString()); if( ! result ){ winErrorCode = GetLastError(); Console.WriteLine("LookupAccountName failed: "+ winErrorCode); }else{ //initialize an empty unicode-string LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); //combine all policies int access = (int)( LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | LSA_AccessPolicy.POLICY_CREATE_ACCOUNT | LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE | LSA_AccessPolicy.POLICY_CREATE_SECRET | LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION | LSA_AccessPolicy.POLICY_LOOKUP_NAMES | LSA_AccessPolicy.POLICY_NOTIFICATION | LSA_AccessPolicy.POLICY_SERVER_ADMIN | LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS | LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS | LSA_AccessPolicy.POLICY_TRUST_ADMIN | LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION | LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION ); //initialize a pointer for the policy handle IntPtr policyHandle = IntPtr.Zero; //these attributes are not used, but LsaOpenPolicy wants them to exists LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); ObjectAttributes.Length = 0; ObjectAttributes.RootDirectory = IntPtr.Zero; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = IntPtr.Zero; ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; //get a policy handle int resultPolicy = (int)LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle); winErrorCode = LsaNtStatusToWinError(resultPolicy); if(winErrorCode != 0){ Console.WriteLine("OpenPolicy failed: "+ winErrorCode); }else{ //Now that we have the SID an the policy, //we can add rights to the account. //initialize an unicode-string for the privilege name LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1]; userRights[0] = new LSA_UNICODE_STRING(); userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName); userRights[0].Length = (UInt16)( privilegeName.Length * UnicodeEncoding.CharSize ); userRights[0].MaximumLength = (UInt16)( (privilegeName.Length+1) * UnicodeEncoding.CharSize ); //add the right to the account int res = LsaAddAccountRights(policyHandle, sid, userRights, 1); winErrorCode = LsaNtStatusToWinError(res); if(winErrorCode != 0){ Console.WriteLine("LsaAddAccountRights failed: "+ winErrorCode); }else{ Console.WriteLine("LsaAddAccountRights successful"); } LsaClose(policyHandle); } FreeSid(sid); } return winErrorCode; } } } "@ Add-Type -TypeDefinition $Source -Language CSharp [Privileges.LsaUtility]::SetRight($username, $Privilege) | Out-Null } 
0
source share

I suspect your password probably has at least one character that has special meaning in the interpolated string. Try a single quote:

 $password='password' 

In general, it's better to use single quotes by default and use double quotes when you specifically want to interpolate something.

BTW, also make sure that you are using the correct service name. You need to use the Name property, not DisplayName. Try gwmi win32_service -filter "name='MyService'" on the command line and make sure it does not return an error. This is probably a problem with single or double quoting.

-one
source share

I know that this problem was published several years ago, however, I ran into the same problem, with almost identical code, which led to an exact return. The installer that I use uses subinacl.exe to set permissions. The following article explains how to set these permissions: http://www.waynezim.com/2010/02/how-to-set-permission-on-a-service-using-subinacl/

I simply added “i” to the installation and added the user to the appropriate group (if applicable). Given the age of the article, I hope someone finds this helpful.

-one
source share

All Articles