I have a list of users and I want to export their group names, sorted A-Z. The following script is not working in the inner ForEach-Object loop.
Get-Content users.txt | ForEach-Object {
$user = $_;
Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | sort
ForEach-Object {
New-Object PSObject -property #{User=$user;Group=$_;}
}
} | Export-Csv -Path 'your_file_path.csv' -NoTypeInformation
The ForEach-Object is just sitting out there alone--you have to either pipe an object to it, or assign the object to a variable and use foreach to loop through the object instead. I took the second approach below as excessive piping makes scripts difficult to read (for me).
Get-Content c:\temp\users.txt | ForEach-Object {
$user = $_;
$AdUser = Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | get-adgroup | select -ExpandProperty Name | sort
foreach($group in $AdUser) {
New-Object PSObject -property #{User=$user;Group=$group;} | Export-Csv -Path 'c:\temp\out.csv' -NoTypeInformation -Append
}
}
...and if you want to pipe it and use ForEach-Object, you just need to put a pipe after the sort and move the Export-Csvso that it exports the new object that was created:
Get-Content c:\temp\users.txt | ForEach-Object {
$user = $_;
Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | get-adgroup | select -ExpandProperty Name | sort |
ForEach-Object {
New-Object PSObject -property #{User=$user;Group=$_;} | Export-Csv -Path 'c:\temp\out.csv' -NoTypeInformation -Append
}
}
Related
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 (#()).
I wrote a search function, which searches for some active directory attributes. I now want to export the content to a .csv file. If I see it correctly, the whole output is a hash table. But when I try to use the GetEnumerator() function, it doesn't do anything.
Can someone help and maybe explain what I did wrong? The code is below. Thanks in advance!
Import-Module ActiveDirectory
$users = Get-ADUser -Filter { employeeNumber -notlike '*' } -Properties memberOf, samAccountName | ForEach-Object -Process { #{ $_.samAccountName = $_.memberOf | Where-Object { $_ -like '*DAT*' } } }
$users.GetEnumerator() |
Select-Object -Property #{N='AD1';E={$_.Key}},
#{N='AD2';E={$_.Value}} |
Export-Csv -NoTypeInformation -Path H:\test123.csv
If you look at your code, you are creating a list of hashtables that contains your SamAccountName and Groups. But, when you use the enumerator, you are only thinking about the hashtable and not the list you created.
This is how you can iterate through a hashtable. You first create a hash table and add all elements to it.
$hash = #{}
Get-ADUser -Filter { employeeNumber -notlike '*' } -Properties memberOf, samAccountName | ForEach-Object -Process { $hash.Add($_.samAccountName, ($_.memberOf | Where-Object { $_ -like '*DAT*' })) }
$hash.GetEnumerator() |
Select-Object -Property #{N='AD1';E={$_.Key}},
#{N='AD2';E={$_.Value}} |
Export-Csv -NoTypeInformation -Path H:\test123.csv
Or you can continue with the list of hashtables but change how you are accessing the data. Each element of your list is a single hashtable with Keys (only one in it).
$users = Get-ADUser -Filter { employeeNumber -notlike '*' } -Properties memberOf, samAccountName | ForEach-Object -Process { #{ $_.samAccountName = $_.memberOf | Where-Object { $_ -like '*DAT*' } } }
$users.GetEnumerator() |
Select-Object -Property #{N='AD1';E={$_.Keys[0]}},
#{N='AD2';E={$_.Values[0]}} |
Export-Csv -NoTypeInformation -Path H:\test123.csv
I try to get result from this part of my powershell scrip into Clixml.
I'm just beginner in powershell so i have kind of problem using arrays.
I'm unable to get result of this script into file.
$groupname = "Domain Admins"
$users = Get-ADGroupMember -Identity $groupname | ? {$_.objectclass -eq "user"}
foreach ($activeusers in $users) { Get-ADUser -Identity $activeusers | ? {$_.enabled -eq $true} |
select-object SamAccountName | Sort-Object -Descending | select-object SamAccountName }
Here is code used for export to Clixml
Export-Clixml -Path 'C:\TEMP\CurrentDomainAdmins3.xml'
You aren't assigning the result of foreach () {} to any variable, e.g. $results = foreach () {} and you cannot pipe the output of that style of loop to another cmdlet.
I don't think you need a loop for it at all; you could rewrite it like this:
$groupName = 'Domain Admins'
Get-AdGroupMember -Identity $groupName |
where-Object -Property ObjectClass -eq -Value User |
Get-AdUser |
Where-Object -Property Enabled |
Export-Clixml -Path 'C:\TEMP\CurrentDomainAdmins3.xml'
or for a more interactive style:
AdGroupMember 'Domain Admins' | ? ObjectClass -eq User | AdUser | ? Enabled
I'm trying to export the username and the user's group membership (of specifc groups) to a CSV file using Export-Csv. However, I couldn't accomplish this using several approaches.
My current script works fine but the output is shown on the PowerShell console alone:
$accounts = Get-Content "C:\Scripts\getUserGroups\users.txt"
foreach ($account in $accounts) {
"$account member of:"
Get-ADPrincipalGroupMembership -Identity $account |
select Name |
Where-Object { $_.name -like 'Browsing_Group*' } |
Sort Name
}
I want to export it to a file in an ordered manner:
UserName1
group membership
UserName2
group membership
etc...
I've tried to add to a variable but probably didn't do that correctly:
$ArrList = [System.Collections.ArrayList]#()
$accounts = Get-Content "C:\Scripts\getUserGroups\users.txt"
foreach ($account in $accounts) {
$ArrList.Add($account)
$groups = Get-ADPrincipalGroupMembership -Identity $account |
select Name |
Where-Object {$_.name -like 'Browsing_group*' } |
Sort Name
$ArrList.Add($grops)
}
Might be a different approach.
You need to build custom objects in order to export the data to a CSV via Export-Csv. The 2 main ways of doing that are:
using calculated properties:
$accounts |
Select-Object #{n='Username';e={$_}}, #{n='Groups';e={
(Get-ADPrincipalGroupMembership -Identity $_ |
Select-Object -Expand Name |
Where-Object {$_ -like 'Browsing_group*' } |
Sort-Object) -join ';'
}} |
Export-Csv 'C:\path\to\output.csv' -NoType
building custom objects directly:
$accounts | ForEach-Object {
$groups = Get-ADPrincipalGroupMembership -Identity $_ |
Select-Object -Expand Name |
Where-Object {$_ -like 'Browsing_group*' } |
Sort-Object
New-Object -Type PSObject -Property #{
'Username' = $_
'Groups' = $groups -join ';'
}
} | Export-Csv 'C:\path\to\output.csv' -NoType
With PowerShell version 3 or newer you can replace New-Object with the [PSCustomObject] type accelerator:
[PSCustomObject]#{
'Username' = $_
'Groups' = $groups -join ';'
}
I'm trying to collect folder permissions to a csv file with Powershell. My problem is that I'd need the results to contain both the SamAccountName and FileSystemRights.
I tried two different method. The first I came up with was a simple approach that gave me IdentityReference and FileSystemRights, but I couldn't find any working method that can get SamAccountName from IdentityReference.
The second one I found on the internet was much more sophisticated. It collects all the accounts that has access to the folder, but it doesn't show FileSystemRights and I couldn't figure out how to change it to do so.
My own solution
(Get-Acl "FolderPath").Access | Select-Object IdentityReference, FileSystemRights
The solution I found
Get-Acl $UncPath | Select-Object -ExpandProperty Access | Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } | Select-Object -ExpandProperty IdentityReference | ForEach-Object { $_.Translate('System.Security.Principal.SecurityIdentifier').Value } | Get-ADGroup -ErrorAction SilentlyContinue | get-adgroupmember | select-object SamAccountName | Format-Table | Out-String
Is there any working method that can get me a result where I can see SamAccountName and FileSystemRights?
Thank you in advance.
$UncPath = 'E:\temp\test'
$all = Get-Acl $UncPath |
Select -ExpandProperty Access |
Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } |
Select-Object #{ Name = 'Identity'; Expression = { $_.IdentityReference -replace "\w+\\(.+)", '$1' } }, FileSystemRights
# Here you can get Users ACL
$distinct_users = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADUser -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# Here we will expand group acls
$groups = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADGroup -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# now we will get groups membership
$group_users = #()
Foreach($group in $groups){
Get-ADGroupMember -Identity $group.Identity | ForEach-Object { $group_users += [PSCustomObject]#{
'Identity' = $group.Identity
'sAMAccountName' = $_.sAMAccountName
'FileSystemRights' = $group.FileSystemRights
} }
}
$everyone = $distinct_users + $group_users
$everyone | Export-Csv -Path D:\example.csv
Check $everyone variable it will contain 3 columns: Identity as it was in the ACL, sAMAccountName and FileSystem Rights.