Im trying to run the below code that compares the user and group and confirms if the user is a member of the group. But i'm unable to export the output to an excel.
$users = gc .\UserInfo.csv
$groups = gc .\groupInfo.csv
$outputFilePath = "C:\Users\salesid.csv"
$members = foreach ($group in $groups) {Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName
foreach ($user in $users) {
If ($members -contains $user) {
$a = write-host "$user is a member of $group"
} Else {
$a = Write-Host "$user is not a member of $group"
}
}
}
$a| Export-Csv .\Output.csv -NoTypeInformation
Read-Host -Prompt "Press Enter to exit"
To output as CSV file you can open in Excel, you need to output objects in the loop, not strings:
$users = Get-Content .\UserInfo.csv
$groups = Get-Content .\groupInfo.csv
$outputFilePath = "C:\Users\salesid.csv"
# loop through the groups; collect all output in $result
$result = foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select-Object -ExpandProperty SamAccountName
# loop through the users array and outout objects that get collected in variable $result
foreach ($user in $users) {
[PsCustomObject]#{
Group = $group
User = $user
IsMember = ($members -contains $user) # True or False in the output
}
}
}
$result | Export-Csv -Path $outputFilePath -UseCulture -NoTypeInformation
If the amount of data is too large to handle in memory, the following code should work, BUT will be slower because of all the extra disk-write actions:
# loop through the groups
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select-Object -ExpandProperty SamAccountName -Unique
# loop through the users array and outout objects that get collected in variable $result
foreach ($user in $users) {
$isMember = "$user is {0}a member of $group" -f $(if ($members -contains $user) {''} else {'NOT '})
[PsCustomObject]#{
Group = $group
User = $user
IsMember = $isMember
} | Export-Csv -Path $outputFilePath -UseCulture -Append -NoTypeInformation
}
}
switch -UseCulture makes sure the delimiter character is the same your local Excel will understand. This might be the default comma, but perhaps your system uses the semi-colon as list seoarator
Related
I am having the below code which is giving me the list of ad groups a specific user is part of
Get-Content "C:\Automation Scripts\users.txt" | Get-ADUser | ForEach{
$user = $_
$groups = Get-ADPrincipalGroupMembership $user
$groups | %{ New-Object PSObject -Property #{ User = $user.SamAccountName; Group = $_.SamAccountName } }
} | Export-Csv "C:\Automation Scripts\User_Groups.csv" -NoTypeInformation
It is working fine and I am getting the result, but the result is coming like below
"User","Group"
"A92M7202822","Domain Users"
"A92M7202822","A92GS-505-Central Team Data"
"A92M7202822","A00GRP-AdminAccounts"
"A92A7803642","Protected Users"
"A92A7803642","A00GRP-AdminAccounts"
I need the result in csv like below
User,Group
A92M7202822,"Domain Users
A92GS-505-Central Team Data
A00GRP-AdminAccounts
A92GS-505-Ids-Analytics-Share-A92DFS
A92GS-505-Data-DSICF-DEV
A92GS-505-Data-DSICF-PRD
CFRGRP-FS-FR4000_SSgt_CFIDS_RW"
A92A7803642,"Domain Users
Protected Users
A00GRP-AdminAccounts"
One cell for user and next cell should have all the groups in it.
Please let me know what changes need to be done for this
Try not to use New-Object, instead you can use PSCustomobject. Also, in your script you have used $user.samaccountname as values for both User and Groups. I have replaced group name value with name you may modify it.
$output = #()
$output += Get-Content "C:\Automation Scripts\users.txt" | Get-ADUser | ForEach{
$user = $_
$groups = Get-ADPrincipalGroupMembership $user
[PSCustomObject]#{
'User'= $user.SamAccountName
'Group' = $groups.Name
}
}
$output | Export-Csv "C:\Automation Scripts\User_Groups.csv" -NoTypeInformation
And another efficient way of doing this is like:
$users = Get-Content "C:\Automation Scripts\users.txt"
$output = foreach ($user in $users)
{
$groups = Get-ADPrincipalGroupMembership $user
foreach($group in $groups)
{
[PSCustomObject]#{
User = $user
Group = $group.Name
}
}
}
$output | Export-Csv "C:\Automation Scripts\User_Groups.csv" -NoTypeInformation
I'm looking to export users with their groups in Active Directory through powershell, but I can't seem to get the pipe to work for some reason the powershell script I'm using right now is
`
$groups = get-adgroup -filter *
foreach ($group in $groups) {
$naam = $group.name
$members = Get-ADGroupMember -identity $group
write-host “Group: $naam”
write-host “————————————-”
foreach ($member in $members) {
$memnaam = $member.samaccountname
write-host “$naammem”
}`
I just can't seem to figure this out any recommendations?
`
$groups = get-adgroup -filter *
foreach ($group in $groups) {
$naam = $group.name
$members = Get-ADGroupMember -identity $group
write-host “Group: $naam”
write-host “————————————-”
foreach ($member in $members) {
$memnaam = $member.samaccountname
write-host “$naammem”
} | Export-CSV c:\FileName.csv`
Check for typos in variable names (you have one) and that you've closed all parentheses and braces. Even better, don't use variables where not needed:
$groups = get-adgroup -Filter *
# If you save your search as an object you won't need to re-run it multiple times to use the data
Write-Host "Processing groups"
$SearchResult = $Groups | ForEach-Object {
$GroupName = $_.Name
# Some simple error trapping
Try {
# Writing to host for informational only
Write-Host "$GroupName..." -NoNewline
$Members = (Get-ADGroupMember -Identity $_ -ErrorAction Stop).SamAccountName
}
Catch {
$Members = $_
}
# Output results as an object
[pscustomobject]#{
Group = $GroupName
Members = $Members
}
Write-Host "Done"
}
Write-Host "Processing complete"
# If you want to display it in console
$SearchResult | Format-List
# Or a GridView
$SearchResult | Out-GridView
The below PowerShell script iterates through the groups listed in the test.csv file.
It pulls samAccountName and distinguishedName from each user in the various groups. However, when I try to pull groupName the output is "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection". Not sure how to fix this-
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
foreach ($group in $groups)
{
foreach ($domain in $domains)
{
if (Get-ADGroup $group -Server $domain)
{
Get-ADGroupMember $group -Server $domain | select groupName, samAccountName, distinguishedName | Export-Csv c:\temp\file.csv -notypeinformation -append
}
}
}
I have tried the below, but it just outputs an empty column instead:
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
foreach ($group in $groups)
{
foreach ($domain in $domains)
{
if (Get-ADGroup $group -Server $domain)
{
Get-ADGroupMember $group -Server $domain | select samAccountName, distinguishedName |
Get-ADUser #{name = ‘MemberOf’;’expression={$_.MemberOf -join “;”}} |
Export-Csv c:\temp\file.csv -notypeinformation
}
}
}
Try this, I added some optimization to your code :)
Note, try {...} catch {...} is more or less needed here because both cmdlets Get-ADGroup and Get-ADGroupMember will throw if the object is not found.
$ErrorActionPreference = 'Stop'
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
$result = foreach ($group in $groups)
{
foreach ($domain in $domains)
{
try
{
$adGroup = Get-ADGroup $group -Server $domain
$members = (Get-ADGroupMember $adGroup -Server $domain).where({
# Here, I assume your looking only for user objects
# since you're next cmdlet is Get-ADUser
$_.ObjectClass -eq 'user'
})
foreach($user in $members)
{
# !!! $adUser = Get-ADUser $user >> This is not needed,
# Get-ADGroupMember already brings you the samAccountName of
# each object
# Here you can cast the result, I assume
# you want your CSV to have the Name of the Group and
# the samAccountName and distinguishedName of each user
[pscustomobject]#{
GroupName = $adGroup.Name
samAccountName = $user.samAccountName
distinguishedName = $user.distinguishedName
}
}
}
catch
{
Write-Warning $_
}
}
}
$result | Export-Csv c:\temp\file.csv -NoTypeInformation
If you change your select statement to:
select-object #{n='groupName';expression={$group}}, samAccountName, distinguishedName
It should output the $group input of Get-ADGroupMember for that column.
Below embedded foreach commands needs $user to come from list.txt, dump groups from AD into $user.txt file and remove.
How do I specify $user as each line in the list.txt whild also verifying the formatting of the list inside the list.txt is just one name per line, no comma?
foreach ($user in .\list.txt) {
$groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Add-Content -Path C:\TEMP\RemoveGroups\$user.txt -Value $groups
foreach ($group in $groups) {
Remove-ADGroupMember $group -Member $user
}
$List = Get-Content .\List.txt
Foreach ($User in $List){
$Groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Foreach ($GroupDN in $Groups){
Try {
$Group = Get-ADGroup $GroupDN
Remove-ADGroupMember $Group -member $user -ErrorAction Stop
$Succeed = $Succeed,$Group.Name -join ";"
}
Catch {
$Failed = $Failed,$Group.Name -Join ";"
}
}
$temp = New-Object psobject -ArgumentList #{
User = $User
Succeed = $Succeed
Failed = $Failed
}
Export-Csv -InputObject $temp -Path C:\TEMP\RemoveGroups\Result.csv -Encoding UTF8 -NoTypeInformation -Append
}
You will get the CSV file like this:
User,Succeed,Failed
user1,Group1;Group2,Group3;Group4
user2,Group2;Group3,Group1;Group4
You can use the following code.
# Read the list of users to an array of strings.
$users = Get-Content .\list.txt
foreach ($user in $users) {
# Validate that the username only contains a-z and 0-9.
if ($user -match "^[a-zA-Z0-9]+$") {
$groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Add-Content -Path C:\TEMP\RemoveGroups\$user.txt -Value $groups
foreach ($group in $groups) {
Remove-ADGroupMember $group -member $user
}
}
}
I have a function that helps me grab over 20k users in our AllUsers group (gets ObjectClass,Name,SamAccountname,DistinguishedName). I'm trying to list anyone who has CBA-* groups, but the loop seems to repeat the output a couple of times per user (after the 1st one), when I only want one iteration (many CBA-* possibilities). Here's what I have. Also, I get errors "Get-ADPrincipalGroupMembership : The server was unable to process the request due to an internal error." Any ideas why that would happen? I'm not sure I can see why my code repeats maybe twice, but then seems to move on to the next user just fine?
ForEach ($User in $Users) {
Get-ADPrincipalGroupMembership -Identity $User.SamAccountName |
Select Name |
Where-Object {$_.Name -like 'CBA-*'} |
ForEach-Object { $User_MemberOf += #($_.Name) }
ForEach ($Group in $User_MemberOf) {
New-Object PSObject -Property #{
SID = $User.SamAccountName
Name = $User.name
Group = $Group
} | Export-Csv -Path $logs -NoTypeInformation -Append
}
}
For each loop iteration, you continue to assign values to $User_MemberOf with the addition operator (+=) meaning that for each new user it gets "sanded" more and more with the previous users' memberships.
Two ways to avoid:
Initialize $User_MemberOf as an empty array at the start of each loop iteration:
foreach($User in $Users){
$User_MemberOf = #()
Get-ADPrincipalGroupMembership -Identity $User.SamAccountName |Select -Expand Name |Where-Object {
$_ -like 'CBA-*'
} |ForEach-Object {
$User_MemberOf += $_
}
foreach($Group in $User_MemberOf){
# export to CSV
}
}
Assign output directly from pipeline:
foreach($User in $Users){
$User_MemberOf = Get-ADPrincipalGroupMembership -Identity $User.SamAccountName |Select -Expand Name |Where-Object {
$_ -like 'CBA-*'
} |ForEach-Object {
$User_MemberOf += $_
}
foreach($Group in $User_MemberOf){
# export to CSV
}
}