Information provided by Microsoft explaining why this is important

-

The original script written by Jared Poeppelman, who works for Microsoft.

-

More information about THIS SCRIPT:

-

For any questions or feedback use the Q&A of the script AND send me an e-mail through the following link: Questions/Feedback

-

.SYNOPSIS
    This PoSH Script Resets The KrbTgt Password For RWDCs And RODCs In A Controlled Manner

.VERSION
    v2.5, 2020-02-17 (UPDATE THE VERSION VARIABLE BELOW)
    
.AUTHOR
    Initial Script/Thoughts.......: Jared Poeppelman, Microsoft
    Script Re-Written/Enhanced....: Jorge de Almeida Pinto [MVP Enterprise Mobility And Security, EMS]
    Blog..........................: Blog: http://jorgequestforknowledge.wordpress.com/
    For Feedback/Questions........: scripts.gallery@iamtec.eu ("mailto:Jorge's Script Gallery <scripts.gallery@iamtec.eu>?subject=[Script Gallery Feedback:] 'REPLACE-THIS-PART-WITH-SOMETHING-MEANINGFULL'")

.DESCRIPTION
    This PoSH script provides the following functions:
    - Single Password Reset for the KrbTgt account in use by RWDCs in a specific AD domain, using either TEST or PROD KrbTgt accounts
    - Single Password Reset for the KrbTgt account in use by an individual RODC in a specific AD domain, using either TEST or PROD KrbTgt accounts
        * A single RODC in a specific AD domain
        * A specific list of RODCs in a specific AD domain
        * All RODCs in a specific AD domain
    - Resetting the password/keys of the KrbTgt Account can be done for multiple reasons such as for example:
        * From a security perspective as mentioned in https://cloudblogs.microsoft.com/microsoftsecure/2015/02/11/krbtgt-account-password-reset-scripts-now-available-for-customers/
        * From an AD recovery perspective as mentioned in https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/ad-forest-recovery-resetting-the-krbtgt-password
    - For all scenarios, an informational mode, which is mode 1 with no changes
    - For all scenarios, a simulation mode, which is mode 2 where replication is tested through the replication of a temporary canary
        object that is created and deleted afterwards. No Password Resets involved here as the temporary canary object is a contact object
    - For all scenarios, a simulation mode, which is mode 3 where the password reset of the chosen TEST KrbTgt account is actually executed
        and replication of it is monitored through the environment for its duration. Can be scoped for RWDCs and RODCs (single, multiple, all)
    - For all scenarios, a real reset mode, which is mode 4 where the password reset of the chosen PROD KrbTgt account is actually executed
        and replication of it is monitored through the environment for its duration
    - The creation of Test KrbTgt Accounts, which is mode 8
    - The deletion of Test KrbTgt Accounts, which is mode 9
    
    Behavior:
    - In mode 1 you will always get a list of all RWDCs, and alls RODCs if applicable, in the targeted AD domain that are available/reachable
        or not
    - In mode 2 it will create the temporary canary object and, depending on the scope, it will check if it exists in the AD database of the
        remote DC(s) (RWDC/RODC)
    - In mode 3, depending on the scope, it uses TEST/BOGUS krbtgt account(s) to reset the password on an originating RWDC. After that it
        checks if pwdLastSet attribute value of the targeted TEST/BOGUS krbtgt account(s) on the remote DC(s) (RWDC/RODC) matches the
        pwdLastSet attribute value of the same TEST/BOGUS krbtgt account on the originating RWDC
        * For RWDCs it uses the TEST/BOGUS krbtgt account "krbtgt_TEST" (All RWDCs) (= Created when running mode 8)
        * For RODCs it uses the TEST/BOGUS krbtgt account "krbtgt_<Numeric Value>_TEST" (RODC Specific) (= Created when running mode 8)
    - In mode 4, depending on the scope, it uses PROD/REAL krbtgt account(s) to reset the password on an originating RWDC. After that it
        checks if pwdLastSet attribute value of the targeted PROD/REAL krbtgt account(s) on the remote DC(s) (RWDC/RODC) matches the pwdLastSet
        attribute value of the same PROD/REAL krbtgt account on the originating RWDC
        * For RWDCs it uses the PROD/REAL krbtgt account "krbtgt" (All RWDCs)
        * For RODCs it uses the PROD/REAL krbtgt account "krbtgt_<Numeric Value>" (RODC Specific)
    - In mode 8, for RWDCs it creates (in disabled state!) the TEST/BOGUS krbtgt account "krbtgt_TEST" and adds it to the AD group
        "Denied RODC Password Replication Group". If any RODC exists in the targeted AD domain, it reads the attribute "msDS-KrbTgtLink" of
        each RODC computer account to determine the RODC specific krbtgt account and creates (in disabled state!) the TEST/BOGUS krbtgt
        account "krbtgt_<Numeric Value>_TEST" and adds it to the AD group "Allowed RODC Password Replication Group"
    - In mode 9, for RWDCs it deletes the TEST/BOGUS krbtgt account "krbtgt_TEST" if it exists. If any RODC exists in the targeted AD domain,
        it reads the attribute "msDS-KrbTgtLink" of each RODC computer account to determine the RODC specific krbtgt account and deletes the
        TEST/BOGUS krbtgt account "krbtgt_<Numeric Value>_TEST" if it exists.
    - In mode 2, 3 or 4, if a remote DC (RWDC/RODC) is not available or cannot be reached, there will not be a check against its AD database
        to determine if the change made reached it or not.
    - In mode 2 when performing the "replicate single object" operation, it will always be for the full object, no matter if the remote DC
        is an RWDC or an RODC
    - In mode 3 or 4 when performing the "replicate single object" operation, it will always be for the full object, if the remote DC is an
        RWDC. If the remote DC is an RODC it will always be for the partial object and more specifically "secrets only"
    - When targeting the krbtgt account (TEST/BOGUS or PROD/REAL) in use by all the RWDCs, the originating RWDC is the RWDC with the PDC FSMO
        and all other available/reachable RWDCs will be checked against to see if the change has reached them. No RODCs are involved as those
        do not use the krbtg account in use by the RWDCs and also do not store/cache its password.
    - When targeting the krbtgt account (TEST/BOGUS or PROD/REAL) in use by an RODC, the originating RWDC is the direct replication RWDC if
        available/reachable and when not available the RWDC with the PDC FSMO is used as the originating RWDC. Only the RODC that uses the
        specific krbtgt account is checked against to see if the change has reached them, but only if the RODCs is available/reachable
    - If the operating system attribute of an RODC computer account does not have a value, it is determined to be unknown (not a real RODC),
        and therefore something else. It could for example be a Riverbed appliance in "RODC mode".
    - The only DC that knows what the real replication partner is of an RODC, is the RODC itself. Only the RODC manages a connection object
        that only exists in the AD database of the RODC and does not replicate out to other DCs as RODCs do not support outbound replication.
        Therefore, assuming the RODC is available, the CO is looked up in the RODC AD database and from that CO, the "source" server is
        determined. In case the RODC is not available or its "source" server is not available, the RWDC with the PDC FSMO is used to reset
        the password of the krbtgt account in use by that RODC. If the RODC is available a check will be done against its database, and if
        not available the check is skipped

.TODO
    - Work out the sections that contain '#XXX'
    - Cleanup commented code as it is not used anymore - for next update to occur

.KNOWN ISSUES/BUGS
    - When targeting a remote AD forest for which no trust exist with the AD forest the running account belongs to, the public profile of WinRM may be
        used. In that case the PSSession for 'Get-GPOReport' may fail due to the default firewall exception only allowing access from remote computers
        on the same local subnet. In that case the default 'MaxTicketAge' (default 10 hours) and 'MaxClockSkew' (default 5 minutes) is used instead.
        You may see the following error:
        [<FQDN TARGET DC>] Connecting to remote server <FQDN TARGET DC> failed with the following error message : WinRM cannot complete the operation.
        Verify that the specified computer name is valid, that the computer is accessible over the network, and that a firewall exception for the WinRM
        service is enabled and allows access from this computer. By default, the WinRM firewall exception for public profiles limits access to remote
        computers within the same local subnet. For more information, see the about_Remote_Troubleshooting Help topic.
        + CategoryInfo          : OpenError: (<FQDN TARGET DC>:String) [], PSRemotingTransportException
        + FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
    - Although this script can be used in an environment with Windows Server 2000/2003 RWDCs, it is NOT supported to do this. Windows Server
        2000/2003 RWDCs cannot do KDC PAC validation using the previous (N-1) krbtgt password. Those RWDCs only attempt that with the current
        (N) password. That means that in the subset of KRB AP exchanges where KDC PAC validation is performed, authentication issues could be
        experienced because the target server gets a PAC validation error when asking the KDC (domain controller) to validate the KDC signature
        of the PAC that is inside the service ticket that was presented by the client to the server. This problem would potentially persist
        for the lifetime of the service ticket(s). It is also highly recommended NOT to use products that have reached their end support.
        Please upgrade as soon as possible.
    - This is not related to this script. When increasing the DFL from Windows Server 2003 to any higher level, the password of the KrbTgt
        Account will be reset automatically due to the introduction of AES encryption for Kerberos and the requirement to regenerate new keys
        for DES, RC4, AES128, AES256!

.RELEASE NOTES
    v2.5, 2020-02-17, Jorge de Almeida Pinto [MVP-EMS]:
        - To improve performance, for some actions the nearest RWDC is discovered instead of using the RWDC with the PDC FSMO Role
        
    v2.4, 2020-02-10, Jorge de Almeida Pinto [MVP-EMS]:
        - Checked script with Visual Studio Code and fixed all "problems" identified by Visual Studio Code
            - Variable "$remoteCredsUsed" is ignored by me, as the problem is due to the part 'Creds' in the variable name 
            - Variable "$adminCreds" is ignored by me, as the problem is due to the part 'Creds' in the variable name
        - Bug Fix: Fixed language specific issue with the groups 'Allowed RODC Password Replication Group' and 'Denied RODC Password Replication Group'
        - Added support to execute this script against a remote AD forest, either with or without a trust

    v2.3, 2019-02-25, Jorge de Almeida Pinto [MVP-EMS]:
        - Bug Fix: Removed the language specific error checking. Has been replaced with another check. This solution also resolved another
            issue when checking if a (RW/RO)DC was available or not

    v2.2, 2019-02-12, Jorge de Almeida Pinto [MVP-EMS]:
        - Bug Fix: Instead of searching for "Domain Admins" or "Enterprise Admins" membership, it resolves the default RIDs of those groups,
            combined with the corresponding domain SID, to the actual name of those domain groups. This helps in supporting non-english names
            of those domain groups
        
    v2.1, 2019-02-11, Jorge de Almeida Pinto [MVP-EMS]:
        - New Feature: Read and display metadata of the KrbTgt accounts before and after to assure it was only updated once!
        - Bug Fix: Added a try catch when enumerating details about a specific AD domain that appears not to be available
            
    v2.0, 2018-12-30, Jorge de Almeida Pinto [MVP-EMS]:
        - Renamed script to Reset-KrbTgt-Password-For-RWDCs-And-RODCs.ps1
        - Full rewrite and major release
        - Added possibility to also reset KrbTgt account in use by RODCs
        - Added possibility to try this procedure using a temp canary object (contact object)
        - Added possibility to try this procedure using a TEST krbtgt accounts and perform password reset on those TEST krbtgt accounts
        - Added possibility to create TEST krbtgt accounts if required
        - Added possibility to delete TEST krbtgt accounts if required
        - Check if an RODC account is indeed in use by a Windows RODC and not something simulating an RODC (e.g. Riverbed)
        - Removed dependency for REPADMIN.EXE
        - Removed dependency for RPCPING.EXE
        - Extensive logging to both screen and file
        - Added more checks, such as permissions check, etc.

    v1.7, Jared Poeppelman, Microsoft
       - Modified rpcping.exe call to use "-u 9 -a connect" parameters to accomodate tighter RPC security settings as specified in
            DISA STIG ID: 5.124 Rule ID: SV-32395r1_rule , Vuln ID: V-14254 (thanks Adam Haynes)

    v1.6, Jared Poeppelman, Microsoft
        - Removed 'finally' block of Get-GPOReport error handling (not a bug, just not needed)
                
    v1.5, Jared Poeppelman, Microsoft
        - Renamed script to New-CtmADKrbtgtKeys.ps1
        - Added logic for GroupPolicy Powershell module dependency
        - Fixed bug of attempting PDC to PDC replication
        - Replaced function for password generation
        - Renamed functions to use appropriate Powershell verbs 
        - Added error handling around Get-GpoReport for looking up MaxTicketAge and MaxClockSkew

    v1.4, Jared Poeppelman, Microsoft
        - First version published on TechNet Script Gallery

.NOTES
    - To execute this script, the account running the script MUST be a member of the "Domain Admins" or Administrators group in the
        targeted AD domain.
    - If the account used is from another AD domain in the same AD forest, then the account running the script MUST be a member of the
        "Enterprise Admins" group in the AD forest or Administrators group in the targeted AD domain. For all AD domains in the same
        AD forest, membership of the "Enterprise Admins" group is easier as by default it is a member of the Administrators group in
        every AD domain in the AD forest
    - If the account used is from another AD domain in another AD forest, then the account running the script MUST be a member of the
        "Administrators" group in the targeted AD domain. This also applies to any other target AD domain in that same AD forest
    - This is due to the reset of the password for the targeted KrbTgt account(s) and forcing (single object) replication between DCs
    - Testing "Domain Admins" membership is done through "IsInRole" method as the group is domain specific
    - Testing "Enterprise Admins" membership is done through "IsInRole" method as the group is forest specific
    - Testing "Administrators" membership cannot be done through "IsInRole" method as the group exist in every AD domain with the same
        SID. To still test for required permissions in that case, the value of the Description attribute of the KRBTGT account is copied
        into the DisplayName attribute and cleared afterwards. If both those actions succeed it is proven the required permissions are
        in place!