I am having issues in my thought process. I want an output of something like
'Group Name' 'Title' 'Count' and I am able to get the 'Group Name' and 'Title' Columns but I'm not sure how to count, say, all of the repeat groups in the 'sales' title. Where my code is right now, is searching the entire column to see if it finds that group name, and if it finds that column and then it move the counter by 1 (this is wrong because it my find a group name with a different title)
Any help would be greatly appreciated! Thank you
$allOffices = get-aduser -filter * -Properties physicaldeliveryofficename | Select-Object -ExpandProperty physicaldeliveryofficename #Selecting all offices
$uniOffices = $allOffices | Select-Object -Unique
$groups = $null
$global:ErrorActionPreference = 'silentlycontinue'
$finallist = #()
$count = 0
foreach ($office in $uniOffices) { # Loop through all unique offices
$peopleInOffice = $null
$peopleInOffice = get-aduser -filter * -properties office | Where-Object office -eq $office | Select-Object -ExpandProperty SamAccountName # Array of people in a certain office, selects username
foreach ($person in $peopleInOffice){
$groups = get-ADPrincipalGroupMembership $person
foreach($group in $groups) {
if(($finallist.'Group Name'-contains $group.name) -and ($finallist.'Title' -contains $office)){$count++}
$finallist+= $group| Select-Object #{N='Group Name';E={$group.name}},#{N='Title';E={($office)}},#{N='Count';E={$count}}
}
}
}
$finallist
So I started working on your problem, and I'm unsure what you're asking. Here's a greatly simplified and more efficient representation of your code:
$offices = Get-ADUser -Filter 'PhysicalDeliveryOfficeName -like "*"' -Properties PhysicalDeliveryOfficeName |
Select-Object -ExpandProperty PhysicalDeliveryOfficeName -Unique
$list = foreach ($office in $offices)
{
foreach ($person in (Get-ADUser -Filter "Office -eq '$office'" -Properties Office, MemberOf))
{
$person.MemberOf |
Get-ADGroup -Properties Name |
Select-Object -Property #(
#{
N = 'Group Name'
E = {$PSItem.Name}
}
#{
N = 'Title'
E = {$office}
}
)
}
}
At the end, you have a $list object which is an array of pscustomobject objects that you can manipulate. You can use Group-Object to determine how many groups there are with similar names using calculated properties, etc.
Using your problem statement:
how to count all of the repeat groups in the sales title
$list | Group-Object -Property Title | Select-Object -ExpandProperty Count
Related
In the code below, the userprinciplename will output strings like "LLL_John.Smith#email.com" and XXXX_Jane.Doe#email.com" but i am hoping to extract a substring from that, that being the codes before the "_" character, so LLL and XXXX.
There may be some which do not have an underscore character however and so these would need to be ignored / have the original string it would have returned.
##Check bottom of script for setting specific OU
Function Get-LastLogon {
param(
[string]$OUName
)
# Get all matching OUs on any level
$OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
$DCs = Get-ADDomainController -Filter *
# Get all users from each OU from each DC
$ADUsers = Foreach ($OU in $OUs) {
Foreach ($DC in $DCs.HostName) {
Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties LastLogon -server $dc |
Select-Object Name,userPrincipalName, #{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}
}
}
# return most recent LastLogon date for each user
$ADUsers |
Group Name,userPrincipalName |
Select Name,userprinciplename, #{n='LastLogon';e={$_.Group.LastLogon | sort -desc | select -First 1}}
} ## End function
##Enter the OU here
Get-LastLogon -OUName 'Clients'
##Un-comment below to export to csv
## | Export-Csv -Path 'C:\temp\UserExport.csv'
Here is what the script looks like now in full:
##Check bottom of script for setting specific OU
Function Get-LastLogon {
param(
[string]$OUName
)
# Get all matching OUs on any level
$OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
$DCs = Get-ADDomainController -Filter *
$ADUsers = foreach ($OU in $OUs) {
foreach ($dc in $DCs.HostName) {
Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties lastLogonTimeStamp -Server $dc |
Select-Object Name,UserPrincipalName,
#{Name = 'LastLogon';Expression = {[DateTime]::FromFileTime($_.lastLogonTimeStamp)}},
#{Name = 'UserCode'; Expression = {([regex]'^([^_]+)_.*').Match($_.UserPrincipalName).Groups[1].Value}}
}
} }
# return the most recent LastLogon date for each user
# (only the users with a code prefix in the UserPrincipalName)
$ADUsers | Where-Object { ![string]::IsNullOrWhiteSpace($_.UserCode) } |
Group-Object UserPrincipalName | ForEach-Object {
[PsCustomObject]#{
Name = $_.Group[0].Name
UserCode = $_.Group[0].UserCode
LastLogon = $_.Group.LastLogon | Sort-Object -Descending | Select-Object -First 1
}
}
## End function
$OUcustom = Read-Host -prompt 'Enter OU here or "Clients" for all'
##Enter the OU here
Get-LastLogon -OUName $OUcustom |
##export csv
Export-Csv -path "C:\temp\UserExport_$((Get-Date).ToString("ddMM_HHmm")).csv" -NoTypeInformation
".csv extracted to C:\temp"
pause
Just add another calculated property to the code you have to get the array of user objects:
$ADUsers = foreach ($OU in $OUs) {
foreach ($dc in $DCs.HostName) {
Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties lastLogonTimeStamp -Server $dc |
Select-Object Name,UserPrincipalName,
#{Name = 'LastLogon';Expression = {[DateTime]::FromFileTime($_.lastLogonTimeStamp)}},
#{Name = 'UserCode'; Expression = {if ($_.UserPrincipalName -like '*_*#*') {($_.UserPrincipalName -split '_')[0]} else { $null }}}
# or use regex like:
# #{Name = 'UserCode'; Expression = {([regex]'^([^_]+)_.*').Match($_.UserPrincipalName).Groups[1].Value}}
}
}
Then you can filter out the users that do have such a code:
# return the most recent LastLogon date for each user
# (only the users with a code prefix in the UserPrincipalName)
$ADUsers | Where-Object { ![string]::IsNullOrWhiteSpace($_.UserCode) } |
Group-Object UserPrincipalName | ForEach-Object {
[PsCustomObject]#{
Name = $_.Group[0].Name
UserCode = $_.Group[0].UserCode
LastLogon = $_.Group.LastLogon | Sort-Object -Descending | Select-Object -First 1
}
}
If you want to rule out all users that do not have some code followed by an underscore in their UserPrincipalName property straight away, you can use the filter parameter:
Get-ADUser -SearchBase $OU.DistinguishedName -Filter "UserPrincipalName -like '*_*#*'" -Properties lastLogonTimeStamp -Server $dc
This however will not give you the opportunity to use the collected users for some other purpose, like outputting users who do not have a code prefixed, as would be easy to do with the code above.
P.S. Did you know PowerShell also provides an attribute LastLogonDate, which is the LDAP property lastLogonTimeStamp, converted to local time.
So this was actually more simple than I realised.
I just needed to add in:
#{N='userPrincipalName';E={$_.userPrincipalName.Split("_")[0]}}
To the first and second blocks where UserPrincipleName was being selected.
Will post the full working code below for relevance.
##Check bottom of script for setting specific OU
Function Get-LastLogon {
param(
[string]$OUName
)
# Get all matching OUs on any level
$OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
$DCs = Get-ADDomainController -Filter *
# Get all users from each OU from each DC
$ADUsers = Foreach ($OU in $OUs) {
Foreach ($DC in $DCs.HostName) {
Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties LastLogon -server $dc |
Select-Object Name,#{N='userPrincipalName';E={$_.userPrincipalName.Split("_")[0]}}, #{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}
}
}
# return most recent LastLogon date for each user
$ADUsers |
Group Name,userPrincipalName |
Select Name,#{N='userprinciplename';E={$_.userprinciplename.Split("_")[0]}}, #{n='LastLogon';e={$_.Group.LastLogon | sort -desc | select -First 1}}
} ## End function
$OUcustom = Read-Host -prompt 'Enter OU here or "Clients" for all'
##Enter the OU here
Get-LastLogon -OUName $OUcustom |
##export csv
Export-Csv -path "C:\temp\UserExport_$((Get-Date).ToString("ddMM_HHmm")).csv" -NoTypeInformation
".csv extracted to C:\temp"
pause
My goal is to list extended properties of a list of users by Display Name or SamAccountName pulling those names from a Csv. I am using the following script and it works but it either skips names in the Csv or repeats them. If I do one at a time it returns what I need but from the Csv it doesn’t. Csv has one column named Name.
Import-Csv C:\Users\Administrator\Documents\test.txt | Foreach {
Get-ADUser -Filter "DisplayName -eq '$($_.Name)'" -Properties *
} | Select-Object DisplayName, SamAccountName, Title, Department, EmailAddress, ObjectGUID | Sort-Object Displayname | FT
There is nothing wrong with your current code, except for using Import-Csv on a .txt file (test.txt), I would assume this was a typo. I've added an if condition to help you troubleshoot so at least you would know which users where not found.
You should also avoid the use of -Properties *, querying all properties for the users is inefficient and slow.
$properties = #(
'DisplayName'
'SamAccountName'
'Title'
'Department'
'EmailAddress'
'ObjectGUID'
)
Import-Csv C:\Users\Administrator\Documents\test.csv | ForEach-Object {
$adUser = Get-ADUser -Filter "DisplayName -eq '$($_.Name)'" -Properties $properties
if(-not $adUser) {
Write-Warning "'$($_.Name)' could not be found on AD"
return # Go next
}
$adUser
} | Select-Object $properties | Sort-Object Displayname | Format-Table
I want to have a script that i can start and it gives me all the groups starting with APS- and its members
I want to get a HTML where it says in the Header : the group and in the table the Users
this is the code i got so far :
$properties = 'GivenName', 'Surname', 'UserPrincipalName'
Get-ADGroup -Filter {name -like "APS-*"} | ForEach {
$groupName = $_.Name
Get-ADGroupMember -Identity $_.SamAccountName |Get-ADUser -Property $properties |Select
#{N='GroupName';E={$groupName}},'GivenName', 'Surname', 'UserPrincipalName'}
But this give me a list of group,givenname,Surename,userprincipal
i want to get :
Organized like this
Is there a way of getting this ?
please consider the following points in order to accomplish the needed result
the variable $properties contains common values, you do not need to pass it to `Get-ADUser to get its values
You need to specify the parameter recursive to the command Get-ADGroupMember in order to get all child users within child groups.
If you need to output the result in HTML format you can use the command ConvertTo-Html
I modified your code to output the needed format, please check it
$groups = Get-ADGroup -Filter {name -like "APS-*"}
$list = foreach ($group in $groups) {
$groupName = $group.Name
Get-ADGroupMember -Identity $group.SamAccountName -Recursive | Get-ADUser | select #{N='GroupName';E={$groupName}},'GivenName', 'Surname', 'UserPrincipalName'
}
$out = $list | Group-Object GroupName
[string]$out_html = foreach ($item in $out){
$item.group | Select-Object 'GivenName', 'Surname', 'UserPrincipalName' | ConvertTo-Html -PreContent "<br>$($item.Name)<br><br>"
}
$out_html| Out-File .\groups.html
if you need to exclude specific users from the report, you can filter the output of Get-ADGroupMember using the Where clause as follow
# i.e. to exclude specific samaccountnames
$execlusionList = #("SamAccountName1","SamAccountName2")
Get-ADGroupMember -Identity $group.SamAccountName -Recursive | where {$_.samaccountname -notin $execlusionList} | Get-ADUser | select #{N='GroupName';E={$groupName}},'GivenName', 'Surname', 'UserPrincipalName'
So im trying to return a report that will list each user and each group they are in using -Filter "name-like 'BLAH'"
the user may be apart multiple "BLAH" groups but no more than 3. How can i get an output like?
Member | Group1 | Group2 | Group3
I tried the below but not quite what i need
$adgroups = Get-ADGroup -Filter "name -like '*BLAH*'" | sort name
$data = foreach ($adgroup in $adgroups) {
$members = $adgroup | get-adgroupmember |select name| sort name
foreach ($member in $members) {
[PSCustomObject]#{
Members = $member
Group = $adgroup.name
}
}
}
This is what i get when using #Adam Luniewski solution
Try this:
$adgroups = Get-ADGroup -Filter "name -like '*BLAH*'" | Sort-Object Name
$data = ForEach ($adgroup in $adgroups){
$adgroup | get-adgroupmember | Select-Object #{n='Members';e={$_}},#{n='Group';e={(Get-ADUser $_.SamAccountName -Properties MemberOf).MemberOf}}
}
Here Get-ADUser is used to retrieve user group memberships (first said #Olaf) then I used calculated properties to format the output.
This should work. Just watch out if you have StrictMode set in your script, it might throw an error if $usrgrp count is less than 3, then you'd have to modify this part.
# get a list of all users and groups in two columns
$dat = #(Get-ADGroup -Filter "name -like '*BLAH*'" -PipelineVariable group | Get-ADGroupMember | select #{n='UserName';e={$_.name}},#{n='GroupName';e={$group.name}})
# for each user in a list add group fields
$dat | select UserName -Unique | ForEach-Object {
$usrgrp = #($dat | where username -eq $_.UserName | sort GroupName);
[pscustomobject]#{
UserName=$_.Username;
Group1=$usrgrp[0].GroupName;
Group2=$usrgrp[1].GroupName;
Group3=$usrgrp[2].GroupName;
};
}
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