Export users & groups & if they are a member of group - powershell

I need to do a script that will export me enabled users from specific OU and specific value of attribute Company (with some other attributes) and all groups beginning with name "A_ACC*" and if the user is a member of a group or no.
It should look like this on image. Desired result
For now I am working with this:
Get-ADUser -Filter {Company -eq "xxxx"} -SearchBase “yyyyy” -Properties GivenName, Surname, DisplayName, Company, Department, memberof, SamAccountName, PhysicalDeliveryOfficeName | Where {($_.Enabled -eq $True)} | % {
New-Object PSObject -Property #{
SamAccountName= $_.SamAccountName
GivenName = $_.GivenName
Surname=$_.Surname
DisplayName = $_.DisplayName
Company=$_.Company
Department = $_.Department
Location = $_.PhysicalDeliveryOfficeName
Groups = ($_.memberof | Get-ADGroup | Where Name -like "A_ACC*" | Select -ExpandProperty Name) -join ", "
}
} | Select GivenName, Surname, DisplayName, Company, Department, Location, Groups | Export-Csv -Path 'H:\My Documents\PowerShell_exports\Users_export.csv' -NoTypeInformation -Encoding UTF8
But unfortunately I do not know how to proceed further to get result I want.
Can you please advise?
Thank you!

If you have a list of groups that you are looking for you can enters these into an array (shown below as $groupsToCheckFor). Then add a property to each user object for each group with either true/false value depending on whether the group is found in the user's list of groups from memberof
$params = #{
Filter = { Company -eq 'xxxx' }
SearchBase = 'yyyyy'
Properties = #(
'DisplayName'
'Company',
'Department',
'memberof',
'PhysicalDeliveryOfficeName'
)
}
# List groups to check for which will be added as columns
$groupsToCheckFor = 'A_ACC_Group1', 'A_ACC_Group2', 'A_ACC_Group3'
Get-ADUser #params | Where-Object { ($_.Enabled -eq $True) } | ForEach-Object {
$object = [pscustomobject][ordered]#{
GivenName = $_.GivenName
Surname = $_.Surname
DisplayName = $_.DisplayName
Company = $_.Company
Department = $_.Department
SamAccountName = $_.SamAccountName
Location = $_.PhysicalDeliveryOfficeName
}
$groups = ($_.memberof | Get-ADGroup | Where-Object Name -Like 'A_ACC*' | Select-Object -ExpandProperty Name)
$groupsToCheckFor | ForEach-Object {
# add property for each group being checked for
# value is true if group is found in users' groups
$object | Add-Member -NotePropertyName $_ -NotePropertyValue ($_ -in $groups)
}
# output object
$object
} | Export-Csv -Path 'H:\My Documents\PowerShell_exports\Users_export.csv' -NoTypeInformation -Encoding UTF8

Related

How to sort-object lastlogon -descending?

I have to check the lastlogon for different users.
My script queries my domain controllers to output my report, however I have an issue.
My report does not come out in descending order. I added sort-object lastlogon -descending, but the dates don't come out correctly in my file. Can you help me?
$data = #()
$DCs = Get-ADDomainController -Filter * | Select-Object -ExpandProperty name
$users =
#'
samaccountname;
user1
user2
'# | ConvertFrom-Csv -Delimiter ';'
foreach ($DC in $DCs) {
foreach($user in $users)
{$data += Get-ADUser $User.samaccountname.Trim() -Properties displayname, userprincipalname, samaccountname, lastlogon -server $DC | Select-Object DisplayName, UserPrincipalName, SamAccountName, Enabled, #{name='LastLogon';expression={[datetime]::fromFileTime($_.lastLogon).ToString('yyyy-MM-dd')}} }
}
$data | Group-Object Lastlogon | Foreach-Object {$_.Group | Sort-Object lastLogon -Descending | Select-Object -Last 10 | Export-Excel "C:\temp\lastlogon ($(Get-Date -Format "yyyy-MM-dd")).xlsx"}
write-host Done! -ForegroundColor Green
It's unclear what you want to accomplish with your script but basically, if you .ToString(..) a DateTime object then Sort-Object will not know how to sort it correctly. Here is how you can approach your code:
$DCs = (Get-ADDomainController -Filter *).Name
$users = #'
samaccountname;
user1
user2
'# | ConvertFrom-Csv -Delimiter ';'
& {
foreach ($DC in $DCs) {
foreach($user in $users) {
$params = #{
Properties = 'displayname', 'lastlogon'
Server = $DC
Identity = $User.samaccountname.Trim()
}
Get-ADUser #params | Select-Object #(
'DisplayName'
'UserPrincipalName'
'SamAccountName'
'Enabled'
#{
Name = 'LastLogon'
Expression = {
[datetime]::fromFileTime($_.LastLogon)
}
}
)
}
}
} | Group-Object { $_.Lastlogon.ToString('yyyy-MM-dd') } | Foreach-Object {
$_.Group | Sort-Object LastLogon -Descending | Select-Object -Last 10 |
Export-Excel "C:\temp\lastlogon ($(Get-Date -Format "yyyy-MM-dd")).xlsx"
}
You also want to avoid adding elements (+=) to a fixed collection (#()).

Pscustomobject adding dynamic values

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

Get all members for groups and subgroups

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.

Correcting PowerShell script to show Disabled AD user account (not shared mailboxes) with Exchange mailbox and its size in MBytes?

I am attempting to modify the script below so it is showing all Disabled AD user account with Exchange User mailbox still enabled (not Shared Mailbox).
Because the script below also returns Shared Mailboxes which is always created as disabled AD user account.
$Allusers = Get-ADUser -Filter {(enabled -eq $false)} -Properties homeMDB, mailNickName, mail, DisplayName, SamAccountName, Givenname, SurName | ?{ $_.homeMDB -ne $null }
$Allusers | Select-Object Givenname, Surname, DisplayName, Mail, MailNickName, SamAccountName, homeMDB | Export-Csv "C:\DisableduserMBX.csv" -NoTypeInformation
It would be good if there is mailbox size as well in the column in MBytes.
Like in the below script:
Get-Mailbox -ResultSize Unlimited |
Get-MailboxStatistics |
Select DisplayName,StorageLimitStatus, `
#{name="TotalItemSize (MB)"; expression={[math]::Round(($_.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}}, `
ItemCount |
Sort "TotalItemSize (MB)" -Descending
To add the MBYTES column, you can try this.
Note this uses the filter as provided by notjustme.
# for the sake of readability..
$filter = '(Enabled -eq $false) -and (msExchRecipientTypeDetails -ne 4) -and ("$null" -ne homeMDB)'
$properties = #('homeMDB', 'mailNickName', 'mail', 'DisplayName', 'SamAccountName', 'Givenname', 'SurName', 'ProxyAddresses')
$Allusers = (Get-ADUser -Filter $filter -Properties $properties |
ForEach-Object {
$size = (Get-MailboxStatistics $_.SamAccountName).TotalItemSize.Value.ToMB()
New-Object -TypeName PSObject -Property #{
homeMDB = $_.homeMDB
mailNickName = $_.mailNickName
mail = $_.mail
ProxyAddresses = $_.ProxyAddresses -join '; '
DisplayName = $_.DisplayName
SamAccountName = $_.SamAccountName
Givenname = $_.Givenname
SurName = $_.SurName
MBytes = $size
}
}) | Sort-Object MBytes -Descending | Export-Csv "C:\DisableduserMBX.csv" -NoTypeInformation
p.s. I've added the ProxyAddresses in there to be able to spot more alias emailaddresses.
p.s. 2 The Identity parameter for Get-MailboxStatistics can be one of:
Name
Display name
Alias
Distinguished name (DN)
Canonical DN
domain name\account name
Email address
GUID
LegacyExchangeDN
SamAccountName
User ID or user principal name (UPN)
msExchRecipientTypeDetails with the value of 4 denotes a shared mailbox. So to exclude these you could try changing your first line of code to the following and see if that gives you the desired output.
$Allusers = Get-ADUser -Filter 'enabled -eq $false -and msExchRecipientTypeDetails -ne 4' -Properties homeMDB, mailNickName, mail, DisplayName, SamAccountName, Givenname, SurName | ?{ $_.homeMDB -ne $null }
You should also be able to include the homeMDB-bit in the filter directly;
$Allusers = Get-ADUser -Filter 'enabled -eq $false -and msExchRecipientTypeDetails -ne 4 -and homeMDB -ne "$null"' -Properties homeMDB, mailNickName, mail, DisplayName, SamAccountName, Givenname, SurName

Powershell Read Users from ActiveDirectory , sort and group the result

I want to read users from different Active Directory groups and then sort and group the results.
From a list like
UserName UserGroup
UZZ GAA
UKK GAA
UZZ GBB
ULL GBB
I want to get that:
Username UserGroup
UKK GAA
ULL GBB
UZZ GAA
So, from User UZZ I want to get only one entry in the list with the first value of UserGroup (first in the alphanumeric sort).
Till now I have the following code:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "G-Q-T*"} | select name -expandproperty name)
$Table = #()
$Record = #{"GroupName" = """Username" = ""}
Foreach ($Group in $Groups) {
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name, samaccountname
foreach ($Member in $Arrayofmembers) {
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Sort-object -property Username | Group-object -property Username | export-csv "U:\members.csv" -NoTypeInformation**
The part making the list works fine. But not the sort and group part.
Thank you a lot for an answer and help.
Meanwhile I found out, that I have also to add the SID into the .csv File.
The SID is also in the Get-AdGroupMember. But then I try to implement is as the following, the output in case of SID stays empty. What did I wrong where? Thank you in advance for an answer:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter "name -like 'G-Q-T*'" | select name -expandproperty name)
$Table = #()
$Record = #{
"GroupName" = ""
"Username" = ""
"SID" = ""
}
Foreach ($Group in $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name,samaccountname,SID
foreach ($Member in $Arrayofmembers)
{
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$Record."SID" = $Member.SID
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}} , #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} , #{n="SID";e={$_.SID | Sort-Object SID | Select-Object -First 1 -ExpandProperty SID}}| Export-Csv "U:\member.csv" -NoTypeInformation
I would group on username and use calculated properties to create the desired result. Sort the groupnames in the group and pick out the first value. Try to replace your last line with:
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation
Avoid -Filter * as it retrieves every group. Use it to get only the groups you need
$Groups = Get-ADGroup -Filter "name -like 'G-Q-T*'"
Alternative using the famous pipeline:
Get-ADGroup -Filter "name -like 'G-Q-T*'" | ForEach-Object {
$groupname = $_.Name
$_ | Get-ADGroupMember | ForEach-Object {
New-Object -TypeName psobject -Property #{
UserName = $_.SamAccountName
SID = $_.SID
GroupName = $groupname
}
}
} | Group-Object -Property UserName |
Select-Object #{n="UserName";e={$_.Name}}, #{n="SID";e={$_.Group[0].SID}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation