Thursday, February 17, 2011

Extension to Windows Audit: Expand lists of groups against domain

This script takes input from the Windows auditing script on this site (the one that extracts from SYDI-Server XML into CSV, or the Powershell script on this site that audits servers using ADSI interface rather than WMI)

The input must be CSV format and have the following headers: -

"Server","User","DisplayName","Memberof","HPA","AccountCode","AccessGroups","Status"

Server: The name of the server where the users/groups were extracted from. This is not used in the script however it is written back to the output as is.

User: Either a user or group name. Script will check determine if a local user/group or a domain user/group. If it is a domain group then it will be recursed to determine all members of this domain group including all nested groups. The aim is to expand out all groups and so this column should only contain users after running the script.

Displayname: The display name of all domain users will be returned in this column.

Memberof: The trail through which each user is a member of the group originally specified in the "User" column.

HPA: not used in this script - can be used to note whether each user is HPA highly privileged access).

AccountCode: not used in this script. Can be used to put a code against each user account.

AccessGroups: Name of group that was expanded out. This column may or may not be useful.

Status: If "Local" then the user/group is a local user/group. If "Direct" then user is a domain user that is directly a member of the local group on the server. If "Expanded User" then user is a member of domain groups that are a member of the local group on the server. If "ForeignPrincipal" then an expanded security object is a place holder - an object from another domain and cannot be further expanded by this script. If "Non AD" then the domain could not findan object with the specified name. You may need to run the script against the output in another domain in order to expand out this object.

The script can be run against its own output as many times as required. This allows the script to be run in multiple domains and thus fully expanding out all group memberships within a list.





$grouphash = @{}
function Get-RecursiveGroupMembership {
param (
[string] $groupname,
[string] $lastname
)
$members = @()

if($grouphash[$groupname] -eq $null)
{
#$grouphash[$line.User] = Get-QADGroupMember $line.User -Indirect | Select-Object NTAccountName | foreach {$_.NTAccountName}
$this = (Get-QADGroup $groupname).member | Get-QADObject | Select-Object NTAccountName, type, displayName
}
$this = $grouphash[$groupname]
$this = (Get-QADGroup $groupname).member | Get-QADObject | Select-Object NTAccountName, type, displayName
$this | foreach {
if ($_.type -eq 'user') {
$mem ="" | Select-Object name, grp, type, displayname;
$mem.name = $_.NTAccountName
$mem.grp = $lastname
$mem.type = "Expanded User"
$mem.displayname = $_.displayName
$members = $members + $mem
#$members += @('"'+$_.NTAccountName+'"' , '"'+$lastname+'"')
}
elseif ($_.type -eq 'computer') {
$mem ="" | Select-Object name, grp, type, displayname;
$mem.name = $_.NTAccountName
$mem.grp = $lastname
$mem.type = "Expanded User"
$mem.displayname = ""
$members = $members + $mem
#$members += @('"'+$_.NTAccountName+'"' , '"'+$lastname+'"')
}
elseif ($_.type -eq 'group') {
$newlastname = $lastname + ':' + $_.NTAccountName
#Write-Host "Adding sub group $_" + $newlastname

$members += Get-RecursiveGroupMembership $_.NTAccountName $newlastname
}
else {#Probably Foreign Security Principal - should note as such
$mem ="" | Select-Object name, grp, type, displayName;
$mem.name = $_.NTAccountName
$mem.grp = $lastname
$mem.type = "ForeignSecurityPrincipal"
$mem.displayname = ""
$members = $members + $mem

}
}
return $members
}
cls

Add-PSSnapin Quest.ActiveRoles.ADManagement –ErrorAction SilentlyContinue

$csvin = Import-Csv info.csv | where-Object {$_.HPA -eq "Yes"}

connect-QADService



try{
'"Server","User","DisplayName","Memberof","HPA","AccountCode","AccessGroups","Status"' | Out-File -filepath "infoOut.csv"
} catch [System.Management.Automation.Host.PromptingException]
{
return
} catch [Exception]
{
Write-Host "Error!!!"
return
}

#$myobj = "" | select "Server","User","DisplayName","Memberof","HPA","AccountCode","AccessGroups","Status"

foreach($line in $csvin)
{
if($line.HPA -ne "Yes")
{
continue
}

$user = $line.User.Split('\')

if($user[0] -eq $line.Server)
{
"Local User: " + $line.User
'"'+$line.Server +'","'+ $line.User + '","' + $line.DisplayName + '","Administrators","Yes","","","Local"' | Out-File -filepath "infoOut.csv" -Append
continue
}

$ret = Get-QADObject $line.User
if($ret -ne $null)
{
if($ret.ClassName -eq "group")
{
# "Good User: " + $line.User
# if($grouphash[$line.User] -eq $null)
# {
# "Getting Group Users"
# $grouphash[$line.User] = Get-QADGroupMember $line.User -Indirect | Select-Object NTAccountName | foreach {$_.NTAccountName}
# }
$membersout = Get-RecursiveGroupMembership $line.User $line.User

foreach($mem in $membersout )
{
#'"Server","User","Member of","HPA","Account Code","Access Groups","Status"' | Out-File -filepath "infoOut.csv"
'"'+$line.Server +'","'+ $mem.name + '","' + $mem.displayName + '","'+$mem.grp +'","Yes","","'+ $line.User +'","' + $mem.type + '"' | Out-File -filepath "infoOut.csv" -Append
}

} elseif($ret.ClassName -eq "user") {
'"'+$line.Server +'","'+ $line.User + '","' + $ret.displayName + '","Administrators","Yes","","","Direct"' | Out-File -filepath "infoOut.csv" -Append

} else
{
'"'+$line.Server +'","'+ $line.User + '","","Administrators","Yes","","","Direct-Foreign"' | Out-File -filepath "infoOut.csv" -Append
}
} elseif ($line.status -eq "Expanded User") {
"Previously expanded user: " + $line.User
'"'+$line.Server +'","'+ $line.User + '","' + $line.Displayname + '","'+ $line.Memberof + '","Yes"," ","' + $line.AccessGroups + '" , "' + $line.status + '"' | Out-File -filepath "infoOut.csv" -Append

} elseif ($line.status -eq "Direct") {
"Previously Direct User: " + $line.User
'"'+$line.Server +'","'+ $line.User +'","' + $line.Displayname + '","' + $line.Memberof + '","Yes"," ","' + $line.AccessGroups + '","' + $line.status + '"' | Out-File -filepath "infoOut.csv" -Append

} else
{
"Non Ad User: " + $line.User
'"'+$line.Server +'" , "'+ $line.User + '","' + $line.Displayname + '","Administrators" , "Yes" ,"","","NON AD"' | Out-File -filepath "infoOut.csv" -Append
}
$ret = $null
}
Disconnect-QADService
$kv = @()
foreach($hk in $grouphash.Keys)
{
foreach($st in $grouphash[$hk])
{
$obnew = New-Object System.Object
$obnew | Add-Member -MemberType NoteProperty -Name Group -Value $hk
$obnew | Add-Member -MemberType NoteProperty -Name Member -Value $st
$kv += $obnew
}
}

No comments:

Post a Comment