Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc91f0d6b0 | |||
| 6b2ae6c8b5 | |||
| 37d1a8d971 | |||
| 0175864e72 | |||
| 9496063b97 | |||
| 27a682a968 | |||
| 255cfe0a17 |
@@ -0,0 +1,161 @@
|
||||
##################################################
|
||||
## ____ ___ ____ _____ _ _ _____ _____ ##
|
||||
## / ___/ _ \| _ \| ____| | \ | | ____|_ _| ##
|
||||
## | | | | | | |_) | _| | \| | _| | | ##
|
||||
## | |__| |_| | _ <| |___ _| |\ | |___ | | ##
|
||||
## \____\__\_\_| \_\_____(_)_| \_|_____| |_| ##
|
||||
## Move fast and fix things. ##
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Bump-Version.ps1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
#Requires -Version 5.1
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Bumps the unified Elysium version across all project files.
|
||||
|
||||
.DESCRIPTION
|
||||
Updates the centralized $ElysiumVersion variable, ASCII headers in all
|
||||
operational scripts, the settings template, and runtime references
|
||||
(User-Agent, usage beacon, etc.). Optionally stubs a new CHANGELOG entry.
|
||||
|
||||
.PARAMETER NewVersion
|
||||
The new version string to apply (e.g. 2.2.2).
|
||||
|
||||
.PARAMETER SkipChangelog
|
||||
Do not print a CHANGELOG entry stub.
|
||||
|
||||
.EXAMPLE
|
||||
.\Bump-Version.ps1 -NewVersion 2.2.2
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$NewVersion,
|
||||
|
||||
[switch]$SkipChangelog
|
||||
)
|
||||
|
||||
$scriptRoot = $PSScriptRoot
|
||||
if (-not $scriptRoot) { $scriptRoot = (Get-Location).Path }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Validate input
|
||||
# ---------------------------------------------------------------------------
|
||||
if ($NewVersion -notmatch '^\d+\.\d+\.\d+$') {
|
||||
throw "Version must be in semantic format X.Y.Z (e.g. 2.2.2). Got: '$NewVersion'"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Determine current version from Elysium.Common.ps1
|
||||
# ---------------------------------------------------------------------------
|
||||
$commonPath = Join-Path -Path $scriptRoot -ChildPath 'Elysium.Common.ps1'
|
||||
if (-not (Test-Path -LiteralPath $commonPath)) {
|
||||
throw "Elysium.Common.ps1 not found at $commonPath"
|
||||
}
|
||||
|
||||
$commonContent = Get-Content -LiteralPath $commonPath -Raw
|
||||
$currentVersionMatch = [regex]::Match($commonContent, "\`$script:ElysiumVersion\s*=\s*'([^']+)'")
|
||||
if (-not $currentVersionMatch.Success) {
|
||||
throw "Could not determine current version from Elysium.Common.ps1"
|
||||
}
|
||||
$oldVersion = $currentVersionMatch.Groups[1].Value
|
||||
|
||||
if ($oldVersion -eq $NewVersion) {
|
||||
Write-Warning "Current version is already $NewVersion. Nothing to do."
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Bumping Elysium from $oldVersion -> $NewVersion"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helper: replace in file
|
||||
# ---------------------------------------------------------------------------
|
||||
function Edit-FileVersion {
|
||||
param(
|
||||
[string]$Path,
|
||||
[string]$Old,
|
||||
[string]$New
|
||||
)
|
||||
$content = Get-Content -LiteralPath $Path -Raw
|
||||
$newContent = $content.Replace($Old, $New)
|
||||
if ($newContent -eq $content) {
|
||||
Write-Verbose " No changes in $(Split-Path -Leaf $Path)"
|
||||
} else {
|
||||
Set-Content -LiteralPath $Path -Value $newContent -NoNewline -Encoding UTF8
|
||||
Write-Host " Updated $(Split-Path -Leaf $Path)"
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 1. Central version variable
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Host "`n[1/4] Updating centralized version variable..."
|
||||
Edit-FileVersion -Path $commonPath -Old "`$script:ElysiumVersion = '$oldVersion'" -New "`$script:ElysiumVersion = '$NewVersion'"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 2. ASCII headers in scripts and templates
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Host "`n[2/4] Updating script headers..."
|
||||
$headerTargets = Get-ChildItem -Path $scriptRoot -File | Where-Object {
|
||||
$_.Extension -in @('.ps1', '.py') -or $_.Name -eq 'ElysiumSettings.txt.sample'
|
||||
}
|
||||
foreach ($file in $headerTargets) {
|
||||
$content = Get-Content -LiteralPath $file.FullName -Raw
|
||||
# The header pattern: ## Version: X.Y.Z ##
|
||||
$pattern = "## Version:\s+$([regex]::Escape($oldVersion))\s+##"
|
||||
$replacement = "## Version: $NewVersion ##"
|
||||
$newContent = [regex]::Replace($content, $pattern, $replacement)
|
||||
if ($newContent -ne $content) {
|
||||
Set-Content -LiteralPath $file.FullName -Value $newContent -NoNewline -Encoding UTF8
|
||||
Write-Host " Updated $($file.Name)"
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. Runtime references (safety net)
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Host "`n[3/4] Updating runtime version references..."
|
||||
$runtimeTargets = Get-ChildItem -Path $scriptRoot -Filter '*.ps1' -File
|
||||
foreach ($file in $runtimeTargets) {
|
||||
$content = Get-Content -LiteralPath $file.FullName -Raw
|
||||
$newContent = $content
|
||||
# User-Agent patterns: 'Elysium/2.2.1 (+...)' or "Elysium/2.2.1 (+...)"
|
||||
$newContent = [regex]::Replace($newContent,
|
||||
"Elysium/$([regex]::Escape($oldVersion))",
|
||||
"Elysium/$NewVersion")
|
||||
# Literal string assignments: version = '2.2.1'
|
||||
$newContent = [regex]::Replace($newContent,
|
||||
"version\s*=\s*'$([regex]::Escape($oldVersion))'",
|
||||
"version = '$NewVersion'")
|
||||
if ($newContent -ne $content) {
|
||||
Set-Content -LiteralPath $file.FullName -Value $newContent -NoNewline -Encoding UTF8
|
||||
Write-Host " Updated runtime refs in $($file.Name)"
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 4. CHANGELOG stub
|
||||
# ---------------------------------------------------------------------------
|
||||
if (-not $SkipChangelog) {
|
||||
Write-Host "`n[4/4] CHANGELOG entry stub (copy-paste ready):"
|
||||
$today = (Get-Date).ToString('yyyy-MM-dd')
|
||||
$stub = @"
|
||||
|
||||
---
|
||||
|
||||
## [$NewVersion] — $today
|
||||
|
||||
### Changed
|
||||
- (describe your change here)
|
||||
"@
|
||||
Write-Host $stub
|
||||
Write-Host "`nAppend the above to CHANGELOG.md, then commit and tag."
|
||||
}
|
||||
|
||||
Write-Host "`nDone. Review the changes with: git diff --stat"
|
||||
@@ -6,6 +6,58 @@ Starting with **v2.2.0**, Elysium uses a **unified project version**. All script
|
||||
|
||||
---
|
||||
|
||||
## [2.4.0] — 2026-06-09
|
||||
|
||||
### Added
|
||||
- **DC clock skew pre-flight check** (`Test-DCClockSkew` in `Elysium.Common.ps1`): compares the local machine clock against the target DC's `RootDSE.currentTime` before attempting DCSync. Warns if skew exceeds 300s (Kerberos hard limit) or 60s (approaching limit), and provides the `w32tm /resync /force` remediation command.
|
||||
- **SDProp protection warning** in `Test-ReplicationPermissions`: detects `adminCount=1` on the service account and warns that SDProp runs every 60 minutes and may silently revert replication rights or group memberships.
|
||||
- **Protected Users group warning** in `Test-ReplicationPermissions`: detects membership in the Protected Users group (RID 525) and warns that it restricts Kerberos delegation and RC4 authentication required by DSInternals for DRS replication.
|
||||
|
||||
### Fixed
|
||||
- DSInternals auto-update flow now uses `Install-Module -Force -AllowClobber` instead of `Update-Module` to avoid a PowerShellGet bug where null `PublishedDate` metadata causes "cannot convert null to type system.datetime".
|
||||
|
||||
---
|
||||
|
||||
## [2.3.0] — 2026-06-09
|
||||
|
||||
### Added
|
||||
- `Test-WeakADPasswords.ps1` now checks the installed DSInternals version at startup:
|
||||
- **v6.2** (unsigned) is flagged with a warning explaining that unsigned native DLLs are blocked and replication will fail. Remediation: `Update-Module DSInternals`.
|
||||
- **Below v7.0** triggers an interactive prompt offering to run `Update-Module DSInternals -Force` automatically. If accepted, the script updates the module and exits cleanly so the operator can re-run with the new version loaded.
|
||||
- v7.0+ is required because it fixes intermittent CRC errors mid-replication and `Test-PasswordQuality` result truncation bugs.
|
||||
|
||||
---
|
||||
|
||||
## [2.2.5] — 2026-06-09
|
||||
|
||||
### Fixed
|
||||
- The DSInternals `Zone.Identifier` block error message (added in v2.2.4) now dynamically resolves the actual DSInternals module path via `Get-Module` instead of hardcoding `$env:ProgramFiles\WindowsPowerShell\DSInternals`. The `Unblock-File` command in the error now points to the correct installation directory.
|
||||
|
||||
---
|
||||
|
||||
## [2.2.4] — 2026-06-09
|
||||
|
||||
### Fixed
|
||||
- `Test-ReplicationPermissions` (in `Elysium.Common.ps1`) now skips `InheritOnly` ACEs when evaluating replication rights. An ACE marked `InheritOnly` applies only to child objects, not the domain root itself, so it does not grant the required extended rights for DCSync on the domain object.
|
||||
- `Import-CompatModule` (in `Test-WeakADPasswords.ps1`) now detects DSInternals being blocked by Windows `Zone.Identifier` (alternate data stream from internet download) and throws a clear, actionable error with the exact `Unblock-File` command to run. Previously this surfaced as an opaque non-FIPS warning.
|
||||
|
||||
---
|
||||
|
||||
## [2.2.3] — 2026-06-09
|
||||
|
||||
### Fixed
|
||||
- `Test-ReplicationPermissions` (in `Elysium.Common.ps1`) now correctly recognizes `GenericAll` and blanket `ExtendedRight` (empty ObjectType) ACEs as satisfying replication permission requirements. Previously, only exact GUID-matched ExtendedRight ACEs were detected, causing false negatives when rights were granted via broader permissions.
|
||||
- Improved error diagnostics: the missing-rights message now indicates whether an ACE for the specific right exists on the domain object but is not assigned to the caller, versus no ACE existing at all.
|
||||
|
||||
---
|
||||
|
||||
## [2.2.2] — 2026-06-09
|
||||
|
||||
### Fixed
|
||||
- `Test-ReplicationPermissions` (in `Elysium.Common.ps1`) now resolves the caller's **effective token SIDs** via the `tokenGroups` constructed attribute instead of walking `MemberOf` directly. This correctly accounts for nested group memberships and avoids false-positive "missing permissions" errors when the account is entitled through nested groups.
|
||||
|
||||
---
|
||||
|
||||
## [2.2.1] — 2026-06-09
|
||||
|
||||
### Changed
|
||||
|
||||
+80
-13
@@ -1,3 +1,5 @@
|
||||
$script:ElysiumVersion = '2.4.0'
|
||||
|
||||
function Invoke-RestartWithExecutable {
|
||||
param(
|
||||
[string]$ExecutablePath,
|
||||
@@ -336,14 +338,33 @@ function Test-ReplicationPermissions {
|
||||
try {
|
||||
$samName = $Credential.UserName -replace '^.*\\', ''
|
||||
$adUser = Get-ADUser -Identity $samName -Server $Server -Credential $Credential `
|
||||
-Properties SID, MemberOf -ErrorAction Stop
|
||||
-Properties SID, DistinguishedName, adminCount -ErrorAction Stop
|
||||
[void]$callerSids.Add($adUser.SID.Value)
|
||||
foreach ($groupDN in @($adUser.MemberOf)) {
|
||||
try {
|
||||
$g = Get-ADGroup -Identity $groupDN -Server $Server -Credential $Credential `
|
||||
-Properties SID -ErrorAction Stop
|
||||
[void]$callerSids.Add($g.SID.Value)
|
||||
} catch { }
|
||||
|
||||
# tokenGroups is a constructed attribute containing all SIDs in the user's token,
|
||||
# including nested group memberships — more reliable than walking MemberOf recursively
|
||||
$userDe = New-Object System.DirectoryServices.DirectoryEntry(
|
||||
"LDAP://$Server/$($adUser.DistinguishedName)",
|
||||
$Credential.UserName,
|
||||
$Credential.GetNetworkCredential().Password
|
||||
)
|
||||
$userDe.RefreshCache(@('tokenGroups'))
|
||||
foreach ($sidBytes in $userDe.Properties['tokenGroups']) {
|
||||
$sid = New-Object System.Security.Principal.SecurityIdentifier($sidBytes, 0)
|
||||
[void]$callerSids.Add($sid.Value)
|
||||
}
|
||||
|
||||
# adminCount=1 means SDProp is managing this account; it runs every 60 min and can
|
||||
# silently revert replication rights or group memberships granted to the account
|
||||
if ($adUser.adminCount -eq 1) {
|
||||
Write-Warning ("Account '{0}' has adminCount=1 (SDProp-protected). It is or was a member of a privileged group. SDProp runs every 60 minutes and may silently revert replication rights or group memberships on this account." -f $Credential.UserName)
|
||||
}
|
||||
|
||||
# Protected Users group (RID 525) blocks the Kerberos mechanisms DSInternals uses for DRS
|
||||
$domainSidStr = $adUser.SID.Value.Substring(0, $adUser.SID.Value.LastIndexOf('-'))
|
||||
$protectedUsersSid = "$domainSidStr-525"
|
||||
if ($callerSids.Contains($protectedUsersSid)) {
|
||||
Write-Warning ("Account '{0}' is a member of Protected Users. This group restricts Kerberos delegation and RC4 authentication that DSInternals requires for DRS replication — access will be denied regardless of assigned rights." -f $Credential.UserName)
|
||||
}
|
||||
} catch {
|
||||
Write-Warning ("Could not resolve account SIDs for replication permission pre-check: {0}. Skipping." -f $_.Exception.Message)
|
||||
@@ -366,21 +387,67 @@ function Test-ReplicationPermissions {
|
||||
|
||||
$missing = @()
|
||||
foreach ($rightName in $requiredRights.Keys) {
|
||||
$guid = $requiredRights[$rightName]
|
||||
$granted = $false
|
||||
$guid = $requiredRights[$rightName]
|
||||
$granted = $false
|
||||
$aceExistsForGuid = $false
|
||||
foreach ($ace in $acl) {
|
||||
if ($ace.AccessControlType -ne [System.Security.AccessControl.AccessControlType]::Allow) { continue }
|
||||
if (-not ($ace.ActiveDirectoryRights -band [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight)) { continue }
|
||||
if ($ace.ObjectType -ne $guid) { continue }
|
||||
# InheritOnly ACEs apply to child objects only — the domain root itself is not covered
|
||||
if ([bool]($ace.PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::InheritOnly)) { continue }
|
||||
$rights = $ace.ActiveDirectoryRights
|
||||
$hasExtended = [bool]($rights -band [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight)
|
||||
$hasGenericAll = [bool]($rights -band [System.DirectoryServices.ActiveDirectoryRights]::GenericAll)
|
||||
# Match: exact GUID, OR ExtendedRight with empty ObjectType (all extended rights), OR GenericAll
|
||||
$isMatch = $hasGenericAll `
|
||||
-or ($hasExtended -and $ace.ObjectType -eq [guid]::Empty) `
|
||||
-or ($hasExtended -and $ace.ObjectType -eq $guid)
|
||||
if (-not $isMatch) { continue }
|
||||
if ($ace.ObjectType -eq $guid) { $aceExistsForGuid = $true }
|
||||
if ($callerSids.Contains($ace.IdentityReference.Value)) { $granted = $true; break }
|
||||
}
|
||||
if (-not $granted) { $missing += $rightName }
|
||||
if (-not $granted) {
|
||||
$hint = if ($aceExistsForGuid) {
|
||||
' (ACE exists on the domain object but is not assigned to this account or any of its groups)'
|
||||
} else {
|
||||
' (no ACE found for this right on the domain object at all)'
|
||||
}
|
||||
$missing += $rightName + $hint
|
||||
}
|
||||
}
|
||||
|
||||
if ($missing.Count -gt 0) {
|
||||
throw ("Account '{0}' is missing the following replication permissions on '{1}':`n - {2}`n`nGrant these extended rights on the domain object to allow DCSync-based hash retrieval." -f `
|
||||
throw ("Account '{0}' failed replication permission check on '{1}':`n - {2}`n`nGrant these extended rights on the domain object to allow DCSync-based hash retrieval." -f `
|
||||
$Credential.UserName, $DomainDN, ($missing -join "`n - "))
|
||||
}
|
||||
|
||||
Write-Host ("[+] Replication permissions verified for '{0}'." -f $Credential.UserName)
|
||||
}
|
||||
|
||||
function Test-DCClockSkew {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Server,
|
||||
[Parameter(Mandatory)][System.Management.Automation.PSCredential]$Credential
|
||||
)
|
||||
try {
|
||||
$rootDse = New-Object System.DirectoryServices.DirectoryEntry(
|
||||
"LDAP://$Server/RootDSE",
|
||||
$Credential.UserName,
|
||||
$Credential.GetNetworkCredential().Password
|
||||
)
|
||||
$dcTimeStr = $rootDse.Properties['currentTime'][0]
|
||||
$dcTime = [datetime]::ParseExact(
|
||||
$dcTimeStr, 'yyyyMMddHHmmss.0Z',
|
||||
[System.Globalization.CultureInfo]::InvariantCulture,
|
||||
[System.Globalization.DateTimeStyles]::AssumeUniversal).ToUniversalTime()
|
||||
$skewSeconds = [Math]::Abs(([datetime]::UtcNow - $dcTime).TotalSeconds)
|
||||
if ($skewSeconds -gt 300) {
|
||||
Write-Warning ("Clock skew of {0:N0}s with '{1}' exceeds Kerberos limit of 300s — authentication will fail. Sync the clock: w32tm /resync /force" -f $skewSeconds, $Server)
|
||||
} elseif ($skewSeconds -gt 60) {
|
||||
Write-Warning ("Clock skew of {0:N0}s detected with '{1}'. Kerberos allows up to 300s — approaching the limit." -f $skewSeconds, $Server)
|
||||
} else {
|
||||
Write-Host ("[+] Clock skew with '{0}': {1:N0}s (OK)." -f $Server, $skewSeconds)
|
||||
}
|
||||
} catch {
|
||||
Write-Warning ("Could not check clock skew against '{0}': {1}" -f $Server, $_.Exception.Message)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Elysium.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: ElysiumSettings.txt ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Extract-NTHashes.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Prepare-KHDBStorage.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Test-WeakADPasswords.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
@@ -95,7 +95,7 @@ function Invoke-UsageBeacon {
|
||||
if ($normalizedMethod -in @('POST', 'PUT')) {
|
||||
$payload = [ordered]@{
|
||||
script = 'Test-WeakADPasswords'
|
||||
version = '2.2.1'
|
||||
version = $ElysiumVersion
|
||||
ranAtUtc = (Get-Date).ToUniversalTime().ToString('o')
|
||||
}
|
||||
if (-not [string]::IsNullOrWhiteSpace($InstanceId)) {
|
||||
@@ -352,7 +352,14 @@ function Import-CompatModule {
|
||||
|
||||
$nonFipsErrors = @($importErrors | Where-Object { $_.Exception.Message -notmatch 'Only FIPS certified cryptographic algorithms are enabled in \.NET' })
|
||||
if ($nonFipsErrors.Count -gt 0) {
|
||||
Write-Warning ("DSInternals import reported non-fatal warning(s): {0}" -f $nonFipsErrors[0].Exception.Message)
|
||||
$nonFipsMsg = $nonFipsErrors[0].Exception.Message
|
||||
if ($nonFipsMsg -match 'Zone\.Identifier|alternate data stream') {
|
||||
$dsModule = Get-Module -Name DSInternals -ErrorAction SilentlyContinue
|
||||
if (-not $dsModule) { $dsModule = Get-Module -ListAvailable -Name DSInternals -ErrorAction SilentlyContinue | Select-Object -First 1 }
|
||||
$dsPath = if ($dsModule) { $dsModule.ModuleBase } else { '<DSInternals module path>' }
|
||||
throw ("DSInternals native DLL is blocked by Windows (Zone.Identifier). Run the following on the target machine and retry:`n Get-ChildItem -Path '$dsPath' -Recurse | Unblock-File")
|
||||
}
|
||||
Write-Warning ("DSInternals import reported non-fatal warning(s): {0}" -f $nonFipsMsg)
|
||||
}
|
||||
|
||||
Write-Verbose ("Imported module '{0}' (Core={1}, Windows={2})" -f $Name, $runningInPSCore, $onWindows)
|
||||
@@ -385,6 +392,28 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
# Version check: v6.2 was unsigned (blocks native DLLs, causes replication failures);
|
||||
# v7.0 fixes intermittent CRC errors mid-replication and Test-PasswordQuality result truncation.
|
||||
$dsInternalsVersion = (Get-Module -Name DSInternals).Version
|
||||
$minimumVersion = [version]'7.0'
|
||||
$unsignedVersion = [version]'6.2'
|
||||
if ($dsInternalsVersion -eq $unsignedVersion) {
|
||||
Write-Warning ("DSInternals {0} is not digitally signed, which blocks its native DLLs and causes replication failures. Update to v7.0+: Install-Module DSInternals -Force -AllowClobber" -f $dsInternalsVersion)
|
||||
} elseif ($dsInternalsVersion -lt $minimumVersion) {
|
||||
$resp = Read-Host ("DSInternals {0} is installed; v7.0 fixes intermittent replication CRC errors and result truncation. Update now? [Y/N]" -f $dsInternalsVersion)
|
||||
if ($resp -match '^(?i:y|yes)$') {
|
||||
try {
|
||||
# Install-Module -Force is used instead of Update-Module to avoid a PowerShellGet bug
|
||||
# where null PublishedDate metadata causes "cannot convert null to type system.datetime"
|
||||
Install-Module -Name DSInternals -Force -AllowClobber -ErrorAction Stop
|
||||
Write-Host '[+] DSInternals updated. Please re-run the script to load the new version.'
|
||||
exit 0
|
||||
} catch {
|
||||
Write-Warning ("DSInternals update failed: {0}" -f $_.Exception.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Resolve KHDB path with fallbacks
|
||||
$installationPath = $ElysiumSettings["InstallationPath"]
|
||||
if ([string]::IsNullOrWhiteSpace($installationPath)) { $installationPath = $scriptRoot }
|
||||
@@ -575,9 +604,10 @@ function Test-WeakADPasswords {
|
||||
Write-Verbose ("Using credential supplied by caller: {0}" -f $credential.UserName)
|
||||
}
|
||||
|
||||
# Verify the account has the three replication extended rights before attempting DCSync
|
||||
# Pre-flight checks before attempting DCSync
|
||||
try {
|
||||
$domainInfo = Get-ADDomain -Server $selectedDomain["DC"] -Credential $credential -ErrorAction Stop
|
||||
Test-DCClockSkew -Server $selectedDomain["DC"] -Credential $credential
|
||||
Test-ReplicationPermissions -DomainDN $domainInfo.DistinguishedName `
|
||||
-Server $selectedDomain["DC"] -Credential $credential
|
||||
} catch {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Uninstall.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Update-KHDB.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
@@ -61,7 +61,7 @@ function New-HttpClient {
|
||||
Add-Type -AssemblyName System.Net.Http -ErrorAction SilentlyContinue
|
||||
$client = [System.Net.Http.HttpClient]::new()
|
||||
$client.Timeout = [TimeSpan]::FromSeconds(600)
|
||||
$client.DefaultRequestHeaders.UserAgent.ParseAdd('Elysium/2.2.1 (+Update-KHDB)')
|
||||
$client.DefaultRequestHeaders.UserAgent.ParseAdd("Elysium/$ElysiumVersion (+Update-KHDB)")
|
||||
return $client
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
##################################################
|
||||
## Project: Elysium ##
|
||||
## File: Update-LithnetStore.ps1 ##
|
||||
## Version: 2.2.1 ##
|
||||
## Version: 2.4.0 ##
|
||||
## Support: support@cqre.net ##
|
||||
##################################################
|
||||
|
||||
|
||||
Reference in New Issue
Block a user