locked
reset password user permission RRS feed

  • Question

  • Would it be possible to write a script that checks every user object in active directory and checks the security permission "reset password" to see if "everyone" has a tick against reset password for any user? Is that possible and if theres a script out there (couldnt find one) that does so could you send me a link?

    Thanks

    Wednesday, March 21, 2012 6:06 PM

Answers

  • I tested the script on a domain with 2300 users and it took maybe two minutes. When I was testing I used a filter for a few users, like Jaap suggested.


    Richard Mueller - MVP Directory Services

    • Marked as answer by cf090 Thursday, March 22, 2012 3:11 PM
    Thursday, March 22, 2012 11:15 AM

All replies

  • Would it be possible to write a script that checks every user object in active directory and checks the security permission "reset password" to see if "everyone" has a tick against reset password for any user? Is that possible and if theres a script out there (couldnt find one) that does so could you send me a link?

    Thanks

    You can use the dsmod tool to change every users change password flag.

    dsmod user * -mustchpwd yes

    Be careful as it will take effect immediately and there is no undoing it.


    ¯\_(ツ)_/¯

    Wednesday, March 21, 2012 7:52 PM
  • if what you're asking is related to AD ACLs/Permissions and ExtendedRights, where you want to see if the Everyone group has the Change Password extended right on all user objects, then you should be able to use the code below to accomplish what you want:

    import-module ac*
    (Get-ACL ("AD:\" + (Get-ADuser myusername | Select -ExpandProperty DistinguishedName))).Access | ? {($_.objectType -eq 'ab721a
    53-1e2f-11d0-9819-00aa0040529b') -and ($_.IdentityReference -eq "Everyone")}

    the 'AD' drive is created by importing the activedirectory module and the GUID you see in the where-clause is the GUID for the Change Password extended right.

    Edit:  in other words, you should be able to extrapolate from this code how to query all users and format your data as you please.
    Edit2:  Active Directory Extended Rights Reference


    • Edited by thepip3r Wednesday, March 21, 2012 9:09 PM
    Wednesday, March 21, 2012 9:04 PM
  • By experimenting, I found the GUID for the "reset password" permissioin is "{00299570-246D-11D0-A768-00AA006E0529}". Any ACL in the DACL of a user with objectType equal to this value grants the "reset password" permission to the trustee of the ACL.

    Searching for all users where some trustee has this permission will involve binding to three objects per user. This will be slow if there are many users. There is no way to query for this. You must enumerate all the ACL's in the DACL for every user. Also, this only finds individual trustees that have been granted this permission. It does not find the "Account Operators" or "Domain Admins" groups that have this permission. Here is a VBScript program that worked for me to find all trustees granted the "reset password" permission on the "Security" tab of user properties in ADUC:

    ' ResetPWRight.vbs
    Option Explicit

    Dim objUser, objACE, objDiscretionaryACL, objSecurityDescriptor
    Dim strDN, intCount, strOutput
    Dim objRootDSE, strDNSDomain, adoConnection, adoCommand, strQuery
    Dim adoRecordset, strBase, strFilter, strAttributes

    ' Determine DNS domain name from RootDSE object.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")

    ' Use ADO to search Active Directory for all users.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection

    ' Search entire domain.
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"

    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 200
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False

    Set adoRecordset = adoCommand.Execute

    ' Enumerate recordset.
    Do Until adoRecordset.EOF
        strDN = adoRecordset.Fields("distinguishedName").Value
        ' Escape any forward slash characters.
        strDN = Replace(strDN, "/", "\/")
        ' Bind to the object in Active Directory with the LDAP provider
        Set objUser = GetObject("LDAP://" & strDN)

        ' Bind to the security objects.
        Set objSecurityDescriptor = objUser.Get("ntSecurityDescriptor")
        Set objDiscretionaryACL = objSecurityDescriptor.discretionaryACL

        ' Enumerate each ACE in the DACL.
        intCount = 0
        strOutput = strDN & vbCrLf & "  Trustees that can reset this user's password:"
        For Each objACE In objDiscretionaryACL
            If (objACE.objectType = "{00299570-246D-11D0-A768-00AA006E0529}") Then
                strOutput = strOutput & vbCrLf & "    " & objACE.Trustee
                intCount = intCount + 1
            End If
        Next
        If (intCount > 0) Then
            Wscript.Echo strOutput
        End If
        adoRecordset.MoveNext
    Loop

    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    -----



    Richard Mueller - MVP Directory Services

    Wednesday, March 21, 2012 10:09 PM
  • Would it be possible to write a script that checks every user object in active directory and checks the security permission "reset password" to see if "everyone" has a tick against reset password for any user? Is that possible and if theres a script out there (couldnt find one) that does so could you send me a link?

    Thanks

    You can use the dsmod tool to change every users change password flag.

    dsmod user * -mustchpwd yes

    Be careful as it will take effect immediately and there is no undoing it.


    ¯\_(ツ)_/¯


    Can you confirm what this does. The permission I was concerned with is reset password not change password. I want to see which users have reset password to which accounts.
    Thursday, March 22, 2012 9:02 AM
  • By experimenting, I found the GUID for the "reset password" permissioin is "{00299570-246D-11D0-A768-00AA006E0529}". Any ACL in the DACL of a user with objectType equal to this value grants the "reset password" permission to the trustee of the ACL.

    Searching for all users where some trustee has this permission will involve binding to three objects per user. This will be slow if there are many users. There is no way to query for this. You must enumerate all the ACL's in the DACL for every user. Also, this only finds individual trustees that have been granted this permission. It does not find the "Account Operators" or "Domain Admins" groups that have this permission. Here is a VBScript program that worked for me to find all trustees granted the "reset password" permission on the "Security" tab of user properties in ADUC:

    ' ResetPWRight.vbs
    Option Explicit

    Dim objUser, objACE, objDiscretionaryACL, objSecurityDescriptor
    Dim strDN, intCount, strOutput
    Dim objRootDSE, strDNSDomain, adoConnection, adoCommand, strQuery
    Dim adoRecordset, strBase, strFilter, strAttributes

    ' Determine DNS domain name from RootDSE object.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")

    ' Use ADO to search Active Directory for all users.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection

    ' Search entire domain.
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"

    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 200
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False

    Set adoRecordset = adoCommand.Execute

    ' Enumerate recordset.
    Do Until adoRecordset.EOF
        strDN = adoRecordset.Fields("distinguishedName").Value
        ' Escape any forward slash characters.
        strDN = Replace(strDN, "/", "\/")
        ' Bind to the object in Active Directory with the LDAP provider
        Set objUser = GetObject("LDAP://" & strDN)

        ' Bind to the security objects.
        Set objSecurityDescriptor = objUser.Get("ntSecurityDescriptor")
        Set objDiscretionaryACL = objSecurityDescriptor.discretionaryACL

        ' Enumerate each ACE in the DACL.
        intCount = 0
        strOutput = strDN & vbCrLf & "  Trustees that can reset this user's password:"
        For Each objACE In objDiscretionaryACL
            If (objACE.objectType = "{00299570-246D-11D0-A768-00AA006E0529}") Then
                strOutput = strOutput & vbCrLf & "    " & objACE.Trustee
                intCount = intCount + 1
            End If
        Next
        If (intCount > 0) Then
            Wscript.Echo strOutput
        End If
        adoRecordset.MoveNext
    Loop

    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    -----



    Richard Mueller - MVP Directory Services


    I am not sure if I should risk it as per your comments as we have 2000 users? What do you think?
    Thursday, March 22, 2012 9:11 AM
  • You could also run this against a small subset of users first. For example running the command against a OU with only a limited amount of users or by limiting the results the query will return. This way you would be able to test how it runs. 

    Alternatively you could also change the query filter to only target a single user:

    strFilter = "(&(objectCategory=person)(objectClass=user)(displayname='Testuser1'))"

    Thursday, March 22, 2012 10:31 AM
  • I tested the script on a domain with 2300 users and it took maybe two minutes. When I was testing I used a filter for a few users, like Jaap suggested.


    Richard Mueller - MVP Directory Services

    • Marked as answer by cf090 Thursday, March 22, 2012 3:11 PM
    Thursday, March 22, 2012 11:15 AM