i have array of users how to find what ones are Disabled - active-directory

What i am trying to do = Return all Disabled accounts in certin Groups and store them in a Veriable i can use to search with VM view to detach Persistant Drives from disabled users.
$groups = Get-ADGroup -Filter {Name -like "view_*"}
$rtn = #()
ForEach ($Group in $Groups)
{
$rtn += (Get-ADGroupMember -Identity "$($group.name)" -recursive)
}
$dis = #()
foreach ($user in $rtn)
{
$dis += (get-aduser -filter {enabled -eq $false})
}
i belive this works for me but i need to know is there a Better way to do this? cause this takes a lot of time with couple thousand users

If there's any overlap in your group membership (users in multiple groups), you'll be calling Get-ADUser multiple times for the same user. This will slow you down and return duplicate data you'll have to filter out.
You can do this without the Foreach loop and array building, just a single pipeline will work. Linebreaks added for formatting clarity.
$rtn = get-adgroup -filter {name -like "view__*"}|`
foreach-object {Get-ADGroupMember $_ -recursive}|`
select-object -expandproperty distinguishedname -unique|`
get-aduser -Properties enabled|`
where-object {$_.enabled -eq $false};
This returned 37 distinct users across 9 groups. Across multiple runs, the execution time was anywhere from 1.1 to 2.5 seconds.
The method in your answer returned 60 users across those same 9 groups - with a lot of duplicates (because they weren't filtered out). Across multiple runs, the execution time was anywhere from 1.7 to 3.5 seconds.

This is feel is the best way to accomplish what i set out to do
$groups = Get-ADGroup -Filter {Name -like "view_*"}
$rtn = #()
ForEach ($Group in $Groups)
{
$rtn += (Get-ADGroupMember -Identity "$($group.name)" -recursive | %{Get-ADUser -Identity $_.distinguishedName -Properties Enabled | ?{$_.Enabled -eq $false}} )
}
if any one has a better way of doing this please let me know.

Related

How to Count the number of AD Groups a user a member of

I've tried several ways of doing this, however I've found the below has been the best so far, which I found via another website. It works really well, however I now require to have the script get the number of AD Groups each user is a member of on another Domain.
Here is the working script:
# Either create an array of target users or import via a file
$colUser = (get-content "C:\TR\List.txt")
# Create a report array object
$UserReport = #()
foreach ($objUser in $colUser) {
# Cycle through our target users
$ErrorFlag = $false
Try {
# Attempt to enumerate and count the target users group membership
$count = Get-ADPrincipalGroupMembership $objUser | measure | select -expand count
} Catch {
# If we get an error - capture it and skip adding this user to the report
write-host "Error: $_"
$ErrorFlag = $true
}
If (!$ErrorFlag) {
# When we don't have an error - add the user details to a hash object
$UserHash = #{
Username = $objUser
Groupcount = $count
}
# Create a new object using our hash object
$objUserInfo = New-Object PSObject -Property $UserHash
# Add the new object to the reporting array
$UserReport += $objUserInfo
}
}
# Output our report object sorted by descending group membership numbers
$UserReport | sort -desc Groupcount | export-csv C:\TR\ExportCount.csv
I've tried adding
Get-ADDomain -Server 'DC.Server'
in various places, however it tends to either break the script, or the script just doesn't look for accounts in the new domain.
Can anyone please help?
Thanks :)
This works for me:
Get-AdUser -filter "*" -Properties memberof |
Select SamAccountName,#{n="NumberOfGroups";e={$_.memberof.count}} |
Where-Object { $_.NumberOfGroups -gt 0 } |
Export-CSV C:\TR\ExportCount.csv
For a different domain than the one you are currently using:
Get-AdUser -Server whatever.example.com `
-Credential (Get-Credential) -filter "*" `
-Properties memberof
The rest stays the same.
To get only users listed in a file:
Get-Content "C:\TR\List.txt" | Get-AdUser #... rest of the above
This assumes that the file contains one username per line.

Get-ADUser - searching for expired account. Using variables in command

I am currently working on a Powershell GUI script to help my team easier find accounts with expired passwords, disabled accounts etc and to output these to a CSV. It revolves almost entirely around the "Get-ADUser" command. So far almost everything has worked, bar finding accounts with expired passwords.
I've researched this a lot already but there seems to be no easy way of finding expired accounts using Get-ADUser. I know I can use Search-ADAccount instead but it would be very awkward to do so (as I would need to re-write a lot of code).
Get-Aduser -Properties * -Filter {PasswordExpired -eq $true} just draws a blank.
I've found a partial solution over at https://serverfault.com/questions/805526/get-aduser-password-expired-filter-not-working-correctly/805611
For example,
Get-ADUser -Properties * -Filter * | ? {$_.PasswordExpired -eq $True -and $_.Enabled -eq $true} | Select-Object name, enabled | Export-Csv "C:\report.csv" -NoTypeInformation
works just fine but if I try to assign the 'middle' of the command i.e
{$_.PasswordExpired -eq $True -and $_.Enabled -eq $true}
to a variable and then substitute it into the command I either get an error, a list of all those in my AD or nobody at all. The rational for substituting in a variable is to allow for the possible account statuses (that the user can choose from by selecting a radio button).
I've tried the various permutations of double and single quotes, including and not including curly brackets etc but Powershell will not give me a break!
Thanks!
The Get-ADUser cmdlet exposes the PasswordExpired extended property, which is a boolean indicating if the password is expired. It is based on the msDS-User-Account-Control-Computed attribute. However, you cannot filter with this property.
This would mean you can check the UF_PASSWORD_EXPIRED bit on that property:
Get-ADUser -Filter "Enabled -eq 'True'" -Properties 'msDS-User-Account-Control-Computed' |
Where-Object {($_.'msDS-User-Account-Control-Computed' -band 0x800000) -eq 0x800000} | # UF_PASSWORD_EXPIRED --> 0x800000 = 8388608
Select-Object Name, Enabled | Export-Csv "C:\report.csv" -NoTypeInformation
You can speed up the above by extending the filter to rule out users with PasswordNeverExpires and PasswordNotRequired both $false:
$filter = "Enabled -eq 'True' -and PasswordNeverExpires -eq 'False' -and PasswordNotRequired -eq 'False'"
Get-ADUser -Filter $filter -Properties PasswordNeverExpires, PasswordNotRequired, 'msDS-User-Account-Control-Computed' |
Where-Object {($_.'msDS-User-Account-Control-Computed' -band 0x800000) -eq 0x800000} | # UF_PASSWORD_EXPIRED --> 0x800000 = 8388608
Select-Object Name, Enabled | Export-Csv "C:\report.csv" -NoTypeInformation
I reckon I've found a solution over on Stack Exchange.
See https://serverfault.com/questions/723217/find-out-if-password-expired-or-when-it-expires-for-user-in-a-specific-ou
Early tests suggest it works.

PowerShell array iteration or parsing problem?

I'm new to PowerShell. I'm trying to pull a users Active Directory info based on their job title and place it in a csv file. I have two corresponding arrays, $title and $csvfile. $title[0] corresponds with $csvfile[0] and $title[1] to $csvfile[1] and so on. This loop creates all my .csv files but doesn't pull any user data. I can manually enter any of the $title items into the script and it works but when used as an array I get nothing.
Does an array add any leading or ending spaces, quotations, delimiters, anything that might keep the -and statement from working?
$title = #(
'Director of Nursing'
'Assistant Director of Nursing'
'Activities Director'
)
$csvfile = #(
'DON'
'ADON'
'ACTIVITIES'
)
for($i=0; $i -lt $title.Count; $i++)
{
#Get-ADUser -Filter { (Title -like "Director of Nursing") -and (Company -like "location1") }| Export-Csv c:\temp\$($csvfile[$i]).csv"
Get-ADUser -filter { (Title -like "$($title[$i])") -and (Company -like "Location1") }| Export-Csv "c:\tempPath\$($csvfile[$i]).csv"
}
The AD module re-parses the -Filter block (and turns it into a proper LDAP filter), the likeliest explanation is that it can't resolve $($title[$i]) when that happens.
Try with a string filter instead:
Get-ADUser -filter "Title -like '$($title[$i])' -and Company -like 'Location1'"| ...

Is there a way to sort within DistinguishedName

I am trying to get a list of users and Id like to sort based on the last OU= in DistinguishedName. The syntax I'm using isn't quite right and I need some pointers. Thank You
get-aduser -Filter {Enabled -eq $true} -Properties * | where {($_.EmployeeNumber -eq $null) -and ($_.PrimaryGroup -eq 'CN=Domain Users,CN=Users,DC=OURDOMAIN,DC=net')} | FT SamAccountName,Name,EmployeeNumber,DistinguishedName,Created | export-csv Users.csv
You can ask for the msDS-parentdistname attribute in AD. It's a relatively new attribute, so it's possible it's not available on the version of Windows Server that you're running in your environment. But you can see if it's there.
It's a constructed attribute, which means it's calculated at the time it's asked for. But that also means you have to explicitly ask for it (you can't use -Properties *).
The use Sort-Object to sort your list.
get-aduser -Filter {Enabled -eq $true} -Properties SamAccountName,Name,EmployeeNumber,DistinguishedName,Created,msDS-parentdistname | where {($_.EmployeeNumber -eq $null) -and ($_.PrimaryGroup -eq 'CN=Domain Users,CN=Users,DC=OURDOMAIN,DC=net')} | Sort-Object msDS-parentdistname | FT SamAccountName,Name,EmployeeNumber,DistinguishedName,Created,msDS-parentdistname | export-csv Users.csv

Powershell Bulk Remove-ADGroupMember

I am looking to carry out a bulk removal of members from multiple groups from an imported CSV file of SAMAccountName, ADGroup. I could just loop through every record in the array (of which there will be 1600 entries) but it would be better if I could collate all of the users that are in a particular group and issue the Remove-ADGroupMember with multiple users.
I'm not sure how to process the data in the array so it appears as ADGroup, MultipleSAMAccountNames - I'm probably missing something obvious.
Example CSV:
SAMAccountName, ADGroup
User1, GroupA
User2, GroupA
User3, GroupB
User4, GroupA
Example Code:
Import-Module ActiveDirectory
$Users = Import-CSV "Users.csv"
foreach ($User in $Users)
{
Remove-ADGroupMember -identity $User.ADGroup -Members $User.SAMAccountName
}
Desired:
foreach ($Group in $Users)
{
Remove-ADGroupMember -identity $Group.ADGroup -Members $Group.MultipleSAMAccountNames
}
Thanks in advance
Try this:
$Users = Import-CSV "Users.csv"
$Groups = $Users.ADGroup | Sort-Object -Unique
foreach ($Group in $Groups) {
Remove-ADGroupMember -identity $Group -Members ($Users | Where-Object { $_.ADGroup -eq $Group }).SamAccountName
}
Gets a unique list of the groups in the CSV.
Loops through each unique group and uses Where-Object to filter $Users for any users that match that group, the result of which is then sent to the -Members parameter.
Note this is untested code, so use with care.
Mark Wragg beat me to it, but here's my (also untested) solution without the need for a Where-Object clause:
Import-Module ActiveDirectory
# read the CSV file and group the objects by the 'ADGroup' property
$UsersAndGroups = Import-CSV "Users.csv" | Group-Object -Property ADGroup
# loop through the groups
foreach ($group in $UsersAndGroups) {
# get an array of users belonging to this group
$accounts = $group.Group | Select-Object -ExpandProperty SAMAccountName -Unique
# remove them all from the group
Remove-ADGroupMember -Identity $group.Name -Members $accounts
}
For testing purposes, add the -WhatIf switch at the end of the Remove-ADGroupMember command.

Resources