From 91d7254ea640a4f3a824f1978c48fe903fb7f8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20K=C5=82ys?= Date: Wed, 6 May 2026 09:31:04 +0200 Subject: [PATCH 1/3] Add readable encryption type reporting --- Private/Configuration.ServiceAccounts.ps1 | 10 ++- Private/Configuration.WinADComputer.ps1 | 9 +- Private/Configuration.WinADUser.ps1 | 9 +- ...onvertTo-WinADSupportedEncryptionTypes.ps1 | 85 +++++++++++++++++++ Private/Get-WinADTrustObject.ps1 | 5 +- Public/Get-WinADComputers.ps1 | 23 ++++- Public/Get-WinADServiceAccount.ps1 | 14 ++- Public/Get-WinADUsers.ps1 | 23 ++++- 8 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 Private/ConvertTo-WinADSupportedEncryptionTypes.ps1 diff --git a/Private/Configuration.ServiceAccounts.ps1 b/Private/Configuration.ServiceAccounts.ps1 index f9d3abf4..f317aa37 100644 --- a/Private/Configuration.ServiceAccounts.ps1 +++ b/Private/Configuration.ServiceAccounts.ps1 @@ -21,11 +21,17 @@ New-HTMLTab -Name $Domain { New-HTMLTable -DataTable $Script:Reporting['ServiceAccounts']['Data'][$Domain] -Filtering { - + New-HTMLTableCondition -Name 'UsesDESEncryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Red + New-HTMLTableCondition -Name 'UsesRC4Encryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Salmon + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $true -BackgroundColor LightYellow + New-HTMLTableConditionGroup -Conditions { + New-HTMLTableCondition -Name 'UsesAESKeys' -ComparisonType bool -Operator eq -Value $false + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $false + } -BackgroundColor LightPink -HighlightHeaders SupportedEncryptionTypes, UsesAESKeys } } } } } } -} \ No newline at end of file +} diff --git a/Private/Configuration.WinADComputer.ps1 b/Private/Configuration.WinADComputer.ps1 index a4e2d72a..ffe1f463 100644 --- a/Private/Configuration.WinADComputer.ps1 +++ b/Private/Configuration.WinADComputer.ps1 @@ -188,10 +188,17 @@ New-HTMLTableCondition -Name 'Enabled' -ComparisonType string -Operator eq -Value $True New-HTMLTableCondition -Name 'PasswordNotRequired' -ComparisonType string -Operator eq -Value $True } -BackgroundColor Red -HighlightHeaders Name, SamAccountName, Enabled, PasswordNotRequired + New-HTMLTableCondition -Name 'UsesDESEncryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Red + New-HTMLTableCondition -Name 'UsesRC4Encryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Salmon + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $true -BackgroundColor LightYellow + New-HTMLTableConditionGroup -Conditions { + New-HTMLTableCondition -Name 'UsesAESKeys' -ComparisonType bool -Operator eq -Value $false + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $false + } -BackgroundColor LightPink -HighlightHeaders SupportedEncryptionTypes, UsesAESKeys } -ScrollX } } } } } -} \ No newline at end of file +} diff --git a/Private/Configuration.WinADUser.ps1 b/Private/Configuration.WinADUser.ps1 index b0be45d8..90677526 100644 --- a/Private/Configuration.WinADUser.ps1 +++ b/Private/Configuration.WinADUser.ps1 @@ -164,10 +164,17 @@ New-HTMLTableCondition -Name 'Enabled' -ComparisonType string -Operator eq -Value $True New-HTMLTableCondition -Name 'PasswordNotRequired' -ComparisonType string -Operator eq -Value $True } -BackgroundColor Red -HighlightHeaders Name, SamAccountName, Enabled, PasswordNotRequired + New-HTMLTableCondition -Name 'UsesDESEncryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Red + New-HTMLTableCondition -Name 'UsesRC4Encryption' -ComparisonType bool -Operator eq -Value $true -BackgroundColor Salmon + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $true -BackgroundColor LightYellow + New-HTMLTableConditionGroup -Conditions { + New-HTMLTableCondition -Name 'UsesAESKeys' -ComparisonType bool -Operator eq -Value $false + New-HTMLTableCondition -Name 'UsesDomainEncryptionDefaults' -ComparisonType bool -Operator eq -Value $false + } -BackgroundColor LightPink -HighlightHeaders SupportedEncryptionTypes, UsesAESKeys } -ScrollX } } } } } -} \ No newline at end of file +} diff --git a/Private/ConvertTo-WinADSupportedEncryptionTypes.ps1 b/Private/ConvertTo-WinADSupportedEncryptionTypes.ps1 new file mode 100644 index 00000000..f67932b6 --- /dev/null +++ b/Private/ConvertTo-WinADSupportedEncryptionTypes.ps1 @@ -0,0 +1,85 @@ +function ConvertTo-WinADSupportedEncryptionTypes { + [cmdletBinding()] + param( + [AllowNull()][object] $Value + ) + + if ($null -ne $Value -and $Value -is [System.Collections.IEnumerable] -and $Value -isnot [string]) { + $Value = @($Value) | Select-Object -First 1 + } + + if ($null -eq $Value -or ($Value -is [string] -and $Value -eq '')) { + return [PSCustomObject] @{ + RawValue = $null + ValueState = 'Not configured' + Types = [string[]] @() + TypesText = 'Not configured (uses KDC/domain defaults)' + UsesDomainDefaults = $true + UsesAESKeys = $false + UsesRC4Encryption = $false + UsesDESEncryption = $false + EnforcesAESSessionKeys = $false + } + } + + try { + [int32] $RawValue = $Value + } catch { + return [PSCustomObject] @{ + RawValue = $Value + ValueState = 'Invalid' + Types = [string[]] @() + TypesText = "Invalid value: $Value" + UsesDomainDefaults = $false + UsesAESKeys = $false + UsesRC4Encryption = $false + UsesDESEncryption = $false + EnforcesAESSessionKeys = $false + } + } + + if ($RawValue -eq 0) { + return [PSCustomObject] @{ + RawValue = 0 + ValueState = 'Configured as 0' + Types = [string[]] @() + TypesText = 'Configured as 0 (uses KDC/domain defaults)' + UsesDomainDefaults = $true + UsesAESKeys = $false + UsesRC4Encryption = $false + UsesDESEncryption = $false + EnforcesAESSessionKeys = $false + } + } + + $EncryptionTypeMap = [ordered] @{ + '1' = 'DES-CBC-CRC' + '2' = 'DES-CBC-MD5' + '4' = 'RC4-HMAC' + '8' = 'AES128-CTS-HMAC-SHA1-96' + '16' = 'AES256-CTS-HMAC-SHA1-96' + '32' = 'FAST-supported' + '64' = 'Compound-identity-supported' + '128' = 'Claims-supported' + '256' = 'AES256-CTS-HMAC-SHA1-96-SK' + '512' = 'Resource-SID-compression-disabled' + } + + [string[]] $Types = foreach ($Bit in $EncryptionTypeMap.Keys) { + if ($RawValue -band [int32] $Bit) { + $EncryptionTypeMap[$Bit] + } + } + + [PSCustomObject] @{ + RawValue = $RawValue + ValueState = 'Configured' + Types = $Types + TypesText = if ($Types.Count -gt 0) { $Types -join ', ' } else { 'None' } + UsesDomainDefaults = $false + UsesAESKeys = $Types -contains 'AES128-CTS-HMAC-SHA1-96' -or $Types -contains 'AES256-CTS-HMAC-SHA1-96' + UsesRC4Encryption = $Types -contains 'RC4-HMAC' + UsesDESEncryption = $Types -contains 'DES-CBC-CRC' -or $Types -contains 'DES-CBC-MD5' + EnforcesAESSessionKeys = $Types -contains 'AES256-CTS-HMAC-SHA1-96-SK' + } +} diff --git a/Private/Get-WinADTrustObject.ps1 b/Private/Get-WinADTrustObject.ps1 index 5915e5be..a0bac4ac 100644 --- a/Private/Get-WinADTrustObject.ps1 +++ b/Private/Get-WinADTrustObject.ps1 @@ -77,6 +77,7 @@ } else { $ObjectSID = $null } + $SupportedEncryption = ConvertTo-WinADSupportedEncryptionTypes -Value $Trust.properties.'msds-supportedencryptiontypes' $TrustObject = [PSCustomObject] @{ #Name = [string] $Trust.properties.name # {ad.evotec.xyz} @@ -101,7 +102,7 @@ ShowInAdvancedViewOnly = [bool]::Parse($Trust.properties.showinadvancedviewonly) # {True} TrustPosixOffset = [string] $Trust.properties.trustposixoffset # {-2147483648} msDSTrustForestTrustInfo = $msDSTrustForestTrustInfo - msDSSupportedEncryptionTypes = if ($Trust.properties.'msds-supportedencryptiontypes') { Get-ADEncryptionTypes -Value ([int] $Trust.properties.'msds-supportedencryptiontypes'[0]) } else { $null } + msDSSupportedEncryptionTypes = $SupportedEncryption.Types #SecurityIdentifier = [string] $Trust.properties.securityidentifier # {1 4 0 0 0 0 0 5 21 0 0 0 113 37 225 50 27 133 23 171 67 175 144 188} #InstanceType = $Trust.properties.instancetype # {4} #AdsPath = [string] $Trust.properties.adspath # {LDAP://CN=ad.evotec.xyz,CN=System,DC=ad,DC=evotec,DC=pl} @@ -119,4 +120,4 @@ if ($AsHashTable) { $Summary } -} \ No newline at end of file +} diff --git a/Public/Get-WinADComputers.ps1 b/Public/Get-WinADComputers.ps1 index 10b04965..c541ba6f 100644 --- a/Public/Get-WinADComputers.ps1 +++ b/Public/Get-WinADComputers.ps1 @@ -58,7 +58,7 @@ $Properties = @( 'DistinguishedName', 'LastLogonDate', 'PasswordLastSet', 'Enabled', 'DnsHostName', 'PasswordNeverExpires', 'PasswordNotRequired', 'PasswordExpired', 'ManagedBy', 'OperatingSystemVersion', 'OperatingSystem' , 'TrustedForDelegation', 'WhenCreated', 'WhenChanged', 'PrimaryGroupID' - 'nTSecurityDescriptor' + 'nTSecurityDescriptor', 'msDS-SupportedEncryptionTypes' ) $AllComputers[$Domain] = Get-ADComputer -Filter "*" -Server $QueryServer -Properties $Properties } @@ -120,6 +120,7 @@ } else { $PasswordLastChangedDays = $null } + $SupportedEncryption = ConvertTo-WinADSupportedEncryptionTypes -Value $Computer.'msDS-SupportedEncryptionTypes' if ($AddOwner) { $Owner = Get-ADACLOwner -ADObject $Computer -Verbose -Resolve @@ -154,6 +155,15 @@ ManagerDN = $Computer.ManagedBy Description = $Computer.Description TrustedForDelegation = $Computer.TrustedForDelegation + 'msDS-SupportedEncryptionTypes' = $SupportedEncryption.RawValue + SupportedEncryptionTypesState = $SupportedEncryption.ValueState + SupportedEncryptionTypes = $SupportedEncryption.TypesText + UsesDomainEncryptionDefaults = $SupportedEncryption.UsesDomainDefaults + UsesAESKeys = $SupportedEncryption.UsesAESKeys + UsesRC4Encryption = $SupportedEncryption.UsesRC4Encryption + UsesDESEncryption = $SupportedEncryption.UsesDESEncryption + EnforcesAESSessionKeys = $SupportedEncryption.EnforcesAESSessionKeys + msDSSupportedEncryptionTypes = $SupportedEncryption.Types } } else { $Owner = $null @@ -185,6 +195,15 @@ ManagerDN = $Computer.ManagedBy Description = $Computer.Description TrustedForDelegation = $Computer.TrustedForDelegation + 'msDS-SupportedEncryptionTypes' = $SupportedEncryption.RawValue + SupportedEncryptionTypesState = $SupportedEncryption.ValueState + SupportedEncryptionTypes = $SupportedEncryption.TypesText + UsesDomainEncryptionDefaults = $SupportedEncryption.UsesDomainDefaults + UsesAESKeys = $SupportedEncryption.UsesAESKeys + UsesRC4Encryption = $SupportedEncryption.UsesRC4Encryption + UsesDESEncryption = $SupportedEncryption.UsesDESEncryption + EnforcesAESSessionKeys = $SupportedEncryption.EnforcesAESSessionKeys + msDSSupportedEncryptionTypes = $SupportedEncryption.Types } } } @@ -196,4 +215,4 @@ $Output[$O] } } -} \ No newline at end of file +} diff --git a/Public/Get-WinADServiceAccount.ps1 b/Public/Get-WinADServiceAccount.ps1 index c05655ac..36f26aa5 100644 --- a/Public/Get-WinADServiceAccount.ps1 +++ b/Public/Get-WinADServiceAccount.ps1 @@ -69,6 +69,7 @@ } else { $PasswordLastChangedDays = $null } + $SupportedEncryption = ConvertTo-WinADSupportedEncryptionTypes -Value $Account.'msDS-SupportedEncryptionTypes' [PSCUstomObject] @{ Name = $Account.Name @@ -100,8 +101,15 @@ AccountExpirationDate = $Account.AccountExpirationDate #AllowReversiblePasswordEncryption = $Account.AllowReversiblePasswordEncryption # : False #CannotChangePassword = $Account.CannotChangePassword # : False - #'msDS-SupportedEncryptionTypes' = $Account.'msDS-SupportedEncryptionTypes' # : 28 - msDSSupportedEncryptionTypes = Get-ADEncryptionTypes -Value $Account.'msds-supportedencryptiontypes' + 'msDS-SupportedEncryptionTypes' = $SupportedEncryption.RawValue + SupportedEncryptionTypesState = $SupportedEncryption.ValueState + SupportedEncryptionTypes = $SupportedEncryption.TypesText + UsesDomainEncryptionDefaults = $SupportedEncryption.UsesDomainDefaults + UsesAESKeys = $SupportedEncryption.UsesAESKeys + UsesRC4Encryption = $SupportedEncryption.UsesRC4Encryption + UsesDESEncryption = $SupportedEncryption.UsesDESEncryption + EnforcesAESSessionKeys = $SupportedEncryption.EnforcesAESSessionKeys + msDSSupportedEncryptionTypes = $SupportedEncryption.Types # 'msDS-User-Account-Control-Computed' = $Account.'msDS-User-Account-Control-Computed' # : 0 #ObjectGUID = $Account.ObjectGUID # : 573ff95e-c1f8-45e2-9b64-662fb9cb0615 PasswordNeverExpires = $Account.PasswordNeverExpires # : False @@ -127,4 +135,4 @@ } else { $Output.Values } -} \ No newline at end of file +} diff --git a/Public/Get-WinADUsers.ps1 b/Public/Get-WinADUsers.ps1 index 9d5dad19..f8c738cc 100644 --- a/Public/Get-WinADUsers.ps1 +++ b/Public/Get-WinADUsers.ps1 @@ -55,7 +55,7 @@ 'WhenCreated', 'WhenChanged' 'nTSecurityDescriptor', 'Country', 'Title', 'Department' - 'msds-resultantpso' + 'msds-resultantpso', 'msDS-SupportedEncryptionTypes' ) try { $AllUsers[$Domain] = Get-ADUser -Filter "*" -Properties $Properties -Server $QueryServer #$ForestInformation['QueryServers'][$Domain].HostName[0] @@ -176,6 +176,7 @@ $msExchRecipientTypeDetails = Convert-ExchangeRecipient -msExchRecipientTypeDetails $User.msExchRecipientTypeDetails $msExchRecipientDisplayType = Convert-ExchangeRecipient -msExchRecipientDisplayType $User.msExchRecipientDisplayType $msExchRemoteRecipientType = Convert-ExchangeRecipient -msExchRemoteRecipientType $User.msExchRemoteRecipientType + $SupportedEncryption = ConvertTo-WinADSupportedEncryptionTypes -Value $User.'msDS-SupportedEncryptionTypes' if ($User.'msds-resultantpso') { # $PasswordPolicy = 'FineGrained' @@ -232,6 +233,15 @@ PasswordExpired = $User.PasswordExpired CannotChangePassword = $User.CannotChangePassword TrustedForDelegation = $User.TrustedForDelegation + 'msDS-SupportedEncryptionTypes' = $SupportedEncryption.RawValue + SupportedEncryptionTypesState = $SupportedEncryption.ValueState + SupportedEncryptionTypes = $SupportedEncryption.TypesText + UsesDomainEncryptionDefaults = $SupportedEncryption.UsesDomainDefaults + UsesAESKeys = $SupportedEncryption.UsesAESKeys + UsesRC4Encryption = $SupportedEncryption.UsesRC4Encryption + UsesDESEncryption = $SupportedEncryption.UsesDESEncryption + EnforcesAESSessionKeys = $SupportedEncryption.EnforcesAESSessionKeys + msDSSupportedEncryptionTypes = $SupportedEncryption.Types ManagerDN = $User.Manager ManagerLastLogon = $ManagerLastLogon Group = $Group @@ -278,6 +288,15 @@ PasswordExpired = $User.PasswordExpired CannotChangePassword = $User.CannotChangePassword TrustedForDelegation = $User.TrustedForDelegation + 'msDS-SupportedEncryptionTypes' = $SupportedEncryption.RawValue + SupportedEncryptionTypesState = $SupportedEncryption.ValueState + SupportedEncryptionTypes = $SupportedEncryption.TypesText + UsesDomainEncryptionDefaults = $SupportedEncryption.UsesDomainDefaults + UsesAESKeys = $SupportedEncryption.UsesAESKeys + UsesRC4Encryption = $SupportedEncryption.UsesRC4Encryption + UsesDESEncryption = $SupportedEncryption.UsesDESEncryption + EnforcesAESSessionKeys = $SupportedEncryption.EnforcesAESSessionKeys + msDSSupportedEncryptionTypes = $SupportedEncryption.Types ManagerDN = $User.Manager ManagerLastLogon = $ManagerLastLogon Group = $Group @@ -296,4 +315,4 @@ } else { $Output.Values } -} \ No newline at end of file +} From 9a03f305499708141658f1d521cc61d6a6c49452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20K=C5=82ys?= Date: Wed, 6 May 2026 09:34:10 +0200 Subject: [PATCH 2/3] =?UTF-8?q?chore(build):=20=F0=9F=94=A7=20Update=20mod?= =?UTF-8?q?ule=20build=20script=20and=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated `ModuleVersion` to `1.0.3` in `ADEssentials.psd1`. * Refactored `Build-Module.ps1` for improved clarity and organization. * Ensured compatibility with required modules and updated documentation paths. --- ADEssentials.psd1 | 2 +- Build/Build-Module.ps1 | 341 +++++++++++++++-------------------------- 2 files changed, 122 insertions(+), 221 deletions(-) diff --git a/ADEssentials.psd1 b/ADEssentials.psd1 index 937a0729..3ea59712 100644 --- a/ADEssentials.psd1 +++ b/ADEssentials.psd1 @@ -8,7 +8,7 @@ Description = 'Helper module for Active Directory with lots of useful functions that simplify supporting Active Directory.' FunctionsToExport = @('Add-ADACL', 'Compare-PingCastleReport', 'Compare-WinADGlobalCatalogObjects', 'Convert-ADSecurityDescriptor', 'Copy-ADOUSecurity', 'Disable-ADACLInheritance', 'Enable-ADACLInheritance', 'Export-ADACLObject', 'Find-WinADObjectDifference', 'Get-ADACL', 'Get-ADACLOwner', 'Get-DNSServerIP', 'Get-PingCastleReport', 'Get-WinADACLConfiguration', 'Get-WinADACLForest', 'Get-WinADBitlockerLapsSummary', 'Get-WinADBrokenProtectedFromDeletion', 'Get-WinADComputerACLLAPS', 'Get-WinADComputers', 'Get-WinADDelegatedAccounts', 'Get-WinADDFSHealth', 'Get-WinADDFSTopology', 'Get-WinADDHCP', 'Get-WinADDHCPHealthCheck', 'Get-WinADDHCPSummary', 'Get-WinADDiagnostics', 'Get-WinADDnsInformation', 'Get-WinADDnsIPAddresses', 'Get-WinADDnsRecords', 'Get-WinADDnsServerForwarder', 'Get-WinADDnsServerScavenging', 'Get-ADWinDnsServerZones', 'Get-WinADDNSZones', 'Get-WinADDomain', 'Get-WinADDomainControllerGenerationId', 'Get-WinADDomainControllerNetLogonSettings', 'Get-WinADDomainControllerNTDSSettings', 'Get-WinADDomainControllerOption', 'Get-WinADDuplicateObject', 'Get-WinADDuplicateSPN', 'Get-WinADForest', 'Get-WinADForestControllerInformation', 'Get-WinADForestOptionalFeatures', 'Get-WinADForestReplication', 'Get-WinADForestReplicationSummary', 'Get-WinADForestRoles', 'Get-WinADForestSchemaDetails', 'Get-WinADForestSchemaProperties', 'Get-WinADForestSites', 'Get-WinADForestSubnet', 'Get-WinADGroupMember', 'Get-WinADGroupMemberOf', 'Get-WinADGroups', 'Get-WinADKerberosAccount', 'Get-WinADLastBackup', 'Get-WinADLDAPBindingsSummary', 'Get-WinADLDAPSummary', 'Get-WinADLMSettings', 'Get-WinADObject', 'Get-WinADOrganization', 'Get-WinADPasswordPolicy', 'Get-WinADPrivilegedObjects', 'Get-WinADProtocol', 'Get-WinADProxyAddresses', 'Get-WinADServiceAccount', 'Get-WinADSharePermission', 'Get-WinADSIDHistory', 'Get-WinADSiteConnections', 'Get-WinADSiteCoverage', 'Get-WinADSiteLinks', 'Get-WinADSiteOptions', 'Get-WinADTombstoneLifetime', 'Get-WinADTrust', 'Get-WinADTrustLegacy', 'Get-WinADUserPrincipalName', 'Get-WinADUsers', 'Get-WinADUsersForeignSecurityPrincipalList', 'Get-WinADWellKnownFolders', 'Invoke-ADEssentials', 'Invoke-PingCastle', 'Invoke-WinADDHCPHealthCheck', 'New-ADACLObject', 'New-ADSite', 'Remove-ADACL', 'Remove-WinADDFSTopology', 'Remove-WinADDuplicateObject', 'Remove-WinADSharePermission', 'Rename-WinADUserPrincipalName', 'Repair-WinADACLConfigurationOwner', 'Repair-WinADBrokenProtectedFromDeletion', 'Repair-WinADEmailAddress', 'Repair-WinADForestControllerInformation', 'Request-ChangePasswordAtLogon', 'Request-DisableOnAccountExpiration', 'Restore-ADACLDefault', 'Set-ADACL', 'Set-ADACLInheritance', 'Set-ADACLOwner', 'Set-DnsServerIP', 'Set-WinADDiagnostics', 'Set-WinADDomainControllerNetLogonSettings', 'Set-WinADDomainControllerOption', 'Set-WinADForestACLOwner', 'Set-WinADReplication', 'Set-WinADReplicationConnections', 'Set-WinADShare', 'Set-WinADTombstoneLifetime', 'Show-WinADDHCPSummary', 'Show-WinADDNSRecords', 'Show-WinADForestReplicationSummary', 'Show-WinADGroupCritical', 'Show-WinADGroupMember', 'Show-WinADGroupMemberOf', 'Show-WinADKerberosAccount', 'Show-WinADLdapSummary', 'Show-WinADObjectDifference', 'Show-WinADOrganization', 'Show-WinADSIDHistory', 'Show-WinADSites', 'Show-WinADSitesCoverage', 'Show-WinADTrust', 'Show-WinADUserSecurity', 'Sync-WinADDomainController', 'Test-ADDomainController', 'Test-ADRolesAvailability', 'Test-ADSiteLinks', 'Test-DNSNameServers', 'Test-FSMORolesAvailability', 'Test-LDAP', 'Test-WinADDNSResolving', 'Test-WinADObjectReplicationStatus', 'Test-WinADVulnerableSchemaClass', 'Update-LastLogonTimestamp') GUID = '9fc9fd61-7f11-4f4b-a527-084086f1905f' - ModuleVersion = '1.0.2' + ModuleVersion = '1.0.3' PowerShellVersion = '5.1' PrivateData = @{ PSData = @{ diff --git a/Build/Build-Module.ps1 b/Build/Build-Module.ps1 index a62cb24e..c9f050e8 100644 --- a/Build/Build-Module.ps1 +++ b/Build/Build-Module.ps1 @@ -1,221 +1,122 @@ -Clear-Host -Import-Module "PSPublishModule" -Force -RequiredVersion '2.0.27' - -Invoke-ModuleBuild -ModuleName 'ADEssentials' { - # Usual defaults as per standard module - $Manifest = [ordered] @{ - ModuleVersion = '1.0.X' - # Supported PSEditions - CompatiblePSEditions = @('Desktop', 'Core') - # ID used to uniquely identify this module - GUID = '9fc9fd61-7f11-4f4b-a527-084086f1905f' - # Author of this module - Author = 'Przemyslaw Klys' - # Company or vendor of this module - CompanyName = 'Evotec' - # Copyright statement for this module - Copyright = "(c) 2011 - $((Get-Date).Year) Przemyslaw Klys @ Evotec. All rights reserved." - # Description of the functionality provided by this module - Description = 'Helper module for Active Directory with lots of useful functions that simplify supporting Active Directory.' - # Minimum version of the Windows PowerShell engine required by this module - PowerShellVersion = '5.1' - # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. - Tags = @('Windows', 'ActiveDirectory') - #IconUri = 'https://evotec.xyz/wp-content/uploads/2018/10/PSSharedGoods-Alternative.png' - ProjectUri = 'https://github.com/EvotecIT/ADEssentials' - } - New-ConfigurationManifest @Manifest - - New-ConfigurationModule -Type RequiredModule -Name 'PSSharedGoods' -Version Latest -Guid Auto - New-ConfigurationModule -Type RequiredModule -Name 'PSWriteHTML' -Version 1.38.0 -Guid Auto - New-ConfigurationModule -Type RequiredModule -Name 'PSEventViewer' -Version 1.0.22 -Guid Auto - New-ConfigurationModule -Type ApprovedModule -Name @('PSSharedGoods', 'PSWriteColor', 'Connectimo', 'PSUnifi', 'PSWebToolbox', 'PSMyPassword') - - New-ConfigurationModuleSkip -IgnoreFunctionName @( - 'ConvertTo-Excel' - ) -IgnoreModuleName @( - 'PSWriteExcel', 'ActiveDirectory', 'Microsoft.PowerShell.Security', - 'Microsoft.WSMan.Management', 'NetTCPIP', 'PowerShellGet', 'CimCmdlets' - 'DnsServer', 'DnsClient', 'DhcpServer' - ) - - $ConfigurationFormat = [ordered] @{ - RemoveComments = $false - - PlaceOpenBraceEnable = $true - PlaceOpenBraceOnSameLine = $true - PlaceOpenBraceNewLineAfter = $true - PlaceOpenBraceIgnoreOneLineBlock = $false - - PlaceCloseBraceEnable = $true - PlaceCloseBraceNewLineAfter = $false - PlaceCloseBraceIgnoreOneLineBlock = $false - PlaceCloseBraceNoEmptyLineBefore = $true - - UseConsistentIndentationEnable = $true - UseConsistentIndentationKind = 'space' - UseConsistentIndentationPipelineIndentation = 'IncreaseIndentationAfterEveryPipeline' - UseConsistentIndentationIndentationSize = 4 - - UseConsistentWhitespaceEnable = $true - UseConsistentWhitespaceCheckInnerBrace = $true - UseConsistentWhitespaceCheckOpenBrace = $true - UseConsistentWhitespaceCheckOpenParen = $true - UseConsistentWhitespaceCheckOperator = $true - UseConsistentWhitespaceCheckPipe = $true - UseConsistentWhitespaceCheckSeparator = $true - - AlignAssignmentStatementEnable = $true - AlignAssignmentStatementCheckHashtable = $true - - UseCorrectCasingEnable = $true - } - # format PSD1 and PSM1 files when merging into a single file - # enable formatting is not required as Configuration is provided - New-ConfigurationFormat -ApplyTo 'OnMergePSM1', 'OnMergePSD1' -Sort None @ConfigurationFormat - # format PSD1 and PSM1 files within the module - # enable formatting is required to make sure that formatting is applied (with default settings) - New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'DefaultPSM1' -EnableFormatting -Sort None - # when creating PSD1 use special style without comments and with only required parameters - New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'OnMergePSD1' -PSD1Style 'Minimal' - # configuration for documentation, at the same time it enables documentation processing - New-ConfigurationDocumentation -Enable:$false -StartClean -UpdateWhenNew -PathReadme 'Docs\Readme.md' -Path 'Docs' - - New-ConfigurationImportModule -ImportSelf - - # exposes specific commands only if following modules are available - New-ConfigurationCommand -ModuleName 'ActiveDirectory' -CommandName @( - 'Add-ADACL' - 'Copy-ADOUSecurity' - 'New-ADACLObject' - 'Enable-ADACLInheritance' - 'Disable-ADACLInheritance' - 'Export-ADACLObject' - 'Get-ADACL' - 'Get-ADACLOwner' - 'Get-WinADACLConfiguration' - 'Get-WinADACLForest' - 'Get-WinADBitlockerLapsSummary' - 'Get-WinADComputerACLLAPS' - 'Get-WinADComputers' - 'Get-WinADDelegatedAccounts' - 'Get-WinADDFSHealth' - 'Get-WinADDHCP' - 'Get-WinADDiagnostics' - 'Get-WinADDuplicateObject' - 'Get-WinADDuplicateSPN' - 'Get-WinADForestControllerInformation' - 'Get-WinADForestOptionalFeatures' - 'Get-WinADForestReplication' - 'Get-WinADForestRoles' - 'Get-WinADForestSchemaProperties' - 'Get-WinADForestSites' - 'Get-WinADForestSubnet' - 'Get-WinADLastBackup' - 'Get-WinADLDAPBindingsSummary' - 'Get-WinADLMSettings' - 'Get-WinADPrivilegedObjects' - 'Get-WinADProtocol' - 'Get-WinADProxyAddresses' - 'Get-WinADServiceAccount' - 'Get-WinADSharePermission' - 'Get-WinADSiteConnections' - 'Get-WinADSiteLinks' - 'Get-WinADTomebstoneLifetime' - 'Get-WinADTrustLegacy' - 'Get-WinADUserPrincipalName' - 'Get-WinADUsers' - 'Get-WinADUsersForeignSecurityPrincipalList' - 'Get-WinADWellKnownFolders' - 'Get-WinADPasswordPolicy' - 'Invoke-ADEssentials' - 'Remove-ADACL' - 'Remove-WinADDuplicateObject' - 'Remove-WinADSharePermission' - 'Rename-WinADUserPrincipalName' - 'Repair-WinADACLConfigurationOwner' - 'Repair-WinADEmailAddress' - 'Repair-WinADForestControllerInformation' - 'Set-ADACLOwner' - 'Set-DnsServerIP' - 'Set-WinADDiagnostics' - 'Set-WinADReplication' - 'Set-WinADReplicationConnections' - 'Set-WinADShare' - 'Set-WinADTombstoneLifetime' - 'Show-WinADGroupCritical' - 'Show-WinADOrganization' - 'Show-WinADSites' - 'Show-WinADUserSecurity' - 'Sync-DomainController' - 'Test-ADDomainController' - 'Test-ADRolesAvailability' - 'Test-ADSiteLinks' - 'Test-DNSNameServers' - 'Test-FSMORolesAvailability' - 'Test-LDAP' - 'Get-WinDNSZones' - 'Get-WinDNSIPAddresses' - 'Find-WinADObjectDifference' - 'Show-WinADObjectDifference' - 'Test-WinADDNSResolving' - 'Get-WinADDomainControllerGenerationId' - 'Compare-WinADGlobalCatalogObjects' - 'Test-WinADObjectReplicationStatus' - 'Get-WinADSiteCoverage' - 'Get-WinADLDAPSummary' - 'Get-WinADForestReplicationSummary' - 'Show-WinADLdapSummary' - 'Show-WinADReplicationSummary' - 'Get-WinADSidHistory' - 'Show-WinADSidHistory' - ) - New-ConfigurationCommand -ModuleName 'DHCPServer' -CommandName @( - 'Get-WinADDHCP' - 'Get-WinADDHCPSummary' - 'Show-WinADDHCPSummary' - 'Get-WinADDHCPHealthCheck' - ) - New-ConfigurationCommand -ModuleName 'DNSServer' -CommandName @( - 'Get-WinADDnsInformation' - 'Get-WinADDNSIPAddresses' - 'Get-WinADDNSRecords' - 'Get-WinADDnsServerForwarder' - 'Get-WinADDnsServerScavenging' - 'Get-WinADDnsServerZones' - 'Get-WinADDnsZones' - 'Remove-WinADDnsRecord' - ) - - New-ConfigurationBuild -Enable:$true -SignModule -MergeModuleOnBuild -MergeFunctionsFromApprovedModules -CertificateThumbprint '483292C9E317AA13B07BB7A96AE9D1A5ED9E7703' - - $newConfigurationArtefactSplat = @{ - Type = 'Unpacked' - Enable = $true - Path = "$PSScriptRoot\..\Artefacts\Unpacked" - ModulesPath = "$PSScriptRoot\..\Artefacts\Unpacked\Modules" - RequiredModulesPath = "$PSScriptRoot\..\Artefacts\Unpacked\Modules" - AddRequiredModules = $true - CopyFiles = @{ - #"Examples\PublishingExample\Example-ExchangeEssentials.ps1" = "RunMe.ps1" - } - } - New-ConfigurationArtefact @newConfigurationArtefactSplat -CopyFilesRelative - $newConfigurationArtefactSplat = @{ - Type = 'Packed' - Enable = $true - Path = "$PSScriptRoot\..\Artefacts\Packed" - ModulesPath = "$PSScriptRoot\..\Artefacts\Packed\Modules" - RequiredModulesPath = "$PSScriptRoot\..\Artefacts\Packed\Modules" - AddRequiredModules = $true - CopyFiles = @{ - #"Examples\PublishingExample\Example-ExchangeEssentials.ps1" = "RunMe.ps1" - } - ArtefactName = '.v.zip' - } - New-ConfigurationArtefact @newConfigurationArtefactSplat - - # global options for publishing to github/psgallery - #New-ConfigurationPublish -Type PowerShellGallery -FilePath 'C:\Support\Important\PowerShellGalleryAPI.txt' -Enabled:$true - #New-ConfigurationPublish -Type GitHub -FilePath 'C:\Support\Important\GitHubAPI.txt' -UserName 'EvotecIT' -Enabled:$true +Clear-Host +Import-Module "PSPublishModule" -Force + +Invoke-ModuleBuild -ModuleName 'ADEssentials' { + # Usual defaults as per standard module + $Manifest = [ordered] @{ + ModuleVersion = '1.0.X' + # Supported PSEditions + CompatiblePSEditions = @('Desktop', 'Core') + # ID used to uniquely identify this module + GUID = '9fc9fd61-7f11-4f4b-a527-084086f1905f' + # Author of this module + Author = 'Przemyslaw Klys' + # Company or vendor of this module + CompanyName = 'Evotec' + # Copyright statement for this module + Copyright = "(c) 2011 - $((Get-Date).Year) Przemyslaw Klys @ Evotec. All rights reserved." + # Description of the functionality provided by this module + Description = 'Helper module for Active Directory with lots of useful functions that simplify supporting Active Directory.' + # Minimum version of the Windows PowerShell engine required by this module + PowerShellVersion = '5.1' + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + Tags = @('Windows', 'ActiveDirectory') + #IconUri = 'https://evotec.xyz/wp-content/uploads/2018/10/PSSharedGoods-Alternative.png' + ProjectUri = 'https://github.com/EvotecIT/ADEssentials' + } + New-ConfigurationManifest @Manifest + + New-ConfigurationModule -Type RequiredModule -Name 'PSSharedGoods' -Version Latest -Guid Auto + New-ConfigurationModule -Type RequiredModule -Name 'PSWriteHTML' -Version 1.38.0 -Guid Auto + New-ConfigurationModule -Type RequiredModule -Name 'PSEventViewer' -Version 1.0.22 -Guid Auto + New-ConfigurationModule -Type ApprovedModule -Name @('PSSharedGoods', 'PSWriteColor', 'Connectimo', 'PSUnifi', 'PSWebToolbox', 'PSMyPassword') + + New-ConfigurationModuleSkip -IgnoreFunctionName @( + 'ConvertTo-Excel' + ) -IgnoreModuleName @( + 'PSWriteExcel', 'ActiveDirectory', 'Microsoft.PowerShell.Security', + 'Microsoft.WSMan.Management', 'NetTCPIP', 'PowerShellGet', 'CimCmdlets' + 'DnsServer', 'DnsClient', 'DhcpServer' + ) + + $ConfigurationFormat = [ordered] @{ + RemoveComments = $false + + PlaceOpenBraceEnable = $true + PlaceOpenBraceOnSameLine = $true + PlaceOpenBraceNewLineAfter = $true + PlaceOpenBraceIgnoreOneLineBlock = $false + + PlaceCloseBraceEnable = $true + PlaceCloseBraceNewLineAfter = $false + PlaceCloseBraceIgnoreOneLineBlock = $false + PlaceCloseBraceNoEmptyLineBefore = $true + + UseConsistentIndentationEnable = $true + UseConsistentIndentationKind = 'space' + UseConsistentIndentationPipelineIndentation = 'IncreaseIndentationAfterEveryPipeline' + UseConsistentIndentationIndentationSize = 4 + + UseConsistentWhitespaceEnable = $true + UseConsistentWhitespaceCheckInnerBrace = $true + UseConsistentWhitespaceCheckOpenBrace = $true + UseConsistentWhitespaceCheckOpenParen = $true + UseConsistentWhitespaceCheckOperator = $true + UseConsistentWhitespaceCheckPipe = $true + UseConsistentWhitespaceCheckSeparator = $true + + AlignAssignmentStatementEnable = $true + AlignAssignmentStatementCheckHashtable = $true + + UseCorrectCasingEnable = $true + } + # format PSD1 and PSM1 files when merging into a single file + # enable formatting is not required as Configuration is provided + New-ConfigurationFormat -ApplyTo 'OnMergePSM1', 'OnMergePSD1' -Sort None @ConfigurationFormat + # format PSD1 and PSM1 files within the module + # enable formatting is required to make sure that formatting is applied (with default settings) + New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'DefaultPSM1' -EnableFormatting -Sort None + # when creating PSD1 use special style without comments and with only required parameters + New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'OnMergePSD1' -PSD1Style 'Minimal' + # configuration for documentation, at the same time it enables documentation processing + New-ConfigurationDocumentation -Enable:$false -StartClean -UpdateWhenNew -PathReadme 'Docs\Readme.md' -Path 'Docs' + + New-ConfigurationImportModule -ImportSelf + + # exposes specific commands only if following modules are available + New-ConfigurationCommand -ModuleName 'ActiveDirectory' + New-ConfigurationCommand -ModuleName 'DHCPServer' + New-ConfigurationCommand -ModuleName 'DNSServer' + + New-ConfigurationBuild -Enable:$true -SignModule -MergeModuleOnBuild -MergeFunctionsFromApprovedModules -CertificateThumbprint '483292C9E317AA13B07BB7A96AE9D1A5ED9E7703' + + $newConfigurationArtefactSplat = @{ + Type = 'Unpacked' + Enable = $true + Path = "$PSScriptRoot\..\Artefacts\Unpacked" + ModulesPath = "$PSScriptRoot\..\Artefacts\Unpacked\Modules" + RequiredModulesPath = "$PSScriptRoot\..\Artefacts\Unpacked\Modules" + AddRequiredModules = $true + CopyFiles = @{ + #"Examples\PublishingExample\Example-ExchangeEssentials.ps1" = "RunMe.ps1" + } + } + New-ConfigurationArtefact @newConfigurationArtefactSplat -CopyFilesRelative + $newConfigurationArtefactSplat = @{ + Type = 'Packed' + Enable = $true + Path = "$PSScriptRoot\..\Artefacts\Packed" + ModulesPath = "$PSScriptRoot\..\Artefacts\Packed\Modules" + RequiredModulesPath = "$PSScriptRoot\..\Artefacts\Packed\Modules" + AddRequiredModules = $true + CopyFiles = @{ + #"Examples\PublishingExample\Example-ExchangeEssentials.ps1" = "RunMe.ps1" + } + ArtefactName = '.v.zip' + } + New-ConfigurationArtefact @newConfigurationArtefactSplat + + # global options for publishing to github/psgallery + #New-ConfigurationPublish -Type PowerShellGallery -FilePath 'C:\Support\Important\PowerShellGalleryAPI.txt' -Enabled:$true + #New-ConfigurationPublish -Type GitHub -FilePath 'C:\Support\Important\GitHubAPI.txt' -UserName 'EvotecIT' -Enabled:$true } \ No newline at end of file From 2176110842fbbcbd4fd054505f3b50ac87770470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20K=C5=82ys?= Date: Wed, 6 May 2026 09:36:10 +0200 Subject: [PATCH 3/3] =?UTF-8?q?fix(Get-WinADServiceAccount):=20?= =?UTF-8?q?=F0=9F=90=9B=20Correct=20typo=20in=20PSCustomObject=20declarati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed the typo from `[PSCUstomObject]` to `[PSCustomObject]` to ensure proper object creation. --- Public/Get-WinADServiceAccount.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Public/Get-WinADServiceAccount.ps1 b/Public/Get-WinADServiceAccount.ps1 index 36f26aa5..a173371f 100644 --- a/Public/Get-WinADServiceAccount.ps1 +++ b/Public/Get-WinADServiceAccount.ps1 @@ -71,7 +71,7 @@ } $SupportedEncryption = ConvertTo-WinADSupportedEncryptionTypes -Value $Account.'msDS-SupportedEncryptionTypes' - [PSCUstomObject] @{ + [PSCustomObject] @{ Name = $Account.Name Enabled = $Account.Enabled # : True # : WO_SVC_Delete$ ObjectClass = $Account.ObjectClass # : msDS-ManagedServiceAccount