Skip to content

Commit ca32c7f

Browse files
authored
Merge pull request #220 from rebelinux/dev
v0.9.9 wip
2 parents 5c8fbcc + d1c9fb5 commit ca32c7f

11 files changed

+84
-50
lines changed

AsBuiltReport.Microsoft.AD.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'AsBuiltReport.Microsoft.AD.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '0.9.8'
15+
ModuleVersion = '0.9.9'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
##### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates.
99

10+
## [0.9.9] - Unreleased
11+
12+
### Added
13+
14+
- Add disclaimer warning to README.md about report usage and liability
15+
16+
### Changed
17+
18+
- Improve error logging and handling for initial Forest and Domain discovery process
19+
- Update module version to 0.9.9
20+
21+
### Fixed
22+
23+
- Fix cannot index into a null array error when generating Trusts diagrams for domains with no trusts defined
24+
- Fix Trusts diagram generation when multiple domains are present in the report
25+
- Fix issue with Global:Report variable
26+
1027
## [0.9.8] - 2025-12-09
1128

1229
### Added

Language/en-US/MicrosoftAD.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
ReportModuleInfo6 = - Getting dependency information:
1212
ProjectWebsite = - Please refer to the AsBuiltReport.Microsoft.AD github website for more detailed information about this project.
1313
CommunityProject = - AsBuiltReport is a community-maintained open source project. It has no sponsorship, endorsement, or affiliation with any technology vendors, their employees, or affiliates.
14-
DISCLAIMER = The information in this report has been gathered through automation and direct observation. The recommendations and conclusions are based on industry best practices, technical expertise, and empirical data. While comprehensive, this assessment may not cover all possible scenarios or configurations. Implementation of these recommendations should be carried out by qualified personnel with the appropriate knowledge and experience. The author(s) assume no responsibility for any damages, including but not limited to loss of business profits, business interruption, loss of data, or other financial losses resulting from the use of or reliance on this report.
14+
DISCLAIMER = This report contains information gathered through automation and observations. All opinions, recommendations, and conclusions are based on professional insight and expertise, though this assessment is not exhaustive. Implementation of recommendations should be reviewed and executed by qualified personnel. The author(s) assume no liability for any damagesincluding lost profits, business interruption, or financial loss—arising from the use of this report or its recommendations.
1515
'@
1616

1717
# Get-AbrADForest

Language/es-ES/MicrosoftAD.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
ReportModuleInfo6 = - Obteniendo información de dependencias:
1212
ProjectWebsite = - Por favor consulte el sitio web de github de AsBuiltReport.Microsoft.AD para obtener información más detallada sobre este proyecto.
1313
CommunityProject = - AsBuiltReport es un proyecto de código abierto mantenido por la comunidad. No tiene patrocinio, respaldo o afiliación con ningún proveedor de tecnología, sus empleados o afiliados.
14-
DISCLAIMER = La información en este informe ha sido recopilada mediante automatización y observación directa. Las recomendaciones y conclusiones se basan en las mejores prácticas de la industria, experiencia técnica y datos empíricos. Aunque es exhaustivo, esta evaluación puede no cubrir todos los posibles escenarios o configuraciones. La implementación de estas recomendaciones debe ser realizada por personal calificado con el conocimiento y la experiencia adecuados. El(los) autor(es) no asumen ninguna responsabilidad por daños, incluidos, entre otros, la pérdida de beneficios comerciales, interrupción del negocio, pérdida de datos u otras pérdidas financieras derivadas del uso o la confianza en este informe.
14+
DISCLAIMER = Este informe contiene información recopilada mediante automatización y observaciones. Todas las opiniones, recomendaciones y conclusiones se basan en el conocimiento y la experiencia profesional, aunque esta evaluación no es exhaustiva. La implementación de las recomendaciones debe ser revisada y ejecutada por personal calificado. El autor no asumen ninguna responsabilidad por daños, incluyendo, pero no limitado a, pérdida de ganancias, interrupción del negocio o pérdidas financieras, que surjan del uso de este informe o sus recomendaciones.
1515
'@
1616

1717
# Get-AbrADForest

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
</p>
2626
<!-- ********** DO NOT EDIT THESE LINKS ********** -->
2727

28+
> [!WARNING]
29+
> This report contains information gathered through automation and observations. All opinions, recommendations, and conclusions are based on professional insight and expertise, though this assessment is not exhaustive. Implementation of recommendations should be reviewed and executed by qualified personnel. The author(s) assume no liability for any damages—including lost profits, business interruption, or financial loss—arising from the use of this report or its recommendations.
30+
2831
#### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates.
2932

3033
# Microsoft AD As Built Report

Src/Private/Get-AbrDiagrammer.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function Get-AbrDiagrammer {
127127
$FileName = "$($FileName).$($Format)"
128128
$Graph = New-ADDiagram @DiagramParams -DiagramType $DiagramType -Format $Format -Filename $FileName
129129
} else {
130-
$FileName = "AsBuiltReport.$($Global:Report)-($($DiagramType)).$($Format)"
130+
$FileName = "AsBuiltReport.Microsoft.AD-($($DiagramType)).$($Format)"
131131
$Graph = New-ADDiagram @DiagramParams -DiagramType $DiagramType -Format $Format -Filename $FileName
132132
}
133133
if ($Graph) {

Src/Private/Get-ValidPSSession.ps1

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ function Get-ValidPSSession {
55
.DESCRIPTION
66
Function to generate a valid WinRM session from a computer string.
77
.NOTES
8-
Version: 0.9.6
8+
Version: 0.9.9
99
Author: Jonathan Colon
1010
.EXAMPLE
1111
PS C:\Users\JohnDoe> Get-ValidPSSession -ComputerName 'server-dc-01v.pharmax.local'
@@ -24,8 +24,8 @@ function Get-ValidPSSession {
2424
[Parameter(Mandatory)]
2525
[ValidateNotNullOrEmpty()]
2626
[string]$SessionName,
27-
[ref]$PSSTable
28-
27+
[ref]$PSSTable,
28+
[bool]$InitialForrestConnection = $false
2929
)
3030

3131
if ((-not $Options.WinRMFallbackToNoSSL) -and ($PSSTable.Value | Where-Object { $_.DCName -eq $ComputerName -and $_.Status -eq 'Offline' -and $_.Protocol -eq 'PSSessionSSL' })) {
@@ -85,13 +85,17 @@ function Get-ValidPSSession {
8585
return $SessionObject
8686
}
8787
} catch {
88-
Write-PScriboMessage -Message "Unable to Connect to '$ComputerName' through PSSession."
8988
$PSSTable.Value += @{
9089
DCName = $ComputerName
9190
Status = 'Offline'
9291
Protocol = 'PSSession'
9392
Id = 'None'
9493
}
94+
if ($InitialForrestConnection) {
95+
throw "Unable to Connect to '$ComputerName' through PSSession. Error details: $($_.Exception.Message)"
96+
} else {
97+
Write-PScriboMessage -Message "Unable to Connect to '$ComputerName' through PSSession."
98+
}
9599
}
96100
}
97101
} else {
@@ -118,13 +122,17 @@ function Get-ValidPSSession {
118122
return $SessionObject
119123
}
120124
} catch {
121-
Write-PScriboMessage -Message "Unable to Connect to '$ComputerName' through PSSession."
122125
$PSSTable.Value += @{
123126
DCName = $ComputerName
124127
Status = 'Offline'
125128
Protocol = 'PSSession'
126129
Id = 'None'
127130
}
131+
if ($InitialForrestConnection) {
132+
throw "Unable to Connect to '$ComputerName' through PSSession. Error details: $($_.Exception.Message)"
133+
} else {
134+
Write-PScriboMessage -Message "Unable to Connect to '$ComputerName' through PSSession."
135+
}
128136
}
129137
}
130138
}

Src/Private/Get-WinADDFSHealth.ps1

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ function Get-WinADDFSHealth {
2121
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
2222
[alias('DomainControllers')][string[]] $IncludeDomainControllers,
2323
[switch] $SkipRODC,
24-
[int] $EventDays = 1,
2524
[switch] $SkipGPO,
2625
[switch] $SkipAutodetection,
2726
[System.Collections.IDictionary] $ExtendedForestInformation,
2827
[pscredential] $Credential
2928
)
30-
$Today = (Get-Date)
31-
$Yesterday = (Get-Date -Hour 0 -Second 0 -Minute 0 -Millisecond 0).AddDays(-$EventDays)
3229

3330
if (-not $SkipAutodetection) {
3431
$ForestInformation = Get-WinADForestDetail -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended -Credential $Credential

Src/Private/Get-WinADDuplicateObject.ps1

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,48 +42,48 @@ function Get-WinADDuplicateObject {
4242
Credential = $Credential
4343
}
4444
$Objects = Get-ADObject @getADObjectSplat
45-
foreach ($_ in $Objects) {
45+
foreach ($Object in $Objects) {
4646
# Lets allow users to filter on it
4747
if ($ExcludeObjectClass) {
48-
if ($ExcludeObjectClass -contains $_.ObjectClass) {
48+
if ($ExcludeObjectClass -contains $Object.ObjectClass) {
4949
continue
5050
}
5151
}
5252
if ($IncludeObjectClass) {
53-
if ($IncludeObjectClass -notcontains $_.ObjectClass) {
53+
if ($IncludeObjectClass -notcontains $Object.ObjectClass) {
5454
continue
5555
}
5656
}
5757
if ($PartialMatchDistinguishedName) {
58-
if ($_.DistinguishedName -notlike $PartialMatchDistinguishedName) {
58+
if ($Object.DistinguishedName -notlike $PartialMatchDistinguishedName) {
5959
continue
6060
}
6161
}
6262
if ($NoPostProcessing) {
63-
$_
63+
$Object
6464
continue
6565
}
66-
$DomainName = ConvertFrom-DistinguishedName -DistinguishedName $_.DistinguishedName -ToDomainCN
66+
$DomainName = ConvertFrom-DistinguishedName -DistinguishedName $Object.DistinguishedName -ToDomainCN
6767
# Lets create separate objects for different purpoeses
6868
$ConflictObject = [ordered] @{
69-
ConflictDN = $_.DistinguishedName
70-
ConflictWhenChanged = $_.WhenChanged
69+
ConflictDN = $Object.DistinguishedName
70+
ConflictWhenChanged = $Object.WhenChanged
7171
DomainName = $DomainName
72-
ObjectClass = $_.ObjectClass
72+
ObjectClass = $Object.ObjectClass
7373
}
7474
$LiveObjectData = [ordered] @{
7575
LiveDn = "N/A"
7676
LiveWhenChanged = "N/A"
7777
}
7878
$RestData = [ordered] @{
79-
DisplayName = $_.DisplayName
80-
Name = $_.Name.Replace("`n", ' ')
81-
SamAccountName = $_.SamAccountName
82-
ObjectCategory = $_.ObjectCategory
83-
WhenCreated = $_.WhenCreated
84-
WhenChanged = $_.WhenChanged
85-
ProtectedFromAccidentalDeletion = $_.ProtectedFromAccidentalDeletion
86-
ObjectGUID = $_.ObjectGUID.Guid
79+
DisplayName = $Object.DisplayName
80+
Name = $Object.Name.Replace("`n", ' ')
81+
SamAccountName = $Object.SamAccountName
82+
ObjectCategory = $Object.ObjectCategory
83+
WhenCreated = $Object.WhenCreated
84+
WhenChanged = $Object.WhenChanged
85+
ProtectedFromAccidentalDeletion = $Object.ProtectedFromAccidentalDeletion
86+
ObjectGUID = $Object.ObjectGUID.Guid
8787
}
8888
if ($Extended) {
8989
$LiveObject = $null

Src/Private/Get-WinADForestDetail.ps1

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -278,22 +278,22 @@ function Get-WinADForestDetail {
278278
# this makes sure we ask once for all AD stuff and then subsequent calls just filter out things
279279
# this should be much faster then asking again and again for stuff from AD
280280
$Findings = Copy-DictionaryManual -Dictionary $ExtendedForestInformation
281-
[Array] $Findings['Domains'] = foreach ($_ in $Findings.Domains) {
281+
[Array] $Findings['Domains'] = foreach ($Dom in $Findings.Domains) {
282282
if ($IncludeDomains) {
283-
if ($_ -in $IncludeDomains) {
284-
$_.ToLower()
283+
if ($Dom -in $IncludeDomains) {
284+
$Dom.ToLower()
285285
}
286286
# We skip checking for exclusions
287287
continue
288288
}
289-
if ($_ -notin $ExcludeDomains) {
290-
$_.ToLower()
289+
if ($Dom -notin $ExcludeDomains) {
290+
$Dom.ToLower()
291291
}
292292
}
293293
# Now that we have Domains we need to remove all DCs that are not from domains we excluded or included
294-
foreach ($_ in [string[]] $Findings.DomainDomainControllers.Keys) {
295-
if ($_ -notin $Findings.Domains) {
296-
$Findings.DomainDomainControllers.Remove($_)
294+
foreach ($DCkey in [string[]] $Findings.DomainDomainControllers.Keys) {
295+
if ($DCkey -notin $Findings.Domains) {
296+
$Findings.DomainDomainControllers.Remove($DCkey)
297297
}
298298
}
299299
# Same as above but for query servers - we don't remove queried servers
@@ -303,10 +303,10 @@ function Get-WinADForestDetail {
303303
# }
304304
#}
305305
# Now that we have Domains we need to remove all Domains that are excluded or included
306-
foreach ($_ in [string[]] $Findings.DomainsExtended.Keys) {
307-
if ($_ -notin $Findings.Domains) {
308-
$Findings.DomainsExtended.Remove($_)
309-
$NetBiosName = $Findings.DomainsExtended.$_.'NetBIOSName'
306+
foreach ($DomainExtendedKey in [string[]] $Findings.DomainsExtended.Keys) {
307+
if ($DomainExtendedKey -notin $Findings.Domains) {
308+
$Findings.DomainsExtended.Remove($DomainExtendedKey)
309+
$NetBiosName = $Findings.DomainsExtended.$DomainExtendedKey.'NetBIOSName'
310310
if ($NetBiosName) {
311311
$Findings.DomainsExtendedNetBIOS.Remove($NetBiosName)
312312
}

0 commit comments

Comments
 (0)