PowerShell Constant Attention

# Time for loop to run
param($minutes = 920)

# Loop
$myshell = New-Object -com "Wscript.Shell"

for ($i = 0; $i -lt $minutes; $i++) {
    $myshell.sendkeys("{SCROLLLOCK}")
    Get-Date -Format "dddd MM/dd/yyyy HH:mm K" | Write-Host
    Start-Sleep -Milliseconds 100
    $myshell.sendkeys("{SCROLLLOCK}")
    Echo $i
    Start-Sleep -Seconds 60
}

DC GPO for the PCD to source NTP

hat should start with creating a WMI filter that will be used to ensure only the PDCe is allowed to sync from an external time source

1.   Right-click the WMI Filters folder and right-click New

2.  Give the new filter a meaningful name, for example PDCe DC Role Filte

3. Give the new filter a meaningful description such as “This filter will search for a computer with the PDCe FSMO Role [DomainRole 5]”

4. Create a new query by clicking Add

5. Leave the Namespace field at the default value of root\CIMv2

6. Enter the following text for the Query value: Select * from Win32_ComputerSystem where DomainRole = 5

Useful Microsoft Time Configuration References

• '0x01' = 'SpecialInterval'
• '0x02' = 'UseAsFallbackOnly'
• '0x03' = 'SpecialInterval+UseAsFallbackOnly'
• '0x04' = 'SymmetricActive'
• '0x05' = 'SpecialInterval+SymmetricActive'
• '0x06' = 'UseAsFallbackOnly+SymmetricActive'
• '0x07' = 'SpecialInterval+UseAsFallbackOnly+SymmetricActive'
• '0x08' = 'Client'
• '0x09' = 'SpecialInterval+Client'
• '0x0A' = 'UseAsFallbackOnly+Client'
• '0x0B' = 'SpecialInterval+UseAsFallbackOnly+Client'
• '0x0C' = 'SymmetricActive+Client'
• '0x0D' = 'SpecialInterval+SymmetricActive+Client'
• '0x0E' = 'UseAsFallbackOnly+SymmetricActive+Client'
• '0x0F' = 'SpecialInterval+UseAsFallbackOnly+SymmetricActive+Client'

The most useful:

• '0x1' = 'SpecialInterval'
Indicates to sync time with external server in SpecialPollInterval configured in “SpecialPollInterval” registry value.

• '0x2' = 'UseAsFallbackOnly'
Use this time source only as a fallback. If all time sources that are NOT fallbacks have failed, then the system selects one fallback time source at random and uses it. If primary is not available then sync to this server.

• '0x8' = 'Client'
Set the local computer to operate in client mode in the association with this source.
Use client mode association while sync time to external time source.

• '0x9' = 'SpecialInterval+Client'

PowerShell Query CISA Known Exploited Vulnerabilities

Function Get-CISAVulnerabilitiesReport {
<#
    .SYNOPSIS
        Get known exploited vulnerabilities

    .DESCRIPTION
        Get the known exploited vulnerabilities catalog from CISA

    .PARAMETER StartDate
        Datetime object used to filter the catalog

    .PARAMETER Last
        Last number of entries in the catalog sorted by published date

    .EXAMPLE
        Get-CISAVulnerabilitiesReport

        Get all the known exploited vulnerabilities from the catalog published by CISA

    .EXAMPLE
        Get-CISAVulnerabilitiesReport | Measure-Object

        Get the count of all the known exploited vulnerabilities published in the catalog by CISA

    .EXAMPLE
        Get-CISAVulnerabilitiesReport -Last 3

        Get the 3 most recent known exploited vulnerabilities from the catalog published by CISA
    .EXAMPLE
        Get-CISAVulnerabilitiesReport -StartDate (Get-Date).AddDays(-15)

        Get the known exploited vulnerabilities from the catalog published by CISA over the last 15 days
#>
[CmdletBinding(DefaultParameterSetName='__AllParameterSets')]
Param(
    [Parameter(ParameterSetName = 'ByDate')]
    [datetime]$StartDate,

    [Parameter(ParameterSetName = 'ByLast')]
    [int32]$Last
)
Begin {}
Process {
    $HT = @{
        URI = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json'
        ErrorAction = 'Stop'
        UseBasicParsing = [switch]::Present
    }
    try {
        $vuln = (Invoke-RestMethod @HT).vulnerabilities |
        ForEach-Object -Process {
            [PSCustomObject]@{
                CVEId = $_.cveID
                Vendor = $_.vendorProject
                ProductName = $_.product
                Name = $_.vulnerabilityName
                StartDate =  ([datetime]$_.dateAdded)
                Description = $_.shortDescription
                ActionRequired = $_.requiredAction
                DueDate = ([datetime]$_.dueDate)
            }
        }
    } catch {
        Write-Warning -Message "Failed to get data from CISA because $($_.Exception.Message)"
    }
    if ($vuln) {
        Switch ($PSCmdlet.ParameterSetName) {
            'ByDate' {
                $vuln | Where-Object { $_.StartDate -gt $StartDate }
                break
            }
            'ByLast' {
                $vuln | Sort-Object -Property StartDate -Descending | Select-Object -First $Last
                break
            }
            default {
                $vuln
            }
        }
    }
}
End {}
}

SQL Backup Database

Backup-SqlDatabase -ServerInstance SQL-01 -Database Whatever -BackupFile "C:\WhereEver\Backup\Test.bak" -Verbose

Find Source of AD Account Lockout

<#
.SYNOPSIS
    This function locates the computer that processed a failed user logon attempt which caused a user account to become locked out.

.DESCRIPTION
    This function will locate the computer that processed a failed user logon attempt which caused the user account to become locked out.
    The locked out location is found by querying the PDC Emulator for locked out events (4740).
    The function will display the BadPasswordTime attribute on all of the domain controllers to add in further troubleshooting.

.EXAMPLE
    PS C:\>Get-LockedOutLocation -Identity Jimmy.John


    This example will find the locked out location for Jimmy John.
.NOTE
-This function is only compatible with an environment where the domain controller with the PDC Emulator role is running Windows Server 2008 SP2 and higher.
-The script is dependent on the ActiveDirectory PowerShell module, which requires the AD Web services to be running on at least one domain controller.
    
Author: Brandon Lanczak
    
Last Modified: 10-08-2022 @ 21:00 CST
#>

Function Get-LockedOutLocation {

    [CmdletBinding()]

    Param(
      [Parameter(Mandatory=$True)]
      [String]$Identity
    )

    Begin {

        $DCCounter = 0
        $LockedOutStats = @()

        Try { Import-Module ActiveDirectory -ErrorAction Stop }

        Catch {

           Write-Warning $_
           Break
        }
    }

    Process {

        #Get all domain controllers in domain
        $DomainControllers = Get-ADDomainController -Filter *
        $PDCEmulator = $DomainControllers | Where-Object { $_.OperationMasterRoles -contains "PDCEmulator" }

        Write-Verbose "Finding the domain controllers in the domain"

        ForEach($DC in $DomainControllers) {

            $DCCounter++
            Write-Progress -Activity "Contacting DCs for lockout info" -Status "Querying $($DC.Hostname)" -PercentComplete (($DCCounter/$DomainControllers.Count) * 100)
            Try { $UserInfo = Get-ADUser -Identity $Identity  -Server $DC.Hostname -Properties AccountLockoutTime,LastBadPasswordAttempt,BadPwdCount,LockedOut -ErrorAction Stop }

            Catch {

                Write-Warning $_
                Continue
            }

            if ($UserInfo.LastBadPasswordAttempt) {

                $LockedOutStats += New-Object -TypeName PSObject -Property @{
                        Name                   = $UserInfo.SamAccountName
                        SID                    = $UserInfo.SID.Value
                        LockedOut              = $UserInfo.LockedOut
                        BadPwdCount            = $UserInfo.BadPwdCount
                        BadPasswordTime        = $UserInfo.BadPasswordTime
                        DomainController       = $DC.Hostname
                        AccountLockoutTime     = $UserInfo.AccountLockoutTime
                        LastBadPasswordAttempt = ($UserInfo.LastBadPasswordAttempt).ToLocalTime()
                }
            }
        }

        $LockedOutStats | Format-Table -Property Name,LockedOut,DomainController,BadPwdCount,AccountLockoutTime,LastBadPasswordAttempt -AutoSize

        #Get User Info
        Try {

           Write-Verbose "Querying event log on $($PDCEmulator.HostName)"
           $LockedOutEvents = Get-WinEvent -ComputerName $PDCEmulator.HostName -FilterHashtable @{LogName='Security';Id=4740} -ErrorAction Stop | Sort-Object -Property TimeCreated -Descending
        }

        Catch {

           Write-Warning $_
           Continue
        }

        ForEach ($Event in $LockedOutEvents) {

           if ($Event | Where {$_.Properties[2].value -match $UserInfo.SID.Value}) {

              $Event | Select-Object -Property @(
                @{Label = 'User';               Expression = {$_.Properties[0].Value}}
                @{Label = 'DomainController';   Expression = {$_.MachineName}}
                @{Label = 'EventId';            Expression = {$_.Id}}
                @{Label = 'LockedOutTimeStamp'; Expression = {$_.TimeCreated}}
                @{Label = 'Message';            Expression = {$_.Message -split "`r" | Select -First 1}}
                @{Label = 'LockedOutLocation';  Expression = {$_.Properties[1].Value}}
              )
          }
       }
    }
}