How to check if windows user has a password set?

2019-04-22 17:24发布

问题:

Question

I didn't know it would be this difficult to figure out but here I am.

I'm developing a net support client which has to detect if the current logged in user has a password set. I tried it with WMI checking the PasswordRequired property in the Win32_UserAccount class, but it returns false even if my account is password protected. I'm out of ideas...

(Background: I need this info to tell the user he has to set one so I can connect to him via remote desktop, which isn't very happy if the account is "unprotected". If there is a way to get around this I'd also accept a different solution.)

Sincerely yours
Nefarius

Solution

Easier than I thought, I managed it with the WinAPI function LogonUser and provide you this simple wrapper code:

    private bool PasswordRequired
    {
        get
        {
            IntPtr phToken;

            // http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html
            bool loggedIn = LogonUser(Environment.UserName,
                null,
                "",
                (int)LogonType.LOGON32_LOGON_INTERACTIVE,
                (int)LogonProvider.LOGON32_PROVIDER_DEFAULT,
                out phToken);

            int error = Marshal.GetLastWin32Error();

            if (phToken != IntPtr.Zero)
                // http://www.pinvoke.net/default.aspx/kernel32/CloseHandle.html
                CloseHandle(phToken);

            // 1327 = empty password
            if (loggedIn || error == 1327)
                return false;
            else
                return true;
        }
    }

That's exactly what I needed, thank you all for your fast and competent answers, I can always count on you! =)

回答1:

Why not just to try to LogonUser with empty password?



回答2:

Try to Change password with empty password, if succeed, that means user didn't set Password. Suppose domain user and Microsoft account always protected with password. For Microsoft account, it will throw PrincipalOperationException. For local user, if setted password, it will throw PasswordException. VB script reference, c# change password

        try
        {
            using (var context = new PrincipalContext(ContextType.Machine))
            {
                var user = UserPrincipal.FindByIdentity(context, userName);
                if (null == user)
                {
                    //not local user, password required
                    passwordRequired = true;
                }
                else
                {
                    user.ChangePassword("", "");
                }
            }
        }
        catch (PasswordException)
        {
            //local user password required
            passwordRequired = true;
        }
        catch (PrincipalOperationException)
        {
            //for Microsoft account, password required
            passwordRequired = true;
        }


回答3:

From what I can find, windows does not store a clear text version of the users password. Windows stores a copy that has been protected with one-way encryption. You can find more information about logging a user into windows in the MSDN documentation on LSALogonUser function. It does not help you get the users password



标签: c# wmi