How to change calendar permissions for all members of a group? - powershell

I'm currently trying to use powershell to change Outlook calendar permissions for a subset of users, so that they can all view calendar details of one another.
So far, I have been able to find the commands to change permissions for a single user, and for all users in the org - but have not yet established how to apply these changes to just a group.
Here is the script I found to modify permissions for all users:
foreach($user in Get-Mailbox -RecipientTypeDetails UserMailbox) {
$cal = $user.alias+”:\Calendar”
Set-MailboxFolderPermission -Identity $cal -User Default -AccessRights LimitedDetails
}
In order to apply this to just a group of users, would my modifications below be correct?
foreach($user in Get-MsolGroupMember -Identity "Name of Group") {
$cal = $user.alias+”:\Calendar”
Set-MailboxFolderPermission -Identity $cal -User Default -AccessRights LimitedDetails
}

You need to first find the group as object, because Get-MsolGroupMember doesn't have a -Identity parameter.
Then use that to get info of its users:
$groupToFind = 'DisplayName of Group'
$permissions = 'LimitedDetails'
$group = Get-MsolGroup | Where-Object { $_.DisplayName -eq $groupToFind }
if ($group) {
# get the group members (users only) and run through
Get-MsolGroupMember -GroupObjectId $group.ObjectId -MemberObjectTypes User -All | ForEach-Object {
$cal = '{0}:\Calendar' -f $_.Alias
$perms = Get-MailboxFolderPermission -Identity $cal -User Default
if ($perms.AccessRights -contains $permissions) {
Write-Host "User $($_.Alias) already has the '$permissions' permission"
}
else {
Write-Host "Setting permissions on $cal"
# for safety, first run with the -WhatIf switch. If you are satisfied with what
# is output on screen, remove or comment out that switch and run again
Set-MailboxFolderPermission -Identity $cal -User Default -AccessRights $permissions -WhatIf
}
}
}
else {
Write-Warning "Could not find group '$groupToFind'..."
}
Instead of using the Where-Object clause on Get-MsolGroup, you could also do Get-MsolGroup -SearchString $groupToFind, but beware that using -SearchString will return groups that have a display name that START with this string.
If you receive "The command completed successfully, no permissions were changed", this could mean the user first needs to get permissions on the so-called top of the information store (i.e. the mailbox folder itself):
Get-MsolGroupMember -GroupObjectId $group.ObjectId -MemberObjectTypes User -All | ForEach-Object {
$top = '{0}:\' -f $_.Alias # Top of Information Store
$cal = '{0}:\Calendar' -f $_.Alias
Add-MailboxFolderPermission -Identity $top -User Default -AccessRights FolderVisible -Confirm:$false
Set-MailboxFolderPermission -Identity $cal -User Default -AccessRights LimitedDetails -Confirm:$false
}
P.S. Because Outlook runs in cache, it takes time to reflect the changes there.

Related

Move list of users from one OU to a different OU and disable them at the same time - Powershell

I currently have a script that is able to disable a list of usernames using a text file which has a list of username specified:
$users = Get-Content C:\disableusers.txt
foreach ($user in $users) {
Disable-ADAccount -Identity $user
Write-Host "user $($user) has been disabled"
}
I was wondering if it is possible to incorporate moving using from one OU to another during the execution of this script?
e.g. moving from "Users" OU to "Disabled Users" OU.
I have created another script which does move a list of usernames to "Disabled Users" OU:
$users=Get-Content C:\disableusers.txt
$OU = "distinguishedName of my Disable Users OU"
foreach ($user in $users) {
Get-ADUser $user | Move-ADObject -TargetPath $OU
}
Any help on this is much appreciated thanks.
Both of your snippets look good to me, if you are interested in combining them into one you could use -PassThru from Disable-ADAccount to pass the disabled object through the pipeline to Move-ADObject:
$OU = "distinguishedName of my Disable Users OU"
Get-Content C:\disableusers.txt | ForEach-Object {
try {
Disable-ADAccount $_ -PassThru |
Move-ADObject -TargetPath $ou
Write-Host "user $($user) has been disabled and moved"
}
catch {
Write-Error $_
}
}

remove terminated users from DISTRIBUTION groups in AD

I am working on a solution that will help keep our Active Directory clean, so I want to use a Powershell script that will remove the disabled accounts from all groups.
I got the following script:
foreach ($username in (Get-ADUser -SearchBase "OU=Terminated Users,DC=corp,DC=company,DC=com" -filter *)) {
# Get all group memberships
$groups = get-adprincipalgroupmembership $username;
# Loop through each group
foreach ($group in $groups) {
# Exclude Domain Users group
if ($group.name -ne "domain users") {
# Remove user from group
remove-adgroupmember -Identity $group.name -Member $username.SamAccountName -Confirm:$false;
# Write progress to screen
write-host "removed" $username "from" $group.name;
# Define and save group names into filename in c:\temp
$grouplogfile = "c:\temp\" + $username.SamAccountName + ".txt";
$group.name >> $grouplogfile
}
}
}
It's working fine but only for security groups. Users are not deleted from distribution groups. I searched the Internet and people mostly suggest to use "Remove DistributionGroup Member" cmdlet. However, this is the Exchange cmdlet and we use Google Workspace for our email, so this cmdlet is not recognized when I run it on the DC.
Any idea how to solve it? Thanks!
The cmdlet Remove-ADPrincipalGroupMembership will help:
#get all disabled users in specified OU
$disabledUsers = get-aduser -SearchBase "OU=test_piotr,DC=corp,DC=company,DC=com" -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' -Properties memberof,samaccountname
#Loop through array and remove groupmembership and store operation result in $result
$result = #(
foreach ($user in $disabledusers){
try {
#Only process user account if memberships are present
If ($user.memberof){
#Remove all memberships the user has currently, no need to exclude domain users as $user.memberof does not return it
$null = Remove-ADPrincipalGroupMembership -Identity $user.samaccountname -MemberOf $user.memberof -Confirm:$false -ErrorAction:stop
write-host "Removed user: $($user.samaccountname) from groups: $($user.memberof -join ',')"
#Build object for logfile, you could also loop through $user.memberof to create one object per removed group
$attrsHt = #{
smaccountname=$user.samaccountname
group=($user.memberof -join ',')
status='removed'
exception=$null
}
New-Object -typename psobject -Property $attrht
}
}
Catch {
write-error "Failed to remove user: $($user.samaccountname) from groups: $($user.memberof -join ',') - Exception: $_"
$attrsHt = #{
smaccountname=$user.samaccountname
group=($user.memberof -join ',')
status='error'
exception=$_
}
New-Object -typename psobject -Property $attrht
}
}
)

Powershell - New-Mailcontact and Set-Contact

I have been trying to write a script so I can create New-Mailcontact using CSV file, if not already exist in ActiveDirectory.
If already exist in Active Directory then skip New-MailContact command and just run Set-MailContact.
Problem in the script: -
It does create new Mailcontact if not already exist in AD then If the mailcontact does not exist as a member of the groups, add account to group. If it already exists, skip
Also , new mail contact may be member 4 or 5 mail groups it will be add 4 mail groups called "1100-contact" like below. it will be add 5 mail groups called "1000-contact" like below.
if already exist in Active Directory e.g I am saying as "contact2#contoso.com" like below. if its required because already may be wrong displayname in AD.
it will update displayname based on CSV file again and then So already contact may be member of Group-Mail1 and Group-Mail2 it will add to groups if contact is not member to any of these Group-Mail5 and Group-Mail9 groups.
CSV :
Name,ExternalEmailAddress,group1,group2,group3,group4,group5
1000-contact,contact1#contoso.com,Group-Mail1,Group-Mail2,Group-Mail3,Group-Mail4,Group-Mail5
1100-contact,contact3#contoso.com,Group-Mail1,Group-Mail2,Group-Mail3,Group-Mail4
1200-contact,contact2#contoso.com,Group-Mail1,Group-Mail2,Group-Mail5,Group-Mail9
I have tried so far script :
Import-Csv C:\temp\ExternalContacts.csv|
foreach-object{
if (Get-MailContact -anr $_.ExternalEmailAddress)
{
write-host $_.name 'is a duplicate entry!!!'
Set-MailContact -Identity $_.ExternalEmailAddress -DisplayName $_.Name -ForceUpgrade -Confirm:$False
Add-DistributionGroupMember -Identity "$($_.group1)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group2)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group3)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group4)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group5)" -Member $_.ExternalEmailAddress
}
else {
New-MailContact -Name $_.Name -DisplayName $_.Name -ExternalEmailAddress $_.ExternalEmailAddress -OrganizationalUnit "OU=company_Contacts,OU=Contacts,DC=contoso,DC=com"
Add-DistributionGroupMember -Identity "$($_.group1)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group2)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group3)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group4)" -Member $_.ExternalEmailAddress
Add-DistributionGroupMember -Identity "$($_.group5)" -Member $_.ExternalEmailAddress
}
}
UPDATE :
I want to watch out for whitespace in your csv. So This will treat empty if group5 is empty. Am I correct ?
if ($_.group5) {
Add-DistributionGroupMember -Identity $_.group5 -Member $ExternalEmailAddress
}
If I understand the question properly, the main issue is that some contacts need to be added to 4, while others need to be added to 5 distribution groups.
Untested, but this might work for you:
Import-Csv -Path 'C:\temp\ExternalContacts.csv' | ForEach-Object {
# try and find the contact
$contact = Get-MailContact -Filter "EmailAddress -eq '$($_.ExternalEmailAddress)'" -ErrorAction SilentlyContinue
if ($contact) {
if ($_.Name -ne $contact.DisplayName) {
Write-Host "Renaming contact $($contact.DisplayName) to $($_.Name)"
Set-MailContact -Identity $_.ExternalEmailAddress -DisplayName $_.Name -ForceUpgrade -Confirm:$False
}
else {
Write-Host "Contact $($_.Name) already exists"
}
}
else {
Write-Host "Creating new contact $($_.Name)"
$contactParams = #{
Name = $_.Name
DisplayName = $_.Name
ExternalEmailAddress = $_.ExternalEmailAddress
OrganizationalUnit = "OU=company_Contacts,OU=Contacts,DC=contoso,DC=com"
}
New-MailContact #contactParams
}
# get an array of groups this user should be a member of
$groups = ($_.PsObject.Properties.GetEnumerator() | Where-Object { $_.Name -like 'group*' -and ($null -ne $_.Value) }).Value
# add the contact to the appropriate groups
foreach ($group in $groups) {
Add-DistributionGroupMember -Identity $group -Member $_.ExternalEmailAddress
}
}

Returning Unique user Id in GrantSendOnBehalfTo attribute in the Get-Mailbox cmdlet

I'm pulling out details for Delegate details of mailboxes from Office 365 setup using the exchange shell.
The problem is I'm getting the Display name of users in the GrantSendOnBehalfTo attribute of the Mailbox which isn't unique a value. How to print the unique ID of users in the GrantSendOnBehalfTo attribute?
I cannot test this right now, but I think this may help:
$SendOnBehalf = Get-Mailbox -Identity 'testing' | Select-Object -ExpandProperty GrantSendOnBehalfTo
foreach ($user in $SendOnBehalf) {
try {
# get the user or group that has SendOnBehalf permissions
$sob = Get-User -Identity $user -ErrorAction SilentlyContinue
if ($sob) {
Write-Host "User: $($sob.SamAccountName)" # or use $($sob.WindowsEmailAddress) if that is more unique for you
}
else {
$sobGroup = Get-Group -Identity $user -ErrorAction SilentlyContinue
Write-Host "Group: $($sob.SamAccountName)"
}
}
catch {}
}

Powershell - SetMailboxFolderPermission only if AccessRights Not equal Reviewer

I'd like to make a script to set the access rights for everyone as "Reviewer" on the calendar of some users, members of an specific AD group.
I've already made a script which works weel to do that for all members of this group.
I'd just want to make it a little smarter.
I'd like to schedule this script to run automatically once a week and to only apply on mailboxes on which accessrights are not already set as "Reviewer" for everyone.
Something like that :
$comm = Get-ADGroupMember GG_CalendarPermission-Reviewer | select -ExpandProperty name
$GetCalendar = Get-mailboxfolderpermission -identity $user":\calendar" -user default
foreach ($user in $comm) {
if ($GetCalendar.AccessRights -ne "Reviewer") {
set-mailboxfolderpermission -identity $user":\calendar" -user Default -accessrights reviewer
}
elseif($GetCalendar.AccessRights -eq "Reviewer") {
Write-Host "ALREADY DONE"
}
}
But the "if/Elseif" doesn't seems to work :/
Could you help me please ?
Thanks.
$comm = Get-ADGroupMember GG_CalendarPermission-Reviewer | select -ExpandProperty name
foreach ($user in $comm) {
$GetCalendar = Get-Mailboxfolderpermission -identity $user":\calendar" -user default
If ($GetCalendar.AccessRights -ne "Reviewer") {
Set-Mailboxfolderpermission -identity $user":\calendar" -user Default -accessrights reviewer
Write-Host 'Done'
}
ElseIf($GetCalendar.AccessRights -eq "Reviewer") {
Write-Host "ALREADY DONE"
}
}