Export users not in an office 365 security group - powershell

I need to find users that are not in a office 365 security group. I'm not sure how to proceed after getting the list of all the users in the tenant.
This works for pulling a list of users
Get-MSOLUser -all | Where-Object { $_.isLicensed -eq "True"} | Select-Object UserPrincipalName | Export-Csv -path .\users.csv
I'm not sure where to go from here.
This is something like what I'm looking for.
Get-MSOLUser -all | Where-Object { $_.isLicensed -eq "True",-and $_.isNotMemberofGroup "SecurityGroup"} | Select-Object UserPrincipalName | Export-Csv -path .\users.csv

I don't have a way of testing this but this should be the logic you should follow with this pre-historic module, first get the list of members of your target group (in this case ExampleGroup) and then you can loop over all the users filtering by both conditions:
The user has a License
The user is not a member of the Target Group
$targetGroup = "ExampleGroup"
$groupMembers = Get-MsolGroup $targetGroup | Get-MsolGroupMember
Get-MsolUser -All | ForEach-Object {
if($_.isLicensed -eq $true -and $_.ObjectId -notin $groupMembers.ObjectId) {
$_
}
} | Select-Object UserPrincipalName | Export-Csv -Path .\users.csv

the Cmdlets do not natively provide such features but with PowerShell we can use Compare-Object to check differences between two object arrays:
Fetch all users: $allUsers = Get-MSOLUser -all
Fetch members of your group: $groupMembers = Get-MsolGroupMember -GroupObjectId <Your-Group-ID>
Compare the two arrays: Compare-Object -ReferenceObject $groupMembers -DifferenceObject $allUsers -Property ObjectId
Based on your needs you can filter the above based on the SideIndicator property
Export the results by piping the above with | Export-CsV ...

I wasn't able to get the answer to work for me. Perhaps this works for others.
$targetGroup = "ExampleGroup"
$groupMembers = Get-MsolGroupMember -groupobjectid $targetGroup
Get-MsolUser -All | ForEach-Object {
if($_.isLicensed -eq $true -and $_.ObjectId -notin $groupMembers.ObjectId) {
$_
}
} | Select-Object UserPrincipalName | Export-Csv -Path .\users.csv

Related

Compare Object and exporting an Excel Spreadsheet with only users that are in both AD groups

I'm wanting this script to export an Excel spreadsheet with only the users that are in both AD groups.
$members1 = (Get-ADGroup 'Imprivata1' -Properties Member).Member
$members2 = (Get-ADGroup 'Imprivata2' -Properties Member).Member
Compare-Object $members1 $members2 -IncludeEqual | Sort-Object Name | Export-Csv "C:\users$env:username\Desktop\compareadgroups.csv" -Encoding UTF8 -NoTypeInformation
you do not need to use compare-object, you can simply query AD for users which are in both groups:
#Get Group distinguishedName
$groupDNs = get-adgroup -ldapfilter "(|(samaccountname=Imprivata1)(samaccountname=Imprivata2))"
#Build ldap filter
$ldapArray = #(
$groupDNs | %{
"(memberof=$($_.distinguishedName))"
}
)
$ldapString = $ldapArray -join $null
#Search Users that are member of both groups
$users = Get-ADUser -ldapfilter "(&$ldapstring)"
#Recursive Version of the ldap filter
$ldapArray = #(
$groupDNs | %{
"(memberof:1.2.840.113556.1.4.1941:=$($_.distinguishedname))"
}
)
Restricting the output to equal ones only using the sideindicator property, and there's no name property, but inputobject is the property to sort. Powershell 7 not powershell 5.1's export-csv has a -usequotes parameter.
compare $members1 $members2 -includeequal | ? sideindicator -eq == |
sort inputobject | export-csv -notype -usequotes asneeded compareadgroups.csv

how to list users and the groups they are part of in office 365 powershell

i need a script please to export users in office 365 and the groups they are part of and not the other way around. can anyone help please. all answers i found were to export distribution groups and their members.
i tried using the below but i dont know how to select group names.
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Select DisplayName,Alias,PrimarySMTPAddress'
and i tried this too
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Sort Name | % { $MbxDirData = $_ ; Get-MailboxStatistics $_ } | Select DisplayName, #{E={ $MbxDirData.Alias };L='Alias'}, #{E={ $MbxDirData.PrimarySMTPAddress };L='PrimarySMTPAddress'}, #{E={ $_.TotalItemSize.Value + $_.TotalDeletedItemSize.Value };L="TotalMailboxSize"}
any help is appreciated.
This is untested, but I think you can use cmdlets Get-User and then Get-Group to retrieve the groups a user is a member of like this:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$groups.Name -join '; '}}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
The above concatenates the groups with a semi-colon in one single field of the CSV, but if you would rather have output where there is one line for each group, you can do:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
# output a data row for each group in the collection
foreach ($group in $groups) {
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$group.Name}}
}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
We can list all the office 365 groups by using the PowerShell cmdlet Get-UnifiedGroup and its group members by Get-UnifiedGroupLinks cmdlet .
You can use the below PowerShell script ,which will Export All Office 365 Group Members to csv. We have tested this in our local environment which is working fine.
$Groups = Get-UnifiedGroup -ResultSize Unlimited
$Groups | ForEach-Object {
$group = $_
Get-UnifiedGroupLinks -Identity $group.Name -LinkType Members -ResultSize Unlimited | ForEach-Object {
New-Object -TypeName PSObject -Property #{
Group = $group.DisplayName
Member = $_.Name
EmailAddress = $_.PrimarySMTPAddress
RecipientType= $_.RecipientType
}}} | Export-CSV "C:\Office365GroupMembers.csv" -NoTypeInformation -Encoding UTF8
Here is the sample output screenshot for reference :
Note:
Get-UnifiedGroup cmdlet is available only in the cloud-based service.
For more Information you refer this blog post & also if you faces any issues while executing Get-unifiedGroup cmdlet you refer this .

How to Compare AD Group with Azure AD Group and remove members if different

i would like to compare 2 groups and removes members from Azure AD Group if its different, but im having an error. Can someone tell me what im doing wrong?
$membersofAzureADGroup = Get-AzureADGroup -Searchstring Test_Group | Get-AzureADGroupmember | Select Userprincipalname
$membersofADGroup = Get-ADGroupmember "Groupe_A" | Get-ADUser -properties Userprincipalname | Select UserPrincipalName
$RemoveUsers = Compare-Object -ReferenceObject $membersofAzureADGroup -DifferenceObject $membersofADGroup -PassThru | Where SideIndicator -eq "<="
Remove-AzureADGroupMember $RemoveUsers -Members $membersofAzureADGroup
Remove-AzureADGroupMember : Cannot find a positional parameter that accepts the argument "#{UserPrincipalName=user#domain.com;SideIndicator=<=}"
I tried this below but still not working...
Remove-AzureADGroupMember $RemoveUsers -MemberID (Get-AzureADUser | where {$_.Userprincipalname -eq $MembersOfGroup1}).ObjectID
Removing users that are members of an Azure AD Group but are not a member of an Active Directory Group would require filtering and for that you definitely not need Compare-Object.
Since you're trying to find elements of an array that do not exist on another array, Where-Object or .Where(..) method should be more than enough.
$ErrorActionPreference = 'Stop'
$azGName = 'Test_Group'
$adGName = 'Test_Group'
$azGroup = Get-AzureADGroup -Searchstring $azGName
$azMembers = Get-AzureADGroupmember $azGroup
$adMembers = (Get-ADGroupMember $adGName).Where({
$_.ObjectClass -eq 'user'
}).UserPrincipalName
# NOTE: Piping Get-ADUser to Get-ADGroupMember will get you in trouble whenever
# there is a member that is not of the objectclass 'user'.
# Members of AZ Group that are not members of AD Group
$azMembers.Where({$_ -notin $adMembers.UserPrincipalName}).ForEach({
"Removing $_ from $azGName"
try
{
Remove-AzureADGroupMember -ObjectId $azGroup.ObjectId -MemberId $_.ObjectId
}
catch
{
Write-Warning $_.Exception
}
})
I don't have AD or Azure AD, but I followed the principles of your issue and tested the following locally on my computer. See Below
Why you fail is because your $RemoveUsers variable is wrong. I'd be surprised if you've not looked at what is being presented from it.
Why It Doesn't Work
$RemoveUsers = Compare-Object -ReferenceObject $membersofAzureADGroup -DifferenceObject $membersofADGroup -PassThru | Where SideIndicator -eq "<="
Compare Groups On A Local Computer Test
## Step 1 - Place both groups into variables
$Group1 = get-localgroup -Name Administrators | Get-LocalGroupMember | Select Name
$Group2 = get-localgroup -Name Test | Get-LocalGroupMember | Select Name
## Step 2 - See All Output
$compare = Compare-Object -ReferenceObject $Group1 -DifferenceObject $Group2 -property name -passthru -IncludeEqual
## Step 3 See Only Difference in reference (source) object and select InputObject
$DifferenceInSource = (Compare-Object -ReferenceObject $Group1 -DifferenceObject $Group2 | Where SideIndicator -eq "<=" | Select -ExpandProperty InputObject)
## Step 4 Pull Out Names
$DifferenceInSourceName = $DifferenceInSource.Name
## Split WorkGroup and Account
$SplitName = $DifferenceInSourceName.Split('\')
## Step 5 Test To See If Account Resolves
Get-LocalUser -name $SplitName[1]
Obviously you then structure around a ForEach statement to make the update on multiple references.

Powershell Export to Clicml from ForEach

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

PowerShell Get-ACL with SamAccountName values

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.