zjorz / Public-AD-Scripts

AD Scripts
GNU General Public License v3.0
271 stars 76 forks source link

KrbTgt reset continues when ADCs are unreachable #19

Open Eribaer opened 8 months ago

Eribaer commented 8 months ago

Script recognizes DCs being unreachable in same domain. Script continues to reset ticket for reachable DCs instead of stopping. Is there an option for stopping yet? ! offline DC is not RODC!

Please understand that due to privacy reasons domain names were replaced with "xxx". The functionality of the output should still be clear.

Current input: .\Reset-KrbTgt-Password-For-RWDCs-And-RODCs.ps1 -noInfo -modeOfOperation "resetModeKrbTgtProdAccountsResetOnce" -targetedADforestFQDN "xxx" -targetedADDomainFQDN "xxx" -targetKrbTgtAccountScope "allRWDCs" -continueOps

Current output: [2024-03-11 11:30:10] : Local Computer Name...................: xxx [2024-03-11 11:30:10] : FQDN AD Domain Of Computer............: xxx [2024-03-11 11:30:10] : FQDN Computer In AD Domain............: xxx [2024-03-11 11:30:10] : FQDN Computer In DNS..................: xxx [2024-03-11 11:30:10] : FQDN DNS Domain Of Computer...........: xxx [2024-03-11 11:30:10] : Execution Mode........................: AUTOMATED [2024-03-11 11:30:10] : [2024-03-11 11:30:10] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:10] : CHECKING ELEVATION STATUS OF CURRENT PROCESS... [2024-03-11 11:30:10] : [2024-03-11 11:30:10] : Current Elevation Status...: ELEVATED [2024-03-11 11:30:10] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:10] : INFORMATION REGARDING KRBTGT ACCOUNTS AND PASSWORD RESETS... [2024-03-11 11:30:10] :

[2024-03-11 11:30:10] : [2024-03-11 11:30:10] : --> Chosen: NO [2024-03-11 11:30:10] : [2024-03-11 11:30:10] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:10] : LOADING REQUIRED POWERSHELL MODULES... [2024-03-11 11:30:10] : [2024-03-11 11:30:28] : PoSH Module 'GroupPolicy' Has Been Loaded... [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:28] : SELECT THE MODE OF OPERATION... [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : Which mode of operation do you want to execute? [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 1 - Informational Mode (No Changes At All) [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 2 - Simulation Mode Temporary Canary Object Created To Test Replication Convergence! [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 3 - Simulation Mode Use KrbTgt TEST/BOGUS Accounts - No Password Reset/WhatIf Mode! [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 4 - Real Reset Mode Use KrbTgt TEST/BOGUS Accounts - Password Will Be Reset Once! [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 5 - Simulation Mode Use KrbTgt PROD/REAL Accounts - No Password Reset/WhatIf Mode! [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 6 - Real Reset Mode Use KrbTgt PROD/REAL Accounts - Password Will Be Reset Once! [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 8 - Create TEST KrbTgt Accounts [2024-03-11 11:30:28] : - 9 - Cleanup TEST KrbTgt Accounts [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : - 0 - Exit Script [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : Please specify the mode of operation: 6 [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : --> Chosen Mode: Mode 6 - Real Reset Mode Use KrbTgt PROD/REAL Accounts - Password Will Be Reset Once!... [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:28] : SPECIFY THE TARGET AD FOREST... [2024-03-11 11:30:28] : [2024-03-11 11:30:28] : For the AD forest to be targeted, please provide the FQDN or press [ENTER] for the current AD forest: EriksUndDanielsSchnuckeligeDomain.de [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : --> Selected AD Forest: 'xxx'... [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : Checking Resolvability of the specified Local AD forest 'xxx' through DNS... [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : The specified Local AD forest 'xxx' is either resolvable through DNS or reachable through RootDse! [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : Continuing Script... [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : Checking Accessibility of the specified AD forest 'xxx' By Trying To Retrieve AD Forest Data... [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : The specified AD forest 'xxx' is accessible! [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : Continuing Script... [2024-03-11 11:30:29] : [2024-03-11 11:30:29] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:29] : SELECT THE TARGET AD DOMAIN... [2024-03-11 11:30:29] : [2024-03-11 11:30:31] : Forest Mode/Level...: Windows2016Forest [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : List Of AD Domains In AD Forest 'xxx'... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : ListNr Name NetBIOS DomainSID IsRootDomain DomainMode IsCurr entDom ain
 1   xxx                                  xxx                                  xxx                                             True   Windows2016    Domain             True

[2024-03-11 11:30:31] : --> Found [1] AD Domain(s) in the AD forest 'xxx'... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : For the AD domain to be targeted, please provide the list nr or the FQDN or press [ENTER] for the current AD domain: xxx [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : --> Selected AD Domain: 'xxx'... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : Checking existence of the specified AD domain 'xxx' in the AD forest 'xxx'... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : The specified AD domain 'xxx' exists in the AD forest 'xxx'! [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : Continuing Script... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:31] : TESTING IF REQUIRED PERMISSIONS ARE AVAILABLE (DOMAIN/ENTERPRISE ADMINS OR ADMINISTRATORS CREDENTIALS)... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : The user account 'xxx' is running with Domain Administrator equivalent permissions in the AD Domain 'xxx'!... [2024-03-11 11:30:31] : The user account 'x\Admin' is a member of 'x\Domain Admins'!... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : Continuing Script... [2024-03-11 11:30:31] : [2024-03-11 11:30:31] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:31] : GATHERING TARGETED AD DOMAIN INFORMATION... [2024-03-11 11:30:31] : [2024-03-11 11:30:41] : [2024-03-11 11:30:41] : Domain FQDN...........................: 'xxx' [2024-03-11 11:30:41] : Domain Functional Mode................: 'Windows2016Domain' [2024-03-11 11:30:41] : Domain Functional Mode Level..........: '7' [2024-03-11 11:30:41] : FQDN RWDC With PDC FSMO...............: 'xxx' [2024-03-11 11:30:41] : DSA RWDC With PDC FSMO................: 'CN=NTDS Settings,CN=x,CN=Servers,CN=First-Site,CN=Sites,CN=Configuration,DC=xxx,DC=x' [2024-03-11 11:30:41] : Max TGT Lifetime (Hours)..............: '10' [2024-03-11 11:30:41] : Max TGT Lifetime Sourced From.........: 'Default Domain Policy' [2024-03-11 11:30:41] : Max Clock Skew (Minutes)..............: '5' [2024-03-11 11:30:41] : Max Clock Skew Sourced From...........: 'Default Domain Policy' [2024-03-11 11:30:41] : [2024-03-11 11:30:41] : Checking Domain Functional Mode of targeted AD domain 'xxx' is high enough... [2024-03-11 11:30:41] : [2024-03-11 11:30:41] : The specified AD domain 'xxx' has a Domain Functional Mode of 'Windows2008Domain (3)' or higher!... [2024-03-11 11:30:41] : [2024-03-11 11:30:41] : Continuing Script... [2024-03-11 11:30:41] : [2024-03-11 11:30:41] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:41] : GATHERING DOMAIN CONTROLLER INFORMATION AND TESTING CONNECTIVITY... [2024-03-11 11:30:41] : [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : List Of Domain Controllers In AD Domain 'EriksUndDanielsSchnuckeligeDomain.de'... [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : Host Name PDC Site Name DS Type Krb Tgt Pwd Last Set Org RWDC Or g Ti me


xxx True First-Site Read/Write krbtgt 2024-03-05 13:56:05 xxx 20 xxx False First-Site Read/Write krbtgt 2024-03-05 13:56:05 xxx 20

[2024-03-11 11:30:44] : [2024-03-11 11:30:44] : REMARKS: [2024-03-11 11:30:44] : - 'N.A.' in the columns 'Source RWDC FQDN' and 'Source RWDC DSA' means the RWDC is considered as the master for this script. [2024-03-11 11:30:44] : - 'RODC Unreachable' in the columns 'Source RWDC FQDN' and 'Source RWDC DSA' means the RODC cannot be reached to determine its replicating source [2024-03-11 11:30:44] : RWDC/DSA. The unavailability can be due to firewalls/networking or the RODC actually being down. [2024-03-11 11:30:44] : - 'Unknown' in various columns means that an RODC was found that may not be a true Windows Server RODC. It may be an appliance acting as an RODC. [2024-03-11 11:30:44] : - 'RWDC Demoted' in the column 'Org RWDC' means the RWDC existed once, but it does not exist anymore as it has been decommissioned in the past. [2024-03-11 11:30:44] : This is normal. [2024-03-11 11:30:44] : - 'No Such Object' in the columns 'Pwd Last Set', 'Org RWDC', 'Org Time' or 'Ver' means the targeted object was not found in the AD domain. [2024-03-11 11:30:44] : Although this is possible for any targeted object, this is most likely the case when targeting the KrbTgt TEST/BOGUS accounts and if those [2024-03-11 11:30:44] : do not exist yet. This may also occur for an appliance acting as an RODC as in that case no KrbTgt TEST/BOGUS account is created. [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : --> Found [2] Real DC(s) In AD Domain... [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : --> Found [2] RWDC(s) In AD Domain... [2024-03-11 11:30:44] : --> Found [1] Reachable RWDC(s) In AD Domain... [2024-03-11 11:30:45] : --> Found [1] UnReachable RWDC(s) In AD Domain... [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : --> Found [0] RODC(s) In AD Domain... [2024-03-11 11:30:45] : --> Found [0] Reachable RODC(s) In AD Domain... [2024-03-11 11:30:45] : --> Found [0] UnReachable RODC(s) In AD Domain... [2024-03-11 11:30:45] : --> Found [0] Undetermined RODC(s) In AD Domain... [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:45] : SELECT THE SCOPE OF THE KRBTGT ACCOUNT(S) TO TARGET... [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : Which KrbTgt account do you want to target? [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : - 1 - Scope of KrbTgt in use by all RWDCs in the AD Domain [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : - 0 - Exit Script [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : Please specify the scope of KrbTgt Account to target: 1 [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : --> Chosen Scope KrbTgt Account Target: 1 - Scope of KrbTgt in use by all RWDCs in the AD Domain... [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : ------------------------------------------------------------------------------------------------------------------------------------------------------ [2024-03-11 11:30:45] : REAL RESET MODE (MODE 6) - RESETTING PASSWORD OF SCOPED PROD/REAL KRBTGT ACCOUNT(S) [2024-03-11 11:30:45] : SCOPE: 1 - Scope of KrbTgt in use by all RWDCs in the AD Domain... [2024-03-11 11:30:45] :

[2024-03-11 11:30:45] : [2024-03-11 11:30:45] : --> Chosen: CONTINUE [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : +++++ [2024-03-11 11:30:45] : +++ Processing KrbTgt Account....: 'krbtgt' 'CN=krbtgt,CN=Users,DC=xxx,DC=x' +++ [2024-03-11 11:30:45] : +++ Used By RWDC.................: 'All RWDCs' +++ [2024-03-11 11:30:45] : +++++ [2024-03-11 11:30:45] : [2024-03-11 11:30:45] : --> RWDC To Reset Password On.............: 'xxx' [2024-03-11 11:30:45] : --> sAMAccountName Of KrbTgt Account......: 'krbtgt' [2024-03-11 11:30:45] : --> Distinguished Name Of KrbTgt Account..: 'CN=krbtgt,CN=Users,DC=xxx,DC=x' [2024-03-11 11:30:45] : --> Number Of Chars For Pwd Generation....: '64' [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> Previous Password Set Date/Time.......: '2024-03-05 13:56:05' [2024-03-11 11:30:46] : --> New Password Set Date/Time............: '2024-03-11 11:30:46' [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> Previous Originating RWDC.............: 'xxx' [2024-03-11 11:30:46] : --> New Originating RWDC..................: 'xxx' [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> Previous Originating Time.............: '2024-03-05 13:56:05' [2024-03-11 11:30:46] : --> New Originating Time..................: '2024-03-11 11:30:46' [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> Previous Version Of Attribute Value...: '4' [2024-03-11 11:30:46] : --> New Version Of Attribute Value........: '5' [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> The new password for [CN=krbtgt,CN=Users,DC=xxx,DC=x] HAS BEEN SET on RWDC [xxx]!... [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : =================================================================== CHECK 1 =================================================================== [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : - Contacting DC in AD domain ...[xxx]...(SOURCE RWDC) [2024-03-11 11:30:46] : DC is Reachable... [2024-03-11 11:30:46] : The (new) password for Object [CN=krbtgt,CN=Users,DC=xxx,DC=x] exists in the AD database [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : - Contacting DC in AD domain ...[xxx]... [2024-03-11 11:30:46] : DC is NOT reachable... [2024-03-11 11:30:46] : Unable to connect to DC and check for Object [CN=krbtgt,CN=Users,DC=xxx,DC=x]... [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : --> Start Time......: 2024-03-11 11:30:46 [2024-03-11 11:30:46] : --> End Time........: 2024-03-11 11:30:46 [2024-03-11 11:30:46] : --> Duration........: 0.47 Seconds [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : List Of DCs In AD Domain 'EriksUndDanielsSchnuckeligeDomain.de' And Their Timing... [2024-03-11 11:30:46] : [2024-03-11 11:30:46] : Host Name PDC Site Name DS Type IP Address Reachable Source RWDC FQDN Time

xxx False First-Site Read/Write x False xxx xxx True First-Site Read/Write x True N.A. 0

Eribaer commented 8 months ago

@zjorz it would mean the world to me if you could have a little look :)

Eribaer commented 8 months ago

@zjorz this issue requires your attention ;)

zjorz commented 8 months ago

[2024-03-11 11:30:44] : --> Found [2] Real DC(s) In AD Domain... [2024-03-11 11:30:44] : [2024-03-11 11:30:44] : --> Found [2] RWDC(s) In AD Domain... [2024-03-11 11:30:44] : --> Found [1] Reachable RWDC(s) In AD Domain... [2024-03-11 11:30:45] : --> Found [1] UnReachable RWDC(s) In AD Domain...

you are resetting the KRBTGT account that is used by ALL RWDCs in an AD Domain. For multiple reasons (Dc is down, DC is not reachable due to routing or due to firewalls, etc etc) it is possible a RWDC is not reachable, and that is not necessarily a bad thing. if the reset if successful and other DCs are not available, then the script cannot check it had fully replicated and you will have to assume, AD replication will do the rest If the DC, against which you want to reset the pwd is not available, then the script will obviously abort. At a minimum the reset is needed and for the script to be able to check if the new password has reached all other DCs, is basically just a bonus.

Would you agree?

Eribaer commented 5 months ago

Im sorry i didnt answer earlier, i did not expect an answer and was very happy about it! :)

What im guessing is: On first runthrough, the script disregards unavailable (RW)DCs during PWD-Reset since there is still replication (after). On second runthrough the script checks (on the available (RW)DCs) if PWD-Reset was successful. If yes it continues. If not, it aborts. Script doesnt check successful PWD-Reset on offline (RW)DCs.

Is that right?

Eribaer commented 5 months ago

@zjorz it would be incredibly kind of you to confirm this :)

Eribaer commented 2 months ago

@zjorz come on - dont leave me like that :/

zjorz commented 2 months ago

This is not my daytime job. I get paid to do other stuff, then I also have a family, and whatever is left is spent on e.g. scripts like these and sleep. Working on three scripts in a specific order. Patience my friend, patience.

Eribaer commented 1 month ago

Patient since 4 months... ;)

albert-widjaja commented 1 month ago

@Eribaer ,

From what I can see, this function to test the port can also be enhanced with the Test-Connection to perform the simple ping test.

Function portConnectionCheck($fqdnServer, $port, $timeOut) {
    # Verify if the server is online using Test-Connection
    if (-not (Test-Connection -Count 2 -Quiet -ComputerName $fqdnServer)) {
        return "ERROR: Server is unreachable"
    }

    # Test to see if the hostname is resolvable
    try {
        [System.Net.Dns]::GetHostEntry($fqdnServer) | Out-Null
    } catch {
        return "ERROR: Hostname not resolvable"
    }

    # Check if the TCP port is open
    try {
        $tcpPortSocket = New-Object System.Net.Sockets.TcpClient
        $asyncResult = $tcpPortSocket.BeginConnect($fqdnServer, $port, $null, $null)
        if (-not $asyncResult.AsyncWaitHandle.WaitOne($timeOut, $false)) {
            $tcpPortSocket.Close()
            return "ERROR: Connection timed out"
        }

        $tcpPortSocket.EndConnect($asyncResult)
        $tcpPortSocket.Close()
        return "SUCCESS: Port $port is open"
    } catch {
        return "ERROR: Unable to connect to port $port"
    }
}

Hope this helps.

@zjorz let me know if my understanding of this function is correct.