Display All Disabled ADUsers and their ADGroup Membership - powershell

I am trying to create a script that will do the above,
I did something like that:
Search-ADAccount -AccountDisabled | Export-Csv -Path C:\csv\DisabledUsers.csv -NoTypeInformation
$csv = Import-Csv -Path c:\csv\DisabledUsers.csv
foreach ($SamAccountName in $csv)
{
Get-ADPrincipalGroupMembership | format table | Export-Csv -Path C:\csv\DisabledUsersGroupM.csv -NoTypeInformation
}
It is work fine until the foreach part. Seems like no values imported from the CSV.
I get this:
cmdlet Get-ADPrincipalGroupMembership at command pipeline position
Supply values for the following parameters:
(Type !? for Help.)
Identity:
What am I doing wrong?

You're calling Get-ADPrincipalGroupMembership without a required parameter (the identity of the object whose group membership you want to obtain).
Change
Get-ADPrincipalGroupMembership
to
Get-ADPrincipalGroupMembership $SamAccountName
Also, the Export-Csv inside the loop would overwrite the output file with every iteration, so you'd end up with just the groups of the last user. Add the parameter -Append to avoid this.
With that said, a much simpler approach would probably be a pipeline like this:
Search-ADAccount -AccountDisabled |
Select-Object SamAccountName, #{n='Groups';e={(Get-ADPrincipalGroupMembership $_.SamAccountName | Select-Object -Expand Name) -join ';'}} |
Export-Csv 'C:\csv\DisabledUsers.csv' -NoType

Related

How to pipe results of a foreach loop to an output file?

I have the following code that gets usernames from a list and then retrieves their emails.
I'd like to have this outputted to eventually send automatic emails to these specific addresses.
With the code below, only the last object in the text file is recorded in the outfile.
$users = (get-content c:\temp\Fredro.txt)
foreach ($EUT in $users) {
Get-ADUser -Identity $EUT | Select-Object UserPrincipalName | Out-File -filepath C:\temp\exomailinglist.txt}
How to pipe results of a foreach loop to an output file?
You are overwriting the file on every pass through your foreach loop if an ADUser is found. As Abraham Zinala mentioned in comments if you were to add -Append to the Out-File cmdlet this would solve your problem of the file only containing the last item. I would also recommend adding -ExpandProperty to Select-Object to avoid having the header "UserPrincipalName" also added to the file each time.
$users = (Get-Content c:\temp\Fredro.txt)
foreach ($EUT in $users) {
Get-ADUser -Identity $EUT |
Select-Object -ExpandProperty UserPrincipalName |
Out-File -FilePath C:\temp\exomailinglist.txt -Append
}
Rather than writing to the file in the foreach loop for each user though I would instead recommend to capture all ADUsers first and then write all of the items at once to the file, possibly like this:
$users = (Get-Content c:\temp\Fredro.txt)
$adUsers = foreach ($EUT in $users) {
Get-ADUser -Identity $EUT |
Select-Object -ExpandProperty UserPrincipalName
}
$adUsers | Out-File -FilePath C:\temp\exomailinglist.txt
And lastly, the best option in my opinion, combine it all into one pipeline which would look like this.
Get-Content c:\temp\Fredro.txt |
Get-ADUser |
Select-Object -ExpandProperty UserPrincipalName |
Out-File -FilePath C:\temp\exomailinglist.txt
This method would avoid the foreach loop completely. Get-ADUser accepts Identity from the pipeline byvalue so we can just pipe each line from Get-Content directly. Out-File will wait on all items from the pipeline before writing to the file.

Filter enabled AD users from CSV file

I have a script to import a list of users and want to check if any of these users are disabled. I did try to run the script below but it doesn't filter the users in the CSV file it filters everyone in the entire organization. any suggestions would be appreciated. displayname and SIP address in one of the headers in the CSV file if needed to use the header.
Import-CSV -Path .\Piscataway-+1732.csv | ForEach-Object {
Get-ADUser -Filter "Enabled -eq '$true'" | select Enabled,EmailAddress,SamAccountName
} | Export-CSV .\results77.csv -NoTypeInformation
You have several issues:
You are piping From Import-Csv to ForEach-Object. So Get-ADUser doesn't really know you are piping it input objects.
Get-ADUser's -Identity parameter is by value, not by property name. so you need to echo the appropriate column to send it down the pipe.
If you pipe and use the -Filter parameter the filter is going to apply to the whole domain. It's not going to limit the filter to what you piped in.
If you want the email address to be output you have to tell Get-ADUser to retrieve it.
Try something like this:
Import-CSV -Path .\Piscataway-+1732.csv |
ForEach-Object{ $_.samAccountName }
Get-ADUser -Properties mail |
Where-Object{ $_.Enabled }
Select-Object Enabled,mail,SamAccountName |
Export-CSV .\results77.csv -NoTypeInformation
Note: The Property for the email address is "mail".
Note: Since we don't have a sample of the CSV file the above example
assumes there's a column names samAccountName.
Now, if you want the output to come from the CSV file but validate it according to the user's status in AD we have to change the approach. As always there are several ways to do this.
Example 1:
Import-CSV -Path "c:\temp\test.csv" |
Select-Object #{Label = 'Enabled'; Expression = { ( Get-ADUser $_.samAccountName ).Enabled } },EmailAddress,samAccountName |
Export-CSV -Path "c:\temp\Output.csv" -NoTypeInformation
This again assumes the column name (samAccountName). It also assumes there is not already an "enabled" column. So we are adding a property called enabled that we're getting via Get-ADUser. Then finally re-exporting to Csv.
Example 2:
$CsvData = Import-CSV -Path "c:\temp\test.csv"
$EnabledUsers =
(
$CsvData |
ForEach-Object{ $_.samAccountName } |
Get-ADUser |
Where-Object{ $_.Enabled }
).samAccountName
$CsvData |
Where-Object{ $EnabledUsers -contains $_.samAccountName } |
Select-Object #{Label = 'Enabled'; Expression = { $true } },EmailAddress,samAccountName |
Export-Csv -Path "c:\temp\Output.csv" -NoTypeInformation
Example 1 is great for small jobs but too many individual calls to Get-ADUser might be slow for larger runs. In this example Import the CSV data once. Then use it to get a flat list of those entries that are enabled in AD. Once you have that you can use the -contains operator to check if the account is enabled. Once again there's a little extra work to add the "Enabled" property.
This should give you a general idea. There are probably a dozen more ways to do this, but hopefully this give you a good idea of what has to happen. Let me know if this helps.

Exporting Membership groups for users from input file

I have this script that reads samaccountnames from a file and outputs the name of the user with its membership information. However, the output file only shows the last record. It seems that my code is overwriting the previous record. What am I missing? Thank you so much.
ForEach ($user in $(Get-Content -Path C:\MyScripts\UsersInput.csv))
{
$username = Get-ADUser –Identity $user -Properties *
Get-ADPrincipalGroupMembership $user | select $username.DisplayName, name |
export-csv "C:\MyScripts\UsersAndTheirADGroups.csv" -NoTypeInformation
}
Export-Csv has an -append parameter, so you could use that. ie it would append to the csv file with every iteration of the loop. You would need to make sure the file didn't exist before you start the loop or it would just get bigger and bigger each time you ran the code.
Another way it to add the items to an object and then export that at the end. ie $username += Get-ADUser......
You are reading a CSV file using Get-Content. This lets me think the file is simply a list of user SamAccountNames, each on a separate line. No headings.
Something like this perhaps:
jdoe
jsmith
If that is the case, read the input file like this:
$users = Get-Content -Path 'C:\MyScripts\UsersInput.csv'
To get an array of user SAMAccountnames.
If however it is a proper CSV file with headers, looking something like this:
"SamAccountName","Email","More","Stuff"
"jdoe","john.doe#yourdomain.com","blah","blah"
"jsmith","jane.smith#yourdomain.com","blah","blah"
Then you should use the Import-Csv cmdlet to get the entries as objects and obtain an array of SamAccountNames from that:
$users = Import-Csv -Path 'C:\MyScripts\UsersInput.csv' | Select-Object -ExpandProperty SamAccountName
Once you have that array, loop through it and get the group membership info for each user
Untested
$result = foreach ($accountName in $users) {
Get-ADUser –Identity $accountName -Properties DistinguishedName, DisplayName |
Select-Object #{Name = 'User'; Expression = {$_.DisplayName}},
#{Name = 'Groups'; Expression = { ( $_ | Get-ADPrincipalGroupMembership | Select-Object -ExpandProperty name) -join ', '}}
}
$result | Export-Csv "C:\MyScripts\UsersAndTheirADGroups.csv" -NoTypeInformation
You are indeed overwriting the code ForEach user. You included Export-Csv in the ForEach. Instead export the whole array that ForEach creates:
ForEach ($user in $(Get-Content -Path C:\MyScripts\UsersInput.csv))
{
$username = Get-ADUser –Identity $user -Properties *
Get-ADPrincipalGroupMembership $user | select $username.DisplayName, name
} | export-csv "C:\MyScripts\UsersAndTheirADGroups.csv" -NoTypeInformation

Rename group in column A to group in column B

I am trying to get a script together to rename about 40 security groups. I have imported them all into a csv in column A and put the name I need them changed to in column B. here is what I have so far.
Import-Csv C:\test.csv | ForEach-Object{
$item = $_;
Get-ADGroup -LDAPFilter "(&(sAMAccountName=$($_.OriginalName)))" | Set-ADGroup -OriginalName $item.Renameto
}
Thank you very much for all your help!
Import-Csv C:\test.csv | ForEach-Object{Rename-ADObject -Identity $_.ColumnAHeader -NewName $_.ColumnBHeader}
If possible, use the DistinguishedName in Column A. Otherwise you may have to use the partition parameter to specify the groups location.
You may have to remove Protect Object from accidental deletion. If so, try this:
Import-Csv C:\test.csv | ForEach-Object{
Set-ADObject -Identity $_.ColumnAHeader -ProtectedFromAccidentalDeletion:$false
Rename-ADObject -Identity $_.ColumnAHeader -NewName $_.ColumnBHeader -PassThru | Set-ADObject -ProtectedFromAccidentalDeletion:$true
}

get displayname and office from samaccountname export to csv

How I can get the displayname and the office from a samaccountname list (.txt)? After that I want to save the displaynames and the offices to a .csv file. Here is a approach:
$users = Get-Content C:\TMP\test.txt
foreach ($user in $users)
{
Get-ADUser -ldapfilter "(samaccountname=$user)" -Property name, office | Select-Object -Property Name, Office
}
It should look like:
Hope you can help me?
You are asking for the Export-CSV command but from your comments you might be having issues with placement or your construct of foreach.
Lets try this then
$users = Get-Content C:\TMP\test.txt
$users | ForEach-Object {
Get-ADUser -ldapfilter "(samaccountname=$_)" -Property name,office | Select-Object -Property Name,office
} | Export-Csv -Path C:\temp\export.csv -NoTypeInformation
Update from comments
Was having issues understanding your output from the comments which was why I wanted more that just a picture of the headers. I don't an issue with this code and the text should be quoted so special characters, like commas, should not be an issue. Please update you question with the text content of a sample file and your PowerShell version in case that is coming into play.
Use the delimiter parameter at the end
$users = Get-Content C:\TMP\test.txt
$users | ForEach-Object {
Get-ADUser -ldapfilter "(samaccountname=$_)" -Property name,office | Select-Object -Property Name,office
} | Export-Csv -Path C:\temp\export.csv -NoTypeInformation -Delimiter ";"