-fixed several bugs in Find-GPOLocation (-GroupName now works properly and Sites returned)

-Find-GPOLocation with no arguments now returns all mappings
-fixed parsing issue in Get-NetGPOGroup- names now properly extracted from restricted group templates
This commit is contained in:
Harmj0y 2016-02-28 22:30:22 -05:00
parent 6de1d78af8
commit 4aea2f12f9
1 changed files with 151 additions and 136 deletions

View File

@ -3586,6 +3586,9 @@ function Get-NetComputer {
[String] [String]
$ADSpath, $ADSpath,
[String]
$SiteName,
[Switch] [Switch]
$Unconstrained, $Unconstrained,
@ -3627,8 +3630,13 @@ function Get-NetComputer {
if($ServicePack) { if($ServicePack) {
$Filter += "(operatingsystemservicepack=$ServicePack)" $Filter += "(operatingsystemservicepack=$ServicePack)"
} }
if($SiteName) {
$Filter += "(serverreferencebl=$SiteName)"
}
$CompSearcher.filter = "(&(sAMAccountType=805306369)(dnshostname=$ComputerName)$Filter)" $CompFilter = "(&(sAMAccountType=805306369)(dnshostname=$ComputerName)$Filter)"
Write-Verbose "Get-NetComputer filter : '$CompFilter'"
$CompSearcher.filter = $CompFilter
try { try {
@ -5428,7 +5436,6 @@ function Get-GptTmpl {
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
[ValidateScript({Test-Path -Path $_ })]
[Parameter(Mandatory=$True, ValueFromPipeline=$True)] [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[String] [String]
$GptTmplPath, $GptTmplPath,
@ -5539,7 +5546,6 @@ function Get-GroupsXML {
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
[ValidateScript({Test-Path -Path $_ })]
[Parameter(Mandatory=$True, ValueFromPipeline=$True)] [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[String] [String]
$GroupsXMLPath, $GroupsXMLPath,
@ -5581,7 +5587,8 @@ function Get-GroupsXML {
process { process {
[xml] $GroupsXMLcontent = Get-Content $GroupsXMLPath try {
[xml] $GroupsXMLcontent = Get-Content $GroupsXMLPath -ErrorAction Stop
# process all group properties in the XML # process all group properties in the XML
$GroupsXMLcontent | Select-Xml "//Group" | Select-Object -ExpandProperty node | ForEach-Object { $GroupsXMLcontent | Select-Xml "//Group" | Select-Object -ExpandProperty node | ForEach-Object {
@ -5647,6 +5654,10 @@ function Get-GroupsXML {
} }
} }
} }
catch {
Write-Debug "Error parsing $GptTmplPath : $_"
}
}
end { end {
if($UsePSDrive -and $RandDrive) { if($UsePSDrive -and $RandDrive) {
@ -5849,12 +5860,24 @@ function Get-NetGPOGroup {
$Memberof = $Inf.GroupMembership | Get-Member *Memberof | ForEach-Object { $Inf.GroupMembership.($_.name) } | ForEach-Object { $_.trim('*') } $Memberof = $Inf.GroupMembership | Get-Member *Memberof | ForEach-Object { $Inf.GroupMembership.($_.name) } | ForEach-Object { $_.trim('*') }
$Members = $Inf.GroupMembership | Get-Member *Members | ForEach-Object { $Inf.GroupMembership.($_.name) } | ForEach-Object { $_.trim('*') } $Members = $Inf.GroupMembership | Get-Member *Members | ForEach-Object { $Inf.GroupMembership.($_.name) } | ForEach-Object { $_.trim('*') }
# only return an object if Members are found if(!$Members) {
if ($Members -or $Memberof) { try {
$MembersRaw = $Inf.GroupMembership | Get-Member *Members | Select-Object -ExpandProperty Name
$Members = ($MembersRaw -split "__")[0].trim("*")
}
catch {
$MembersRaw = ''
}
}
# if there is no Memberof defined, assume local admins
if(!$Memberof) { if(!$Memberof) {
$Memberof = 'S-1-5-32-544' try {
$MemberofRaw = $Inf.GroupMembership | Get-Member *Memberof | Select-Object -ExpandProperty Name
$Memberof = ($MemberofRaw -split "__")[0].trim("*")
}
catch {
$Memberof = ''
}
} }
if($ResolveSids) { if($ResolveSids) {
@ -5862,8 +5885,8 @@ function Get-NetGPOGroup {
$Members = $Members | ForEach-Object { Convert-SidToName $_ } $Members = $Members | ForEach-Object { Convert-SidToName $_ }
} }
if($Memberof -isnot [system.array]) {$Memberof = @($Memberof)} if($Memberof -isnot [System.Array]) {$Memberof = @($Memberof)}
if($Members -isnot [system.array]) {$Members = @($Members)} if($Members -isnot [System.Array]) {$Members = @($Members)}
$GPOProperties = @{ $GPOProperties = @{
'GPODisplayName' = $GPODisplayName 'GPODisplayName' = $GPODisplayName
@ -5876,7 +5899,6 @@ function Get-NetGPOGroup {
New-Object -TypeName PSObject -Property $GPOProperties New-Object -TypeName PSObject -Property $GPOProperties
} }
}
$ParseArgs = @{ $ParseArgs = @{
'GroupsXMLpath' = "$GPOPath\MACHINE\Preferences\Groups\Groups.xml" 'GroupsXMLpath' = "$GPOPath\MACHINE\Preferences\Groups\Groups.xml"
@ -6012,16 +6034,16 @@ function Find-GPOLocation {
$ObjectDistName = $Group.distinguishedname $ObjectDistName = $Group.distinguishedname
} }
else { else {
throw "-UserName or -GroupName must be specified!" $TargetSid = '*'
} }
if($LocalGroup -like "*Admin*") { if($LocalGroup -like "*Admin*") {
$LocalSID = "S-1-5-32-544" $LocalSID = 'S-1-5-32-544'
} }
elseif ( ($LocalGroup -like "*RDP*") -or ($LocalGroup -like "*Remote*") ) { elseif ( ($LocalGroup -like "*RDP*") -or ($LocalGroup -like "*Remote*") ) {
$LocalSID = "S-1-5-32-555" $LocalSID = 'S-1-5-32-555'
} }
elseif ($LocalGroup -like "S-1-5*") { elseif ($LocalGroup -like "S-1-5-*") {
$LocalSID = $LocalGroup $LocalSID = $LocalGroup
} }
else { else {
@ -6032,13 +6054,15 @@ function Find-GPOLocation {
Write-Verbose "TargetSid: $TargetSid" Write-Verbose "TargetSid: $TargetSid"
Write-Verbose "TargetObjectDistName: $ObjectDistName" Write-Verbose "TargetObjectDistName: $ObjectDistName"
if($TargetSid -isnot [system.array]) { $TargetSid = @($TargetSid) } if($TargetSid -ne '*') {
if($TargetSid -isnot [System.Array]) { $TargetSid = @($TargetSid) }
# use the tokenGroups approach from Get-NetGroup to get all effective # use the tokenGroups approach from Get-NetGroup to get all effective
# security SIDs this object is a part of # security SIDs this object is a part of
$TargetSid += Get-NetGroup -Domain $Domain -DomainController $DomainController -PageSize $PageSize -UserName $ObjectSamAccountName -RawSids $TargetSid += Get-NetGroup -Domain $Domain -DomainController $DomainController -PageSize $PageSize -UserName $ObjectSamAccountName -RawSids
if($TargetSid -isnot [system.array]) { $TargetSid = @($TargetSid) } if($TargetSid -isnot [System.Array]) { [System.Array]$TargetSid = [System.Array]@($TargetSid) }
}
Write-Verbose "Effective target sids: $TargetSid" Write-Verbose "Effective target sids: $TargetSid"
@ -6052,7 +6076,6 @@ function Find-GPOLocation {
# get all GPO groups, and filter on ones that match our target SID list # get all GPO groups, and filter on ones that match our target SID list
# and match the target local sid memberof list # and match the target local sid memberof list
$GPOgroups = Get-NetGPOGroup @GPOGroupArgs | ForEach-Object { $GPOgroups = Get-NetGPOGroup @GPOGroupArgs | ForEach-Object {
if ($_.members) { if ($_.members) {
$_.members = $_.members | Where-Object {$_} | ForEach-Object { $_.members = $_.members | Where-Object {$_} | ForEach-Object {
if($_ -match '^S-1-.*') { if($_ -match '^S-1-.*') {
@ -6062,28 +6085,22 @@ function Find-GPOLocation {
# if there are any plain group names, try to resolve them to sids # if there are any plain group names, try to resolve them to sids
(Convert-NameToSid -ObjectName $_ -Domain $Domain).SID (Convert-NameToSid -ObjectName $_ -Domain $Domain).SID
} }
} } | Sort-Object -Unique
# stop PowerShell 2.0's string stupid unboxing # stop PowerShell 2.0's string stupid unboxing
if($_.members -isnot [system.array]) { $_.members = @($_.members) } if($_.members -isnot [System.Array]) { $_.members = @($_.members) }
if($_.memberof -isnot [system.array]) { $_.memberof = @($_.memberof) } if($_.memberof -isnot [System.Array]) { $_.memberof = @($_.memberof) }
if($_.members) { # check if the memberof contains the sid of the local account we're searching for
try { Write-Verbose "memberof: $($_.memberof)"
# only return groups that contain a target sid
# TODO: fix stupid weird "-DifferenceObject" is null error
if( (Compare-Object -ReferenceObject $_.members -DifferenceObject $TargetSid -IncludeEqual -ExcludeDifferent) ) {
if ($_.memberof -contains $LocalSid) { if ($_.memberof -contains $LocalSid) {
# check if there's an overlap between the members field and the set of target sids
# if $TargetSid = *, then return all results
if ( ($TargetSid -eq '*') -or ($_.members | Where-Object {$_} | Where-Object { $TargetSid -Contains $_ })) {
$_ $_
} }
} }
} }
catch {
Write-Debug "Error comparing members and $TargetSid : $_"
}
}
}
} }
Write-Verbose "GPOgroups: $GPOgroups" Write-Verbose "GPOgroups: $GPOgroups"
@ -6093,12 +6110,13 @@ function Find-GPOLocation {
$GPOgroups | Where-Object {$_} | ForEach-Object { $GPOgroups | Where-Object {$_} | ForEach-Object {
$GPOguid = $_.GPOName $GPOguid = $_.GPOName
$GPOMembers = $_.Members
if( -not $ProcessedGUIDs[$GPOguid] ) { if( -not $ProcessedGUIDs[$GPOguid] ) {
$GPOname = $_.GPODisplayName $GPOname = $_.GPODisplayName
$Filters = $_.Filters $Filters = $_.Filters
# find any OUs that have this GUID applied # find any OUs that have this GUID applied and then retrieve any computers from the OU
Get-NetOU -Domain $Domain -DomainController $DomainController -GUID $GPOguid -FullData -PageSize $PageSize | ForEach-Object { Get-NetOU -Domain $Domain -DomainController $DomainController -GUID $GPOguid -FullData -PageSize $PageSize | ForEach-Object {
if($Filters) { if($Filters) {
@ -6112,6 +6130,11 @@ function Find-GPOLocation {
$OUComputers = Get-NetComputer -Domain $Domain -DomainController $DomainController -Credential $Credential -ADSpath $_.ADSpath -PageSize $PageSize $OUComputers = Get-NetComputer -Domain $Domain -DomainController $DomainController -Credential $Credential -ADSpath $_.ADSpath -PageSize $PageSize
} }
if(!$ObjectDistName) {
# if the * wildcard was used, set the ObjectDistName as the GPO member sid set
$ObjectDistName = $GPOMembers
}
$GPOLocation = New-Object PSObject $GPOLocation = New-Object PSObject
$GPOLocation | Add-Member Noteproperty 'ObjectName' $ObjectDistName $GPOLocation | Add-Member Noteproperty 'ObjectName' $ObjectDistName
$GPOLocation | Add-Member Noteproperty 'GPOname' $GPOname $GPOLocation | Add-Member Noteproperty 'GPOname' $GPOname
@ -6122,33 +6145,25 @@ function Find-GPOLocation {
} }
# find any sites that have this GUID applied # find any sites that have this GUID applied
# TODO: fix, this isn't the correct way to query computers from a site... Get-NetSite -Domain $Domain -DomainController $DomainController -GUID $GPOguid -PageSize $PageSize -FullData | Foreach-Object {
# Get-NetSite -GUID $GPOguid -FullData | Foreach-Object {
# if($Filters) {
# # filter for computer name/org unit if a filter is specified
# # TODO: handle other filters?
# $SiteComptuers = Get-NetComputer -ADSpath $_.ADSpath -FullData | ? {
# $_.adspath -match ($Filters.Value)
# } | Foreach-Object {$_.dnshostname}
# }
# else {
# $SiteComptuers = Get-NetComputer -ADSpath $_.ADSpath
# }
# $SiteComptuers = Get-NetComputer -ADSpath $_.ADSpath $AppliedSite = New-Object PSObject
# $out = New-Object PSObject $AppliedSite | Add-Member Noteproperty 'Object' $ObjectDistName
# $out | Add-Member Noteproperty 'Object' $ObjectDistName $AppliedSite | Add-Member Noteproperty 'GPOname' $GPOname
# $out | Add-Member Noteproperty 'GPOname' $GPOname $AppliedSite | Add-Member Noteproperty 'GPOguid' $GPOguid
# $out | Add-Member Noteproperty 'GPOguid' $GPOguid $AppliedSite | Add-Member Noteproperty 'ContainerName' $_.distinguishedname
# $out | Add-Member Noteproperty 'ContainerName' $_.distinguishedname $AppliedSite | Add-Member Noteproperty 'Computers' $_.siteobjectbl
# $out | Add-Member Noteproperty 'Computers' $OUComputers $AppliedSite
# $out }
# }
# mark off this GPO GUID so we don't process it again if there are dupes # mark off this GPO GUID so we don't process it again if there are dupes
$ProcessedGUIDs[$GPOguid] = $True $ProcessedGUIDs[$GPOguid] = $True
} }
} }
}
function Get-GPOUserMap {
} }
@ -6250,7 +6265,7 @@ function Find-GPOComputerAdmin {
$Computers = Get-NetComputer -ComputerName $ComputerName -Domain $Domain -DomainController $DomainController -FullData -PageSize $PageSize $Computers = Get-NetComputer -ComputerName $ComputerName -Domain $Domain -DomainController $DomainController -FullData -PageSize $PageSize
if(!$Computers) { if(!$Computers) {
throw "Computer $Computer in domain '$Domain' not found!" throw "Computer $ComputerName in domain '$Domain' not found! Try a fully qualified host name"
} }
ForEach($Computer in $Computers) { ForEach($Computer in $Computers) {