good day to all.
I've been trying to get information about groups and subgroups in Active Directory
I've tried many variants like the one below,
What I essentially need is, to get a CSV of all the groups in AD that contain "infolink" in their name, and the columns I need are:
GiveName
SN
Username
Mail
Group
ManagedBy
But no matter how I put it I only get some of the things I need.
Does someone already have a bit of code that could make my life a bit easier? If so, I'd be immensely grateful.
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "*Infolink*"} | select name -ExpandProperty name)
$Table = #()
$Record = #{
"Group Name" = ""
"Name" = ""
"Username" = ""
"mail" = ""
}
Foreach ($Group in $Groups) {
$Arrayofmembers = Get-ADGroupMember -identity $Group -recursive | select name,samaccountname
foreach ($Member in $Arrayofmembers) {
$Record."Group Name" = $Group
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | export-csv "D:\Infolink.csv" -NoTypeInformation
Try this,
Import-Module ActiveDirectory
$groups = Get-ADGroup -Filter "name -like '*Infolink*'" -Properties ManagedBy
$table = foreach ($group in $groups) {
$Arrayofmembers = Get-ADGroupMember -Identity $group -Recursive
$ArrayofmembersUsers = $Arrayofmembers | Get-ADUser -Properties Mail
$ArrayofmembersUsers | Add-Member -Name GroupInfoLinkName -MemberType NoteProperty -Value $group.Name -Force
$ArrayofmembersUsers | Add-Member -Name GroupInfoLinkManageBy -MemberType NoteProperty -Value $group.ManagedBy -Force
$ArrayofmembersUsers
}
$table | Select-Object -Property GivenName, SurName, SamAccountName, Mail, GroupInfoLinkName, GroupInfoLinkManageBy | Export-Csv "D:\Infolink.csv" -NoTypeInformation
Some Pointers..
Use the Filter on Get-ADGroup else you're getting all groups in AD and then filtering.
PSObject are great but if your Object already has the majority of the properties you require then Add-Member is helpful to add 1 or 2 more.
Many cmdlets have a Properties parameter, you'll see I've used this to include properties that were not included by default. Unfortunately Get-ADGroupMember is not one of those cmdlets so piping to Get-ADUser helps provide a workaround.
Related
I need to find AD group members from given groups in csv file as input. the groups contains Users and Groups also. below is sample input data
I wrote the below code. for users I am getting the output (i.e. for the first entry), but for the second one, as they are groups within group, I am not able to fetch the email.
$GroupCollection= Import-csv -Path "C:\Groups.csv"
$Report = #()
Foreach($Group in $GroupCollection){
$MemberGroup=#()
$Group = $Group.'OPE DLs'
if($Group -match '#')
{
$pos = $Group.IndexOf("#")
$leftPart = $Group.Substring(0, $pos)
}
else
{
$leftPart = $Group
}
$MemberGroup = Get-ADGroupMember -identity $leftPart -recursive | Get-ADUser -Properties mail | Select-Object mail
$MemberGroups = ($MemberGroup.mail) -join "`r`n"
if($MemberGroups -ne ""){
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name 'Contract Details' -Value $Group.'Customer subset'
$Out | Add-Member -MemberType noteproperty -Name 'Group Name' -Value $leftPart
$Out | Add-Member -MemberType noteproperty -Name 'Member Groups' -Value $MemberGroups
$Report += $Out
}
}
$Report | Sort-Object Name | FT -AutoSize
$Report | Sort-Object Name | Export-Csv -Path ‘C:\Group-MemberGroups-Report.csv’ -NoTypeInformation
Please let me know how to get the details. Is the approach is fine or there is any other way to do this.
expected output
As commented, if the object returned by Get-ADGroupMember is a group, you won't get results by piping it through to Get-ADUser, because... it is a group, not a user.
You need to loop over the results and depending on what type the object is (group, user or computer) you use either Get-ADUser or Get-ADGroup (not interested in computer objects).
Try
$Report = foreach ($Group in $GroupCollection){
$groupName = ($Group.'OPE DLs' -split '#')[0]
$groupMembers = Get-ADGroupMember -Identity $groupName -Recursive | ForEach-Object {
$adObject = $_
switch ($adObject.objectClass) {
'group' { ($adObject | Get-ADGroup -Properties mail).mail }
'user' { ($adObject | Get-ADUser -Properties EmailAddress).EmailAddress }
}
}
if (#($groupMembers).Count) {
[PsCustomObject]#{
'Group Name' = $groupName
'Contract Details' = $Group.'Customer subset'
'Member Groups' = $groupMembers -join [environment]::NewLine
}
}
}
$Report = $Report | Sort-Object 'Group Name'
$Report | Format-Table -AutoSize
$Report | Export-Csv -Path 'C:\Group-MemberGroups-Report.csv' -NoTypeInformation
Notes:
adding to an array with += is extremely wasteful because the entire array needs to be rebuilt in memory on each iteration
To take the group name as the part left of the # character, I simply use the -split operator and take the first element ([0])
To output an object, I'm using a [PsCustomObject]#{..} construct rather than the old (pre PowerShell 3.0) New-Object PSObject method
I am trying to read group membership of computers from a particular OU and write to a CSV file. The input criteria for the group membership is like if the computer is part of say "admin" and i need the csv file in the below format
---------------------------------------------------------
Computer Group1 Group2 Group3 Group4
ABCD admin1 admin2 admin3 admin4
EFGH admin2 admin3
XYZZ admin1 admin4
--------------------------------------------------------------
but end up like this.
---------------------------------------------------------
Computer Group1 Group2 Group3 Group4
ABCD admin1 admin2 admin3 admin4
EFGH admin2 admin3
XYZZ admin1 admin4
--------------------------------------------------------------
The code is like this
$All_computer = Get-ADComputer -Filter * -Property * -SearchBase $ou -Server $server | Select-object Name,DNSHostName,Description,memberof
$computerExport = $All_computer |
ForEach-Object {
$ComputerName = $_.Name
$Description = $_.description
$DNSHostname = $_.DNSHostName
$memberof = $_.memberof
$groups = $memberof.where{$_ -like "*$unput_group*"}
$Group_member = [pscustomobject]#{
Workstation = $ComputerName
Comp_Description = $Description
DNS_Hostname = $DNSHostname
}
$i = 0
foreach($group in $Groups)
{
$i++
$member = $group.split('=')[1].split(',')[0]
$Group_member | add-member -MemberType NoteProperty -Name "Group$i" -Value $member
}
$Group_member
}
}
$computerExport | export-csv .\Membership_status.csv -NoTypeInformation
What do i need to do to get the group membership to populate to proper column.
Well of course it does. I mean it's doing what you're asking it to do.
You're only adding the number of properties to the custom object that is found from the where object query. I am really struggling to understand what you're trying to do this for but I THINK what you really want is for each object to have all the possible properties but to have null values for those that don't match that particular computer or better yet to use a boolean.
So... Maybe like this:
[string]$GroupSearch = "admin"
$All_computer = Get-ADComputer -Filter * -Property DNSHostName, Description, memberof -SearchBase $ou -Server $server | Select-Object Name, DNSHostName, Description, memberof
$MatchedGroups = $All_Computer.MemberOf | Sort -Unique | ?{$_.Name -match $GroupSearch}
$computerExport = ForEach ($C in $All_computer) {
$Group_member = [pscustomobject]#{
Workstation = $($C.Name)
Comp_Description = $($C.Description)
DNS_Hostname = $($C.DNSHostName)
}
ForEach ($group in $MatchedGroups) {
[string]$GrpName = $($group.split('=')[1].split(',')[0])
If ($C.MemberOf -contains $group) {
$Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $true
} else {
$Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $false
}
}
$Group_member
}
$computerExport | Export-Csv .\Membership_status.csv -NoTypeInformation
If I understand the question, you need to get all computers from a certain OU that are member of group(s) with a similar partial name.
To do that, I would suggest creating an array of computer objects at first with a temporary extra property called 'Groups' in which the group names that match the partial name are stored.
Later, we'll put these in the correct order as new properties called 'Group1', 'Group2' etc.
# the partial groupname to search for
$unput_group = 'admin'
# Get-ADComputer by default already returns these properties:
# DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName
# get an array of computer objects that are member of 'admin*' group(s) with the desired properties
# one extra temporary property is added which contains an array of 'admin*' group names
$All_computer = Get-ADComputer -Filter * -Property Description, MemberOf -SearchBase $ou -Server $server |
Where-Object { $_.MemberOf -match $unput_group} |
Select-Object #{Name = 'Workstation'; Expression = {$_.Name}},
#{Name = 'Comp_Description'; Expression = {$_.Description}},
#{Name = 'DNS_Hostname'; Expression = {$_.DNSHostName}},
#{Name = 'Groups'; Expression = { #($_.MemberOf |
Where-Object { $_ -match "CN=($unput_group[^,]+)" } |
ForEach-Object { $matches[1] }) }}
# get all the group names from the computers we have collected and sort unique
$All_Groups = $All_computer.Groups | Sort-Object -Unique
# build a lookup hashtable with property names ('Group1', 'Group2' etc)
$hash = [ordered]#{}
for ($i = 1; $i -le $All_Groups.Count; $i++) {
$hash["Group$i"] = $All_Groups[$i - 1]
}
# now loop through the collection and add the group properties in order
$result = foreach ($computer in $All_computer) {
foreach ($propertyName in $hash.Keys) {
$group = if ($computer.Groups -contains $hash[$propertyName]) { $hash[$propertyName] }
$computer | Add-Member -MemberType NoteProperty -Name $propertyName -Value $group
}
# output the updated object and remove the temporary 'Groups' property
$computer | Select-Object * -ExcludeProperty Groups
}
# finally, save the results to disk
$result | Export-Csv -Path .\Membership_status.csv -NoTypeInformation
The following code query's AD for information on user accounts and is expected to export an excel file that contains the Name, Username, AccountEnabled(yes/no), Department, Description, LastLogonDate, and what groups every user in AD has. Currently the script works as intended except that under the users Groups, it does not list 'Domain User' on ANY user which they all contain. I am trying to determine why and how to fix.
Import-Module ActiveDirectory
$Report = #()
#Collect all users
$Users = Get-ADUser -Filter * -Properties Name, GivenName, SurName, SamAccountName, UserPrincipalName, MemberOf, Enabled, Department, Description, LastLogonDate -ResultSetSize $Null
# Use ForEach loop, as we need group membership for every account that is collected.
# MemberOf property of User object has the list of groups and is available in DN format.
Foreach($User in $Users){
$UserGroupCollection = $User.MemberOf
#This Array will hold Group Names to which the user belongs.
$UserGroupMembership = #()
#To get the Group Names from DN format we will again use Foreach loop to query every DN and retrieve the Name property of Group.
Foreach($UserGroup in $UserGroupCollection){
$GroupDetails = Get-ADGroup -Identity $UserGroup
#Here we will add each group Name to UserGroupMembership array
$UserGroupMembership += $GroupDetails.Name
}
#As the UserGroupMembership is array we need to join element with ‘,’ as the seperator
$Groups = $UserGroupMembership -join ‘, ‘
#Creating custom objects
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name Name -Value $User.Name
$Out | Add-Member -MemberType noteproperty -Name UserName -Value $User.SamAccountName
$Out | Add-Member -MemberType noteproperty -Name Enabled -Value $User.Enabled
$Out | Add-Member -MemberType noteproperty -Name Department -Value $User.Department
$Out | Add-Member -MemberType noteproperty -Name Description -Value $User.Description
$Out | Add-Member -MemberType noteproperty -Name LastLogonDate -Value $User.LastLogonDate
$Out | Add-Member -MemberType noteproperty -Name Groups -Value $Groups
$Report += $Out
}
#Output to screen as well as csv file.
#$Report | Sort-Object Name | FT -AutoSize
$Report | Sort-Object Name | Export-Csv -Path "C:\Scripts\Output\users.csv" -NoTypeInformation -Encoding UTF8
You are not seeing it because it's the primary group for most users.
See this question for a better explanation.
https://serverfault.com/questions/955721/why-is-the-domain-users-group-missing-from-this-powershell-ad-query
As for your script it can probably be simplified a bit by using pipes and calculated properties.
$Users = Get-ADUser -Filter * -Properties Name, GivenName, SurName, SamAccountName, UserPrincipalName, MemberOf, Enabled, Department, Description, LastLogonDate -ResultSetSize $Null
$users | Select Name, #{Name='Username';Expression={$_.SamAccountName}}, Enabled, Department, Description, LastLogonDate, `
#{Name='Groups';Expression={
($_.MemberOf | foreach{ Get-AdGroup -Identity $_ } | select -expand name) -join ","
}}
And if you want it to run faster remove the Get-AdGroup command and replace it with a split/trim command.
Although that is a bit more janky, but a lot faster.
$users | Select Name, #{Name='Username';Expression={$_.SamAccountName}}, Enabled, Department, Description, LastLogonDate, `
#{Name='Groups';Expression={
($_.MemberOf | foreach {($_ -split ",")[0].TrimStart('CN=')}) `
}} | select -expand groups | Sort-Object
A more elegant way of creating a custom object like you are doing would be something like this.
[pscustomobject]#{
Username= "jdoe"
FullName = "John Doe"
}
I have a requirement to generate a CSV report to get group members. However, I there are many child domains which contains groups starting with ADM.
I need report in the following format:
GroupName User Company LasLogon CN
ADM_AM UserOne CP1
I've found one script on internet:
Get-ADGroup -Server dc1.chd1.pd.local -Filter 'Name -like "ADM*"' |
ForEach-Object{
$hash=#{GroupName=$_.Name;Member=''}
$_ | Get-ADGroupMember -ea 0 -recurs |
ForEach-Object{
$hash.Member=$_.Name
New-Object psObject -Property $hash
}
} |
sort groupname,member
This script only gives me GroupName and UserName but not other information.
How can I generate this report?
I'm not sure what "ADM_AM, UserOne, CP1" is, but i got this much for you. I'm still new to powershell so forgive me if this is a lot of code =)
$array = #()
Foreach ($group in (Get-ADGroup -Server dc1.chd1.pd.local -Filter 'Name -like "ADM*"'))
{
$hash=#{Username ='';GroupName=$group.Name;Company='';LastLogon='';CN=''}
$members = $hash.GroupName | Get-ADGroupMember -Recursive -ErrorAction SilentlyContinue
Foreach($member in $members)
{
$properties = $member.SamAccountName | Get-ADUser -Properties SamAccountName, Company, lastLogon, CN
$hash.Username = $properties.SamAccountName
$hash.Company = $properties.Company
$hash.LastLogon = $properties.lastLogon
$hash.CN = $properties.CN
$obj = New-Object psObject -Property $hash
$array += $obj
}
}
$array | Export-Csv C:\ -NoTypeInformation
Here is what I would do, Im sure you can shorten it. You shoud specify a searchbase. Once you have the members samaccountname, you can use Get-ADUser to get whatever fields you want.
$GrpArr = #()
$Groups = get-adgroup -filter {name -like "adm*"} -searchbase "ou=Groups,dc=all,dc=ca" | select samaccountname
foreach ($group in $groups)
{
$GrpArr += $group
$members = get-adgroupmember $group | select samaccountName
foreach ($member in $members)
{
$memprops = get-aduser $member -properties company
$comp = $memprops.company
$grpArr += "$member,$comp"
}
}
$grpArr | export-csv c:\temp\Groups.csv -NoTypeInformation
I need to return all members of multiple security groups using PowerShell. Handily, all of the groups start with the same letters.
I can return a list of all the relevant security groups using the following code:
Get-ADGroup -filter 'Name -like"ABC*"' | Select-Object Name
And I know I can return the membership list of a specific security group using the following code:
Get-ADGroupMember "Security Group Name" -recursive | Select-Object Name
However, I can't seem to put them together, although I think what I'm after should look something like this (please feel free to correct me, that's why I'm here!):
$Groups = Get-ADGroup -filter 'Name -like"ABC*"' | Select-Object Name
ForEach ($Group in $Groups) {Get-ADGroupMember -$Group -recursive | Select-Object Name
Any ideas on how to properly structure that would be appreciated!
Thanks,
Chris
This is cleaner and will put in a csv.
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "**"} | select name -expandproperty name)
$Table = #()
$Record = [ordered]#{
"Group Name" = ""
"Name" = ""
"Username" = ""
}
Foreach ($Group in $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name,samaccountname
foreach ($Member in $Arrayofmembers)
{
$Record."Group Name" = $Group
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | export-csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
If you don't care what groups the users were in, and just want a big ol' list of users - this does the job:
$Groups = Get-ADGroup -Filter {Name -like "AB*"}
$rtn = #(); ForEach ($Group in $Groups) {
$rtn += (Get-ADGroupMember -Identity "$($Group.Name)" -Recursive)
}
Then the results:
$rtn | ft -autosize
Get-ADGroupMember "Group1" -recursive | Select-Object Name | Export-Csv c:\path\Groups.csv
I got this to work for me... I would assume that you could put "Group1, Group2, etc." or try a wildcard.
I did pre-load AD into PowerShell before hand:
Get-Module -ListAvailable | Import-Module
This will give you a list of a single group, and the members of each group.
param
(
[Parameter(Mandatory=$true,position=0)]
[String]$GroupName
)
import-module activedirectory
# optional, add a wild card..
# $groups = $groups + "*"
$Groups = Get-ADGroup -filter {Name -like $GroupName} | Select-Object Name
ForEach ($Group in $Groups)
{write-host " "
write-host "$($group.name)"
write-host "----------------------------"
Get-ADGroupMember -identity $($groupname) -recursive | Select-Object samaccountname
}
write-host "Export Complete"
If you want the friendly name, or other details, add them to the end of the select-object query.