I want to create a powershell script that checks a users profile which security groups the user belongs to inside the active directory. Then I want to write it to a file.
I'm having trouble solving this problem.
Example of the expected output.
User1
Security Groups
Domain users
Domain admins...
User2
Security Groups
Domain users
Enterprise admins
New-Item "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
$users = #("User1", "User2", "User3", "User4")
foreach ($user in $users){
Get-ADPrincipalGroupMembership $user | sort name | select name | Out-File "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
}
I imagine you could get a bit more creative with it but this could definitely work for you:
$users = #("user1","user2")
foreach ($user in $users){
$groups = Get-ADPrincipalGroupMembership $user | Where-Object {$_.GroupCategory -eq "Security"} | Sort-Object Name | Select-Object -ExpandProperty Name
Add-Content -Path C:\path\to\file.txt -Value #"
$user
Security Groups
----------------------------
"#
foreach ($group in $groups){
Add-Content -Path C:\path\to\file.txt -Value $group
}
}
This is what the output looks like:
user1
Security Groups
----------------------------
Administrators
Domain Admins
user2
Security Groups
----------------------------
Administrators
Domain Admins
I think it will be something like this:
$users = #("User1", "User2", "User3", "User4")
$file= "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
""| Out-File $file; #Clear content of file
foreach ($user in $users){ ""| Out-File -Append $file; #Add a new line
"$User is in Security groups:"| Out-File -Append $file; # making a Title
"---------------------------------"| Out-File -Append $file; # making a Title
Get-ADPrincipalGroupMembership $user | sort Name | ft -HideTableHeaders Name | Out-File -Append $file #Writing data
}
The txt file will be replaced each time, when running script.
Related
I want to compare all shared mailboxes in Exchange online with members in a Azure sec group and import the difference in the Azure sec group. I believe it fails somewhere in the last 3 rows. It is for a backup solution and I am not the creator of the code.
Get-EXORecipient -ResultSize unlimited -RecipientTypeDetails "SharedMailbox" | select PrimarySMTPAddress | Export-Csv "C:\Users\mnym\Downloads\Sharedmailboxes\sharedmailboxes.csv"
$GroupMembership = Get-AzureADGroupMember -ObjectId "group id" -top 10000 | Select-Object #{Name="PrimarySMTPAddress";Expression={$_.userprincipalname}} | Export-Csv "C:\Users\mnym\Downloads\Sharedmailboxes\Groupmembership.csv"
$File1 = Import-Csv -Path "C:\Users\mnym\Downloads\Sharedmailboxes\sharedmailboxes.csv"
$File2 = (Import-Csv -Path "C:\Users\mnym\Downloads\Sharedmailboxes\Groupmembership.csv").PrimarySMTPAddress
$File1 | where-object{$_.PrimarySMTPAddress -notin $File2} | Export-csv -path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv"
$Diff = Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv"
The file difference.csv is populated and formatted as
A
#TYPE Selected.System.Management.Automation.PSCustomObject
PrimarySmtpAddress
x#domain.com
$UserObjectId = Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv" | ForEach-Object {get-azureaduser -searchstring $_.PrimarySmtpAddress}
$Userobjectid | select objectid | export-csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\userobjectid.csv"
The file userobjectid.csv is empty after above command :(
Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\userobjectid.csv" | ForEach-Object {Add-AzureADGroupMember -ObjectId "group id" -Refobjectid $_.objectid}
I tried to import the difference.csv but I can't seam to get the Refobjectid to match the CSV, I get "Cannot bind argument to parameter 'RefObjectId' because it is null".
Don't use your file system as a variable registry - there's no need to write data to a CSV file only to read it straight back into memory :)
Your code could be as simple as:
# Define the target group id
$groupID = "group id"
# Start by creating a set of all email addresses that are already members of the security group
$securityGroupMembers = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
Get-AzureADGroupMember -ObjectId $groupID -Top 10000 |ForEach-Object {
[void]$securityGroupMembers.Add($_.PrimarySMTPAddress)
}
# Then fetch the shared mailbox and check if they're already members of the group
Get-EXORecipient -ResultSize unlimited -RecipientTypeDetails "SharedMailbox" |ForEach-Object {
if(-not $securityGroupMembers.Contains($_.PrimarySMTPAddress)){
# Add shared mailbox to group
Add-AzureADGroupMember -ObjectId $groupID -Refobjectid $_.ObjectId
}
}
I am trying to get list of AD groups a user is part of and I have a script that works. But I need to show it in a different manner. Currently the script shows a record in one line with username and then multiple group names in the next cell delimited by a semi-colon.
I would like it in a way that all groups are in each seperate row and the username gets repeated.
Example:
DavidChow - Server Admin Group
DavidChow - Desktop Admin Group
DavidChow - Azure Admin Group
NinaChow - Desktop User Group
This is my script:
$UnameList= Import-Csv C:\temp\users_full_list.csv
ForEach ($username in $UnameList){
$groups=Get-ADPrincipalGroupMembership -Identity $username.Identity | select -expand name
$data = [PSCustomObject]#{
samaccountname = $username.Identity
count = $groups.count
memberOf = ($groups -join ';')}
Write-Output $data | Export-Csv C:\Temp\users_full_list_memberships.csv -Delimiter ";" -NoTypeInformation -Append
}
You could create a "data" object for each group of each user, and then export all to CSV at the end:
Import-Csv C:\temp\users_full_list.csv | foreach {
$identity = $_.Identity
Get-ADPrincipalGroupMembership -Identity $identity | foreach {
[PSCustomObject]#{
SamAccountName = $identity
GroupName = $_.Name
}
}
} | Export-Csv C:\Temp\users_full_list_memberships.csv -Delimiter ";" -NoTypeInformation
I'm looking to export some data, in particular an AD user along with their AD groups.
My current code:
$users = import-csv -path C:\path
foreach ($user in $users) {
$user | select name,SamAccountName | ft
Get-ADPrincipalGroupMembership $user.samaccountname | select name
#export-csv -path C:\path-NoTypeInformation -Append
}
The issue i'm having is whenever I try to export this information i'm only exporting the group output whereas I need the username to see who these groups actually belong to.
Perhaps there's a better method to achieve this?
You may want to use Select-Object to sort of "bind" the information together with a couple of calculated properties referencing the current $user's properties:
foreach ($user in $users) {
Get-ADPrincipalGroupMembership $user.samaccountname |Select Name,#{Name='User';Expression={$user.Name}},#{Name='SAMAccountName';Expression={$user.SAMAccountName}} |Export-Csv -Path C:\path -NoTypeInformation -Append
}
If you want to group the output in the shell by user name but only display the group name, you can use Format-Table Name -GroupBy User:
# collect the information
$groupMemberships = foreach ($user in $users) {
Get-ADPrincipalGroupMembership $user.samaccountname |Select Name,#{Name='User';Expression={$user.Name}},#{Name='SAMAccountName';Expression={$user.SAMAccountName}}
}
# format console output
$groupMemberships |Format-Table Name -GroupBy User
# export
$groupMemberships |Export-Csv -Path C:\path -NoTypeInformation -Append
I have simple csv file with column 'logins'
logins
john
mark
maria
...
Have powershell script to check their last logontime:
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName)
{
$time = 0
$user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
if($user.LastLogon -gt $time)
{
$time = $user.LastLogon
}
$dt = [DateTime]::FromFileTime($time)
Write-Host $username $dt }
import-csv -Encoding UTF8 -path C:\scripts\loginy.csv | foreach {
Get-ADUserLastLogon -UserName $_.logins
}
This works fine with output
john 2018-05-10 14:11:28
mark 2018-11-29 14:26:58
maria 2018-11-02 11:14:17
...
When I try to export results it to csv file by code
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
$results = #()
foreach ($_.logins in $users) {
$results += Get-ADUserLastLogon -UserName $_.logins
}
$results | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
getting error
At C:\scripts\OstatnieLogowanie.ps1:19 char:12
+ foreach ($_.logins in $users) {
+ ~
Missing 'in' after variable in foreach loop.
At C:\scripts\OstatnieLogowanie.ps1:19 char:29
+ foreach ($_.logins in $users)
}
I can't get it work over 2 hours :/
Edit: I've confused LastLogon and LastLogonTimestamp. LastLogonDate is based on LastLogonTimestamp. The differences between these properties are explained here and here. I will come back and update my answer.
You're using Write-Host to output data:
Write-Host $username $dt
This won't work. Write-Host means "write to the console screen, not to standard output." That will work just fine if you're trying to display data, but calling $x = Get-ADUserLastLogon -UserName $login will print the results to the console screen and nothing would be assigned to the $x variable. For example:
PS C:\> $x = Write-Host 0
0
PS C:\> $x
PS C:\>
See how Write-Host still wrote to the console and $x doesn't have a value?
Your function should look something like $username, $dt or Write-Output $username, $dt or return $username, $dt.
Although that's still not really going to work like you want. I would probably use a custom object (see Get-Help about_Object_Creation -ShowWindow) like this:
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName) {
$user = Get-ADUser $userName -Properties LastLogonDate
[PSCustomObject]#{'Logins' = $username; 'LastLogonDate' = $user.LastLogonDate}
}
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
$results = foreach ($user in $users) {
Get-ADUserLastLogon -UserName $user.logins
}
$results | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
Frankly, however, if I were doing what you're trying to do here, my actual code would look like this:
Import-Csv -Encoding -Path C:\scripts\loginy.csv |
Select-Object -ExpandProperty logins |
Get-ADUser -Properties LastLogonDate |
Select-Object #{n = 'Logins'; e = {$_.SamAccountName}}, LastLogonDate |
Export-Csv -Path C:\scripts\Eksporty\logowania.csv -Encoding UTF8 -NoTypeInformation
Select-Object -ExpandProperty logins will pass just the bare value of the logins column. Get-ADUser accepts identities from the pipeline, and it fetches the LastLogonDate for each user, as long as the SamAccountName (a default property) which is the logon name.
The next line, Select-Object #{n = 'Logins'; e = {$_.SamAccountName}}, LastLogonDate uses a calculated property (See the examples in Get-Help Select-Object -ShowWindow) to rename the SamAccountName property in a column named Logins. You could use Select-Object SamAccountName, LastLogonDate if you don't care about the column name. And the -NoTypeInformation parameter on Export-Csv just keeps it from adding that annoying "#TYPE System.Management.Automation.PSCustomObject" nonsense on the first line.
$_ is the variable for the current value in pipeline. In your second part of code, since you don't have a pipeline, hence $_ is empty and doesn't have any property/method associated with it.
What you can do is -
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
foreach ($user in $users) {
Get-ADUserLastLogon -UserName $user.logins | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
}
OR
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
foreach ($_ in $users) {
Get-ADUserLastLogon -UserName $_.logins | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
}
Although I would recommend not using the latter since $_ is an automatic variable $PSItem and beside you can have plenty other names for a variable which are not keywords, functions etc.
The use of += to extend an array requires creating a new instance behind the scenes in every iteration.
I'm trying to export some group memberships all to one CSV file so I can find users who are not in our domain. Everything works great, but when all the outputs get appended I can't see what group each entry is in. Here's what I have now.
$Groups = import-csv "C:\users\USER\desktop\secgroupinput2.csv"
foreach($item in $Groups)
{
Get-ADGroupMember -Server "SERVERDC" -Identity $item.directoryname | export-csv "C:\users\USER\desktop\realexport.csv" -Append
}
How can I add a row between appends with the group name, likely from the import?
Thanks!
I did something similar in the past. Hope this code helps :
Function ADGroupMembers
{
$group = get-content C:\Pshell\PM\group.txt
$i =25
do{
if (get-QADgroup $group[$i] -Empty 0)
{write-output ''; Write-Output -inputobject "The $($group[$i]) group members :"; write-output '';
get-QADGroupMember $group[$i] -IncludeAllProperties | Format-Table -AutoSize DisplayName, Type, Office, Company, Department, Title, WhenCreated | Out-String -Width 4096;
write-output ''}
else {Write-Output -inputobject "*** Member not found in the $($group[$i]) group!"; write-output ''}
$i +=1}
while ($i -ne $group.length)
}
ADGroupMembers | out-File 'c:\Pshell\PM\groupmemberdetails.txt'