Skip to content
This repository was archived by the owner on Jan 21, 2021. It is now read-only.

Commit 6789187

Browse files
committed
Get-DomainPolicyData now returns proper object output instead of hashtable.
Modified Get-IniContent and Get-GptTmpl to accept '-OutputObject' to output a PSObject instead of a hashtable
1 parent d12e151 commit 6789187

File tree

1 file changed

+92
-53
lines changed

1 file changed

+92
-53
lines changed

Recon/PowerView.ps1

Lines changed: 92 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,10 @@ is parsed, and then the connection is destroyed with Remove-RemoteConnection.
752752

753753
Specifies the path to the .ini file to parse.
754754

755+
.PARAMETER OutputObject
756+
757+
Switch. Output a custom PSObject instead of a hashtable.
758+
755759
.PARAMETER Credential
756760

757761
A [Management.Automation.PSCredential] object of alternate credentials
@@ -763,6 +767,12 @@ Get-IniContent C:\Windows\example.ini
763767

764768
.EXAMPLE
765769

770+
"C:\Windows\example.ini" | Get-IniContent -OutputObject
771+
772+
Outputs the .ini details as a proper nested PSObject.
773+
774+
.EXAMPLE
775+
766776
"C:\Windows\example.ini" | Get-IniContent
767777

768778
.EXAMPLE
@@ -800,7 +810,10 @@ https://blogs.technet.microsoft.com/heyscriptingguy/2011/08/20/use-powershell-to
800810

801811
[Management.Automation.PSCredential]
802812
[Management.Automation.CredentialAttribute()]
803-
$Credential = [Management.Automation.PSCredential]::Empty
813+
$Credential = [Management.Automation.PSCredential]::Empty,
814+
815+
[Switch]
816+
$OutputObject
804817
)
805818

806819
BEGIN {
@@ -819,28 +832,54 @@ https://blogs.technet.microsoft.com/heyscriptingguy/2011/08/20/use-powershell-to
819832
}
820833

821834
if (Test-Path -Path $TargetPath) {
822-
$IniObject = @{}
835+
if ($PSBoundParameters['OutputObject']) {
836+
$IniObject = New-Object PSObject
837+
}
838+
else {
839+
$IniObject = @{}
840+
}
823841
Switch -Regex -File $TargetPath {
824842
"^\[(.+)\]" # Section
825843
{
826844
$Section = $matches[1].Trim()
827-
$IniObject[$Section] = @{}
845+
if ($PSBoundParameters['OutputObject']) {
846+
$Section = $Section.Replace(' ', '')
847+
$SectionObject = New-Object PSObject
848+
$IniObject | Add-Member Noteproperty $Section $SectionObject
849+
}
850+
else {
851+
$IniObject[$Section] = @{}
852+
}
828853
$CommentCount = 0
829854
}
830855
"^(;.*)$" # Comment
831856
{
832857
$Value = $matches[1].Trim()
833858
$CommentCount = $CommentCount + 1
834859
$Name = 'Comment' + $CommentCount
835-
$IniObject[$Section][$Name] = $Value
860+
if ($PSBoundParameters['OutputObject']) {
861+
$Name = $Name.Replace(' ', '')
862+
$IniObject.$Section | Add-Member Noteproperty $Name $Value
863+
}
864+
else {
865+
$IniObject[$Section][$Name] = $Value
866+
}
836867
}
837868
"(.+?)\s*=(.*)" # Key
838869
{
839870
$Name, $Value = $matches[1..2]
840871
$Name = $Name.Trim()
841872
$Values = $Value.split(',') | ForEach-Object { $_.Trim() }
842-
if ($Values -isnot [System.Array]) { $Values = @($Values) }
843-
$IniObject[$Section][$Name] = $Values
873+
874+
# if ($Values -isnot [System.Array]) { $Values = @($Values) }
875+
876+
if ($PSBoundParameters['OutputObject']) {
877+
$Name = $Name.Replace(' ', '')
878+
$IniObject.$Section | Add-Member Noteproperty $Name $Values
879+
}
880+
else {
881+
$IniObject[$Section][$Name] = $Values
882+
}
844883
}
845884
}
846885
$IniObject
@@ -6601,12 +6640,12 @@ System.Security.AccessControl.AuthorizationRule
66016640
[Alias('DistinguishedName', 'SamAccountName', 'Name')]
66026641
[String]
66036642
$PrincipalIdentity,
6604-
6605-
[ValidateNotNullOrEmpty()]
6643+
6644+
[ValidateNotNullOrEmpty()]
66066645
[String]
66076646
$PrincipalDomain,
66086647

6609-
[ValidateNotNullOrEmpty()]
6648+
[ValidateNotNullOrEmpty()]
66106649
[Alias('DomainController')]
66116650
[String]
66126651
$Server,
@@ -6625,8 +6664,8 @@ System.Security.AccessControl.AuthorizationRule
66256664

66266665
[Switch]
66276666
$Tombstone,
6628-
6629-
[Management.Automation.PSCredential]
6667+
6668+
[Management.Automation.PSCredential]
66306669
[Management.Automation.CredentialAttribute()]
66316670
$Credential = [Management.Automation.PSCredential]::Empty,
66326671

@@ -6688,7 +6727,7 @@ System.Security.AccessControl.AuthorizationRule
66886727

66896728
Process {
66906729
if($PSCmdlet.ParameterSetName -eq 'AuditRuleType') {
6691-
6730+
66926731
if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
66936732
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag
66946733
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
@@ -6703,8 +6742,9 @@ System.Security.AccessControl.AuthorizationRule
67036742
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType, $InheritanceType, $InheritedObjectType
67046743
}
67056744

6706-
} else {
6707-
6745+
}
6746+
else {
6747+
67086748
if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
67096749
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType
67106750
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
@@ -10699,6 +10739,10 @@ the files are parsed, and the connection is destroyed later with Remove-RemoteCo
1069910739

1070010740
Specifies the GptTmpl.inf file path name to parse.
1070110741

10742+
.PARAMETER OutputObject
10743+
10744+
Switch. Output a custom PSObject instead of a hashtable.
10745+
1070210746
.PARAMETER Credential
1070310747

1070410748
A [Management.Automation.PSCredential] object of alternate credentials
@@ -10740,6 +10784,9 @@ Ouputs a hashtable representing the parsed GptTmpl.inf file.
1074010784
[String]
1074110785
$GptTmplPath,
1074210786

10787+
[Switch]
10788+
$OutputObject,
10789+
1074310790
[Management.Automation.PSCredential]
1074410791
[Management.Automation.CredentialAttribute()]
1074510792
$Credential = [Management.Automation.PSCredential]::Empty
@@ -10766,9 +10813,21 @@ Ouputs a hashtable representing the parsed GptTmpl.inf file.
1076610813
}
1076710814

1076810815
Write-Verbose "[Get-GptTmpl] Parsing GptTmplPath: $TargetGptTmplPath"
10769-
$Contents = Get-IniContent -Path $TargetGptTmplPath -ErrorAction Stop
10770-
$Contents['Path'] = $TargetGptTmplPath
10771-
$Contents
10816+
10817+
if ($PSBoundParameters['OutputObject']) {
10818+
$Contents = Get-IniContent -Path $TargetGptTmplPath -OutputObject -ErrorAction Stop
10819+
if ($Contents) {
10820+
$Contents | Add-Member Noteproperty 'Path' $TargetGptTmplPath
10821+
$Contents
10822+
}
10823+
}
10824+
else {
10825+
$Contents = Get-IniContent -Path $TargetGptTmplPath -ErrorAction Stop
10826+
if ($Contents) {
10827+
$Contents['Path'] = $TargetGptTmplPath
10828+
$Contents
10829+
}
10830+
}
1077210831
}
1077310832
catch {
1077410833
Write-Verbose "[Get-GptTmpl] Error parsing $TargetGptTmplPath : $_"
@@ -12216,8 +12275,8 @@ The domain to query for default policies, defaults to the current domain.
1221612275

1221712276
.PARAMETER Policy
1221812277

12219-
Extract 'Domain' or 'DC' (domain controller) policies, otherwise queries for the particular
12220-
GPO name or GUID.
12278+
Extract 'Domain', 'DC' (domain controller) policies, or 'All' for all policies.
12279+
Otherwise queries for the particular GPO name or GUID.
1222112280

1222212281
.PARAMETER Server
1222312282

@@ -12227,10 +12286,6 @@ Specifies an Active Directory server (domain controller) to bind to.
1222712286

1222812287
Specifies the maximum amount of time the server spends searching. Default of 120 seconds.
1222912288

12230-
.PARAMETER ResolveSids
12231-
12232-
Switch. Resolve Sids from a DC policy to object names.
12233-
1223412289
.PARAMETER Credential
1223512290

1223612291
A [Management.Automation.PSCredential] object of alternate credentials
@@ -12252,7 +12307,7 @@ Returns the default domain policy for the dev.testlab.local domain.
1225212307

1225312308
Get-DomainGPO | Get-DomainPolicy
1225412309

12255-
Parses any GptTmpl.infs found for any policies.
12310+
Parses any GptTmpl.infs found for any policies in the current domain.
1225612311

1225712312
.EXAMPLE
1225812313

@@ -12295,9 +12350,6 @@ Ouputs a hashtable representing the parsed GptTmpl.inf file.
1229512350
[Int]
1229612351
$ServerTimeLimit,
1229712352

12298-
[Switch]
12299-
$ResolveSids,
12300-
1230112353
[Management.Automation.PSCredential]
1230212354
[Management.Automation.CredentialAttribute()]
1230312355
$Credential = [Management.Automation.PSCredential]::Empty
@@ -12320,7 +12372,10 @@ Ouputs a hashtable representing the parsed GptTmpl.inf file.
1232012372
$ConvertArguments['Domain'] = $Domain
1232112373
}
1232212374

12323-
if ($Policy -eq 'Domain') {
12375+
if ($Policy -eq 'All') {
12376+
$SearcherArguments['Identity'] = '*'
12377+
}
12378+
elseif ($Policy -eq 'Domain') {
1232412379
$SearcherArguments['Identity'] = '{31B2F340-016D-11D2-945F-00C04FB984F9}'
1232512380
}
1232612381
elseif (($Policy -eq 'DomainController') -or ($Policy -eq 'DC')) {
@@ -12330,39 +12385,23 @@ Ouputs a hashtable representing the parsed GptTmpl.inf file.
1233012385
$SearcherArguments['Identity'] = $Policy
1233112386
}
1233212387

12333-
$GPO = Get-DomainGPO @SearcherArguments
12388+
$GPOResults = Get-DomainGPO @SearcherArguments
1233412389

12335-
if ($GPO) {
12390+
ForEach ($GPO in $GPOResults) {
1233612391
# grab the GptTmpl.inf file and parse it
1233712392
$GptTmplPath = $GPO.gpcfilesyspath + "\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf"
1233812393

12339-
$ParseArgs = @{'GptTmplPath' = $GptTmplPath}
12394+
$ParseArgs = @{
12395+
'GptTmplPath' = $GptTmplPath
12396+
'OutputObject' = $True
12397+
}
1234012398
if ($PSBoundParameters['Credential']) { $ParseArgs['Credential'] = $Credential }
1234112399

1234212400
# parse the GptTmpl.inf
1234312401
Get-GptTmpl @ParseArgs | ForEach-Object {
12344-
if ($PSBoundParameters['ResolveSids']) {
12345-
$Root = $_
12346-
$PrivilegeRightsResovled = @{}
12347-
# if we're resolving sids in PrivilegeRights to names
12348-
if ($Root.'Privilege Rights') {
12349-
$PrivilegeRights = $Root.'Privilege Rights'
12350-
ForEach ($PrivilegeRight in $PrivilegeRights.Keys) {
12351-
$PrivilegeRightsResovled[$PrivilegeRight] = $PrivilegeRights."$PrivilegeRight" | ForEach-Object {
12352-
try {
12353-
$_ | ForEach-Object { ConvertFrom-SID -ObjectSid ($_.Trim('*')) @ConvertArguments }
12354-
}
12355-
catch {
12356-
Write-Verbose "[Get-DomainPolicy] Error resolving SID : $_"
12357-
$_
12358-
}
12359-
}
12360-
}
12361-
}
12362-
$Root.'Privilege Rights' = $PrivilegeRightsResovled
12363-
$Root
12364-
}
12365-
else { $_ }
12402+
$_ | Add-Member Noteproperty 'GPOName' $GPO.name
12403+
$_ | Add-Member Noteproperty 'GPODisplayName' $GPO.displayname
12404+
$_
1236612405
}
1236712406
}
1236812407
}

0 commit comments

Comments
 (0)