Searching AD Groups attached to specified Server - powershell

I'm looking to use powershell, specify a server hostname, and have it display all the AD Groups that have access to that server. From there I'll dig into the groups eventually getting the usernames and storing them in a csv file.
So far I have the code to get the DN of the server -
Get-adcomputer HOSTNAME | select DistinguishedName
Along with having the code to get the eventual usernames and store them in a csv -
$groups= GROUPS
$selectgroups=$groups |Get-Adgroup
$selectgroups |get-adgroupmember -Recursive | Select samaccountname |
Export-csv -path C:\Groups\Members.csv -NoTypeInformation
My problem is I can't figure out how to get powershell to query what groups are on the server I specify. Is this possible or will I have to look at another way of doing this?
Thanks.

Not sure you know exactly what you're looking for. There's no way to tell which AD groups have been granted access to a node via AD. The only thing you can do is look on the local node for AD groups, but there's a lot of places you could want/need to look as Frode F. mentioned already. A common theme would be which AD groups have been added to LOCAL groups on the node in question.
You could use WMI or the ADSI adapter for this information. An ADSI example to get all members of the 'Administrators' local group for server 'NODE123':
$server = "NODE123"
$arrGroupMembers=#()
$Group = "Administrators"
$ADSIComputer = [ADSI]("WinNT://" + $server + ",computer")
$ADSIGroup = $ADSIcomputer.psbase.children.find($Group)
$ADSIMembers= $ADSIGroup.psbase.invoke("Members")
foreach ($member in $ADSIMembers) {
$MemberClass = $member.GetType().InvokeMember("Class", 'GetProperty', $Null, $member, $Null)
if ($memberClass -eq "Group") {
$MemberName = $member.GetType().InvokeMember("Name", 'GetProperty', $Null, $member, $Null)
$arrGroupMembers+=$MemberName
}
}
With the array return above, you now have all groups that have access to NODE123 via being added to the local Administrators group. Maybe this example helps you.

Related

MS Graph API - Group & membership info

I'm trying to pull out a listing of all groups in our Azure Active Directory org along with all the associated members (be them users, groups, contacts, etc).
Since I was unable to locate a method to do this through the various Microsoft portals with a simple export button I began the process of obtaining access to the Microsoft Graph API/SDK via Powershell.
I'm by no means a PowerShell expert as it's not one of my go-to scripts; however, from what I can tell the ability to pull group info in this fashion is fairly limited.
The following is what I've been able to accomplish thus far:
Pull in a list of the groups using Get-MgGroup -All
Use Get-MgGroupMembers to pull back a list of Directory Objects.
This is where I get stuck. From what I've read it looks like a Directory Object by default only returns the ID and the Deleted Date. I'd like to get a display Name for these objects; I can obviously do this by running the appropriate 'Get' cmdlet for the type of directory object (i.e. Get-MgUser); From what I can tell the type of directory object can't be gleaned via PowerShell with out 'trial-and-error'... This seems highly inefficient to simply get a displayName.
Is there a more effective way to determine either the displayName of a Directory Object via a PowerShell cmdlet or at the very least a type so I can write a case statement to run the right cmdlet on the first try?
For the record this is going to be incorporated in to a Powershell Script, the current iteration of which looks like this and sorta works okay... assuming the Id passed in $member.Id belongs to a User type directory object.
Connect-MgGraph
$groups=Get-mgGroup -All
ForEach ($group in $groups){
$members = #{}
$members = Get-MgGroupMember -GroupId $group.Id -All
ForEach ($member in $members){
$user = Get-MgUser $member.Id
Write-Output $object.ODataType
Write-output $group.DisplayName "," $member.Id "," $user.UserType"," $user.DisplayName "," $user.UserPrincipalName "," $user.Mail >> C:scripts\Azure_Groups.txt
}
}
Would appreciate any direction/assistance on this. Thanks in advance!
Not sure why its not returning all the details on the PowerShell query:
This is working fine in MS Graph Explorer with the results showing all the details of the members:
For more details:https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-1.0&tabs=http#example-1-get-the-direct-membership-in-a-group

Count AD group members with certain properties

I need a PowerShell script to count the members of an AD group that have the extensionAttribute4 property equal to o365_facstaff.
I’ve been using the following script to count all members of the group but I specifically need just the ones with the property:
$ADInfo = Get-AdGroup -Identity ‘<group name>’ -Properties Members
$ADInfo.Members.Count
We can get this information from AD with a single -Filter query on Get-ADUser:
# We'll need the group DN instead of the group name
# Here's an example
$groupDn = 'CN=test_group,CN=Users,DC=bender,DC=net'
# Get all ADUsers member of the target group with the specific
$groupMembers = Get-ADUser -Filter "(memberOf -RecursiveMatch '$groupDn') -and (extensionAttribute4 -eq 'o365_facstaff')"
# Check the Count property like you would with any array
$groupMembers.Count
Alternatively, as also mentioned in the comments, you can get the group members off of the ADGroup and further filter, though this results in additional unnecessary local processing. This can become problematic with very large groups, especially if your ADDS infrastructure runs closer to the minimum system requirements:
# Using $ADInfo from your code sample
$membersWithfacstaff = $ADInfo.Members | Where-Object {
( Get-ADUser $_ -Properties extensionAttribute4 ).extensionAttribute4 -eq 'o365_facstaff'
}
# Use the Count property
$facstaff.Count
As also mentioned in the comments, Measure-Command will give you the count too but is a bit redundant here, considering you'd have to reference the Count property anyways if you want to use it programmatically.
See this answer of mine for more information on effectively using the -Filter parameter on the RSAT AD cmdlets.

how to take users off ad groups user is part of

We are trying to take user off all ad groups when user is termed in HR Database. I have the termination of user account figured out but how can we take that specific user our of all assigned group using powershell.
You will want to retrieve the ADUser object before deleting it from ActiveDirectory, examine its .MemberOf property, and then run through those groups with the Remove-ADGroupMember cmdlet.
To get you started you need to get the user's memberOf and the user's distinguishedName
In the following example I am getting the user by their logon name (samaccountname) You can use whatever attribute you want as long as it returns the correct user:
$testUser = "Test User"
$user = Get-ADUser -filter {Samaccountname -eq $testUser} -Properties memberof, distinguishedName
$Groups = $user.MemberOf
$DN = $user.DistinguishedName
Then in order to remove the user from their current membership, you can just put it in a foreach:
foreach($group in $groups)
{
Remove-ADGroupMember -Members $DN -Identity $group -Confirm:$false
}
The -Confirm:$false is to suppress the warning about removal. You might want to remove that part during testing
Many will tell you to look at the user's memberOf attribute. That will work just fine in most cases.
However, memberOf only shows groups with a scope of 'Universal' on any domain in the forest, or 'Global' groups on the same domain. It will not show groups with a 'Domain Local' scope (regardless of domain), or 'Global' groups on other domains.
To guarantee you find all groups the user is a member of, you need to search every domain in your forest for groups that the user is a member of:
Import-Module ActiveDirectory
$user = Get-ADUser "theuser"
$domains = (Get-ADForest).Domains
$groups = New-Object System.Collections.ArrayList
foreach ($domain in $domains) {
$groups.AddRange(#(Get-ADGroup -filter {member -eq $user.DistinguishedName} -Server $domain))
}
Then $groups has the list of groups, and you can use Remove-ADGroupMember to remove the user from those groups.
Again, this is only relevant to you if you either:
Have more than one domain in your forest, and/or
Use 'Domain Local' groups

How to extract a list of users with rights to create domain users in the Active Directory?

I was tasked with creating Powershell scripts that we will use to review the Active Directory of our clients. I like to add that my knowledge of Powershell is very basic, but I've found A LOT online (including many Stack Overflow topics!) to help me with this task. My script is pretty much in place, but there is one functionality that I would like to add to my script. I do not know if (and how) this even possible. I've looked at many sites to help me with this issue, but I did not find any solutions. So I decided to ask it to the community itself. Here is a description of my issue.
What I want is to have a list of users that have the rights to create Domain Users and have the rights to install Updates / Hot-Fixes on Domain Controllers. In order to be able to create a Domain User, the user must have a membership (or equivalent) to Domain Administrators (Found here https://technet.microsoft.com/en-us/library/dd894463(v=ws.10).aspx. It's easy to get the Domain Administrators and Enterprise Administrators (the latter having also the ability to create Domain Users obviously). I have a script that retrieves all the Domain Users and the groups that they have membership to, so that is covered.
What I want to achieve is to get Domain Users that are not a member of the Domain Administrators (or equivalent) groups that have rights to create Domain Users (or within certain OU's like explained in this topic https://serverfault.com/questions/83686/how-to-create-a-limited-domain-admin-that-does-not-have-access-to-domain-contr).
There is not an attribute that defines what I am looking for. I had some ideas of using de 'admincount' property like this: Get-ADUser -Server $ADServer -Filter {admincount -gt 0}. This returns to me all the ADUsers that are within the Default Protected Groups within the Active Directory. But what I want is to be able to get Users that are not contained in these groups.
Is there a way to get this information?
Sorry I began fully coding this but without seeing your script and not having a full test AD env in front of me at the moment, I will give you the psudo-code as it seems like you've done enough that you can probably take this code and run with it and pretty easily have a fully working script since most the primary commands/filters needed I have included below:
Get a list of all OUs
$OUs = #(Get-ADDomain | Select-Object -ExpandProperty DistinguishedName)
$OUs += Get-ADOrganizationalUnit -Filter * | Select-Object -ExpandProperty DistinguishedName
$OUs += Get-ADObject -SearchBase (Get-ADDomain).DistinguishedName -SearchScope OneLevel -LDAPFilter '(objectClass=container)' | Select-Object -ExpandProperty DistinguishedName
Get a filtered list of all non-admin users using:
Get-ADUser -Server $ADServer -Filter { admincount -eq 0 }
Loop through each of the OUs and retrieve their permissions
foreach ($OU in $OUs)
(Get-Acl $OU).access | where { accesscontroltype -eq 'Allow' })
Inner loop your filtered non-admin user array with each access permission needed to perform the pseudo-admin duties using:
foreach ($objUser in $(Get-ADUser -Server $ADServer -Filter { admincount -eq 0 }))
(Get-Acl $OU).access | where { identityreference -eq <TRIMMED INNER LOOP USER OBJECT NAME FROM $objUser> }
If matched, add to new array, otherwise do nothing
Dump array to report

Finding a User on one of many domains

I am trying to get a script running but I keep running across the same issue, I have domains A, B, and C all in the same forest; but when I try to do simple commands such as
Disable-ADAccount -Identity $User
I am not able to get it to complete because it can't find the user in Domain B, which the user is in Domain A.
So the question, is there a way to get a script to check all domains (A, B, C) for "User1" and preform the disable action on them. (Other than setting the Switch)
-server
I ran into this issue recently, and ended up writing a function to get a user's ADUser object. You could use that object to disable the user easily enough.
Function Get-DomainUser{
Param([String]$Alias)
BEGIN{$GCs = Get-ADForest|select -expand GlobalCatalogs|?{($_ -match "^(.*?)\.(.+?)$")}|%{[pscustomobject]#{'Server' = $matches[1];'Region' = $matches[2];'FQDN' = $_}}|group region|%{$_.group|select -first 1}
}
PROCESS{
$DomUser = Get-ADUser -Filter {samAccountName -eq $Alias} -Prop DisplayName
If(([string]::IsNullOrEmpty($DomUser.Name))){
ForEach($GC in $GCs){
$DomUser = Get-ADUser -Filter {samAccountName -eq $Alias} -Server $GC.FQDN -Prop DisplayName
If(!([string]::IsNullOrEmpty($DomUser.Name))){Break}
}
}
$DomUser
}
}
This gets a list of global catalog servers, groups them by sites, then gets only 1 server per site. Then it tries to get the user, and if it fails for the current user then it tries each site until it finds the user.