Looping Through All Calendars With Get-MailboxFolderPermission - powershell

I have researched this extensively and used much trial-and-error, but I have yet to get a scrip to work that performs the function I want it to. What I want is to create a script that will allow the user to type a username, and then run through all the mailboxes and show the user's permissions on those user's calendars. I've gotten very close with the below script, but this only works on the mailbox as a whole, and does not work if I simply add ":\Calendar" to the $Box variable. Any input on how to get this to show the calendar permissions would be welcome.
$Username = Read-Host "Enter the user whose access you would like to view"
foreach ($Box in Get-Mailbox) {
Get-MailboxFolderPermission -Identity $Box -User $Username
}
I know this is a repeat of a previous question, but as I've altered my code significantly, I thought it was worth asking again. Here's the link to my prior question:
Exchange Powershell: Get-MailboxFolderPermission for all calendars
Thanks for any help!

You could refer to the below code:
(Get-Mailbox) | ForEach-Object {
Get-Mailboxfolderpermission (($_.PrimarySmtpAddress)+":\calendar") `
-User happyboy -ErrorAction SilentlyContinue
} | Select-Object Identity, User, Accessrights
For more information, please refer to this link:
Display all mailbox calendars which a user has access to

Using the suggestion by #Alina-Li, I was able to work out the following code. Everything works well now:
(Get-Mailbox) | ForEach-Object {
$Permission = Get-Mailboxfolderpermission ($_.PrimarySMTPAddress.Local + "#" + $_.PrimarySMTPAddress.Domain +":\calendar") `
-User $User -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Accessrights
if ($Permission -ne $null) {
echo ("Calendar: "+($_.Name))
echo ($User+"'s Permission: "+$Permission)
echo ""
}
}

Related

Powershell Script to query Active Directory

I am trying to query all users in multiple OUs of the same name. Get the SamAccountName attribute and then check for a file at a specific location with that name.
Here is what I have so far:
$ous = Get-ADOrganizationalUnit -Filter "Name -eq 'Admin-User-Accounts'"
$ous | ForEach-Object {
$AccountName = Get-ADUser -Filter * -SearchBase $_.DistinguishedName |
Select SamAccountName
Test-Path "\\domain.net\SYSVOL\domain.net\IA\$AccountName.pdf"
}
If a file is not found. I want to add the user to a group, however here is the kicker. The account has to be added to the non-compliance group for the organization that the account belongs to.
I.E an admin account found under:
OU=Admin-User-Accounts,OU=Administration,OU=ORG1,OU=ORGS,DC=domain,DC=net
would be added to the group named 'ORG1 IA - Non-Compliant Users' located under:
OU=Groups,OU=ORG1,OU=Information Assurance,OU=ORGS,DC=domain,DC=net
Well your post is a bit confusing, and no way to really validate because I have nothing setup like this.
Yet, querying for users in all OU or the enterprise is a common everyday thing.
However, an OU name, just like any other AD object name, must be unique. So, querying for the same OU name is not a thing, in a single AD forest / domain. If you meant querying every OU for the same username, then alrighty then.
By stepping thru how you are explanation for your use case, that you have laid out.
(though maybe you want to edit your post to make it's more clear, well to me anyway...)
Using pseudo code, then trying to map that out... and with no real way to determine what you mean by several things in your post/sample. So, the below is a rough first example of how I'd do approach this... again this is untested, so, I leave that homework to you.
# query all users in multiple OUs
(Get-ADOrganizationalUnit -Filter *).DistinguishedName |
ForEach{
# Collect all members of the current OU
$AccountNames = Get-ADUser -SearchBase $PSItem -Filter *
# Process each member in the current OU collection
ForEach($AccountName in $AccountNames)
{
"Processing $($AccountName.SamAccoutnName)`n"
# Initialize properties needed for processing
$UserOrg = $AccountName.DistinguishedName.split(",")[1]
$MemberCheckOU = "OU=Admin-User-Accounts,OU=Administration,OU=ORG1,OU=$UserOrg,DC=domain,DC=net"
$NonCompliantOU = "OU=Groups,OU=ORG1,OU=Information Assurance,OU=$UserOrg,DC=domain,DC=net"
# Validate user file existence for the current user
If(-Not (Test-Path -LiteralPath "\\domain.net\SYSVOL\domain.net\IA\$($AccountName.SamAccoutnName).pdf)"))
{
# if no file Process the user groupmebership modification
"Processing $($AccountName.SamAccoutnName)"
# Notify that the file was not found and processing is required
Write-Warning -Message "$($($AccountName.SamAccoutnName).pdf) not found. Process group modify actions"
# If the current user is in the MemberCheckOU, add to the NonCompliantOU
If(Get-ADPrincipalGroupMembership -Identity $($AccountName.SamAccoutnName) | Where-Object -Property DistinguishedName -Match $MemberCheckOU )
{ Add-ADGroupMember -Identity $NonCompliantOU -Members $($AccountName.SamAccoutnName) }
Else
{
# Do something else
}
}
Else
{
# Notify that the file was found and no processing required
Write-Host "$($AccountName.pdf) found. No further actions taken" -ForegroundColor Green }
}
}
It seems that one of the variables is incorrect because PowerShell is giving me the following:
Get-ADPrincipalGroupMembership : Cannot validate argument on parameter 'Identity'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command
again.
Okay, so here is what I have so far based on your post above Postanote:
# query all users in multiple OUs
(Get-ADOrganizationalUnit -Filter "Name -eq 'Admin-User-Accounts'") |
ForEach{
# Collect all members of the current OU
$AccountNames = Get-ADUser -SearchBase $PSItem -Filter *
# Process each member in the current OU collection
ForEach($AccountName in $AccountNames)
{
"Processing $($AccountName.SamAccoutnName)`n"
# Initialize properties needed for processing
$UserOrg = $AccountName.DistinguishedName.split(",")[1]
$MemberCheckOU = "OU=Admin-User-Accounts,OU=Administration,OU=$UserOrg,OU=ORGS,DC=domain,DC=net"
$NonCompliantOU = "OU=Groups,OU=$UserOrg,OU=Information Assurance,OU=ORGS,DC=domain,DC=net"
# Validate user file existence for the current user
If(-Not (Test-Path -LiteralPath "\\domain.net\SYSVOL\domain.net\IA\$($AccountName.SamAccoutnName).pdf)"))
{
# if no file Process the user groupmebership modification
"Processing $($AccountName.SamAccoutnName)"
# Notify that the file was not found and processing is required
Write-Warning -Message "$($($AccountName.SamAccoutnName).pdf) not found. Process group modify actions"
# If the current user is in the MemberCheckOU, add to the NonCompliantOU
If(Get-ADPrincipalGroupMembership -Identity $($AccountName.SamAccoutnName) | Where-Object -Property DistinguishedName -Match $MemberCheckOU )
{ Add-ADGroupMember -Identity "$UserOrg IA - Non-Compliant Users" -Members $($AccountName.SamAccoutnName) }
Else
{
# Do something else
}
}
Else
{
# Notify that the file was found and no processing required
Write-Host "$($AccountName.pdf) found. No further actions taken" -ForegroundColor Green }
}
}
Looking at the original script fragment:
$ous = Get-ADOrganizationalUnit -Filter "Name -eq 'Admin-User-Accounts'"
$ous | ForEach-Object {
$AccountName = Get-ADUser -Filter * -SearchBase $_.DistinguishedName |
Select SamAccountName # note 1
Test-Path "\\domain.net\SYSVOL\domain.net\IA\$AccountName.pdf" # note 2
}
Note 1: Your going to end up with $accountname.accountname holding your value. I think your going to want to expand this instead.
Note2: Powershell may be getting confused and thinking your looking for the variable $accountname.pdf
Instead, try this...
$ous = Get-ADOrganizationalUnit -Filter "Name -eq 'Admin-User-Accounts'"
$ous | ForEach-Object {
$AccountName = $(Get-ADUser -Filter * -SearchBase $_.DistinguishedName).SamAccountName
Test-Path "\\domain.net\SYSVOL\domain.net\IA\$($AccountName).pdf"
}
here, we save the value of just .SamAccountName for the query to the $AccountName, and by adding $($accountname) we make clear the variable we want, and that .pdf is not part of the variable name.
Now, note as well, this doesn't save the results anywhere, it will just flash them to screen.

Will Office 365 (Admin center or Powershell) tell me if a user's password is expired?

I feel like this question has to have been asked before, but I've spent way too much time searching for it here and elsewhere.
I'm looking for something to tell me that a user's password has expired. When I search for this, I get a ton of sites telling me how to set a user's password to never expire or how to set the password policy. I just want to be able to look up a user in the Admin Center or using PowerShell to see if the password is expired.
I user this cmdlet as a workaround for the moment, but it would be so much easier if I could have it tell me "Password Expired: Yes" or something like that.
Get-MsolUser -SearchString (Read-Host `n Whose info?) | select DisplayName, LastPasswordChangeTimeStamp, #{Name=”PasswordAge (in days.time)”;Expression={(Get-Date)-$_.LastPasswordChangeTimeStamp}}, PasswordNeverExpires | fl
Thanks!
04-Aug-16 Edit based on Junaid's suggested answer below:
I've changed the script to allow for searching, for vertical spacing, and for the accounts where PasswordNeverExpires = TRUE. I hope it's helpful.
$valid = Get-MsolPasswordPolicy -DomainName domain.com | select ValidityPeriod -ExpandProperty ValidityPeriod
Get-MsolUser -SearchString (Read-Host `n Whose info?) | Select DisplayName, LastPasswordChangeTimeStamp, PasswordNeverExpires | foreach{
$user = $_.DisplayName
$exp = $_.LastPasswordChangeTimeStamp.addDays($valid)
If ($_.PasswordNeverExpires -eq $TRUE){
$exp = "Never"
}
Write-Output "$user's Password Expiration: $exp"
}
Write-Output `n
You can achieve it like this. First get the domain's password policy and save the ValidityPeriod to a variable. Then get all users and their last password change time stamp, add the validity period to it and there you have it, the date when the password will expire.
$valid = Get-MsolPasswordPolicy -DomainName yourdomain.com | select ValidityPeriod -ExpandProperty ValidityPeriod
Now we have the validity period in $valid variable.
Get-MsolUser -All | Select UserPrincipalName, LastPasswordChangeTimeStamp | foreach{
$user = $_.UserPrincipalName
$exp = $_.LastPasswordChangeTimeStamp.addDays($valid)
Write-Output "$user's password expires on $exp"
}
I ran this in a powershell session with Msol service connected. So i hope it helps you.

Writing a mailbox property to a Variable or text box

I am writing a basic GUI that makes it easier for staff to find current mailbox/calendar rights. Essentially they type the name of the mail box and the user who's permissions they wish to check, and it writes what the permissions are
I have tried two ways and both ran into problems. The first:
$Property = get-mailboxpermission -Identity $Mailbox -User $User | Format-List AccessRights if($Property -eq "AccessRights : {FullAccess}")
$PermissionText.AppendText(($Property))
Results with the output:
"Microsoft.PowerShell.Commands.Internal.Format.FormatStartData....."
(I have also get the same when simply inputting the get-mailbox command to the append text)
I have also tried instead to convert the access rights property to a variable, then writing that to the text box using if conditions as below code, but that doesn't play nice either
Method:
$Property = get-mailboxpermission -Identity $Mailbox -User $User | format-list AccessRights
if($Property -eq "AccessRights : {FullAccess}")
{$PermissionText.AppendText("Full Access")}
if($Property -eq "AccessRights : {ReadAccess}")
{$PermissionText.AppendText("Read Only")}
Output: Nothing whatsoever
in short, I need a way of either outputting just the permissions to the text box, or, making the variable equal something useable
Try this:
$Property = Get-MailboxPermission -Identity $Mailbox -User $User | ? {$_.AccessRights -eq "FullAccess"}
if($Property)
{
$PermissionText.AppendText($Property.User.ToString())
}
Thankyou #Avshalom i figured it from your idea:
$Property = Get-MailboxPermission -Identity $Mailbox -User $User | ? {$_.AccessRights}
$PermissionText.AppendText($Permission.AccessRights)

Setting a domainusers P.O. Box via Powershell set-ADUser doesn't work?

I'm just wondering if anyone of you is using powershell to set a users P.O. Box via
Set-ADUser
Im comparing domainaccounts between two different domains and let my script write the differences back to one of the DCs. At the first run, the script detects that there's a different POBox on DC1 than on DC2 and writes the one from DC1 back to DC2.
This works perfectly well with all of the atributes except the postOfficeBox.
As stated above, on the first run, the script detects the changes and writes the changes back. That does not apply to the postOfficeBox however. If I open the userobject on DC2, it remains blank! What is even more strange is, that the script doesn't detect that the POBox is blank if I run it again! I have to modify the postOfficeBox manually in order for the script to see any changes again. (and with blank I mean not even spaces)
All other attributes are working fine. Is this a possible bug on Win Server 2012 and WPS?
Here's the code:
$attributes = "c","co","company","countryCode","department","displayName","postOfficeBox","sAMAccountName"
$user1 = Try{Get-ADUser -Identity $_.SamAccountName -Properties $attributes}
catch{}
$user2 = try{Get-ADUser -Identity $_.SamAccountName -Properties $attributes -Credential $AdminCredentials -Server $dc2}
catch{}
if ($user1.SamAccountName -eq $user2.SamAccountName) {
$chk_modified = #{}
$attributes | ? { $user1.$_ -ne $user2.$_ } | % {
$chk_modified[$_] = $user2.$_
}
if ($chk_modified.Count -ge 1) {
Set-ADUser -Identity $_.SamAccountName -Replace $chk_modified
}
}
I see a field in Active Directory called 'POBox' is this the field you mean?
Here is how I would update it
Get-ADUser $userName | Set-ADUser -POBox $pobox -Credential $cred
or this:
'Get-ADUser -Identity $_.SamAccountName | Set-ADUser -postOfficeBox "the new box 42" -credential $cred'
Hope this helps.

Determining if a given user is in a given global group

I’m trying to search through Active Directory using the AD module in PowerShell. I’m trying to determine whether a given user is in a given global group. The issue is that I’m using -match meaning if there is a username that contains another within it, such as 'smith_pl' containing 'smith_p'. The user 'smith_p' will be shown to be in the group.
So my question is: Is there a better way of getting a $True or $False return depending if a user is in a giving global group using the AD module?
If not
Is there a way of getting the output from $ListOfmembers into an array so I can use -eq instead of -match?
Part of Script:
$ListOfmembers = dsquery group domainroot -name $globalgroup |
dsget group -members |
dsget user -samid -L
$checkMember = $False
#Search if the user is in output the list
If($ListOfmembers -match $Logonname){
$checkMember = $True
}
ListOfmembers Output:
samid: user05_t
samid: user23_s
samid: Admin
samid: user45_s
dsget succeeded
Any help would be appreciated, Cheers.
$member = Get-ADGroupMember group1 -Recursive | where {$_.samaccountname -eq 'user1'}
if($member) {'user 1 is a member of group1'}
You can do it like this:
[reflection.assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
$username = "samaccountname"
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($ct, $username)
$g = $user.GetGroups()
( $g | select -expa name ) -contains 'groupname'
You should checkout QAD: http://www.quest.com/powershell/activeroles-server.aspx
$user get-qaduser samAccountName
$user.memberof