Combine multiple foreach results into a single report - powershell

$results = foreach ($Mailbox in (Get-Mailbox -ResultSize Unlimited))
{
get-MailboxFolderPermission -identity "$($Mailbox.Name):\Calendar" -ErrorAction SilentlyContinue |
Where-Object {$_.User -notlike "Default" -and
$_.User -notlike "Anonymous" -and
$_.AccessRights -notlike "None" -and
$_.AccessRights } |
Select #{N="Mailbox";E={$Mailbox.SamAccountName}}, FolderName, User, AccessRights
}
$results
I am still learning powershell (only 1 full year of experience). I'm using this code to report on calendar permissions for all end user mailboxes in our environment. The code works well but it only reports on the Calendar object. I need to run three separate reports to get the Calendar, Contacts, and Inbox permissions.
I have tried creating an array but it throws multiple values all on one line. (Some end users have more than one person with access to their Calendar/Contacts/Inbox. Does anyone have a good idea of how to combine these results?
thanks
Here is an example of what results I would like:

Iterating Mailboxes only once with an additional
ForEach ($Folder in 'Contents','Calendar','Inbox')
Should be more efficient:
#Date
$date = (Get-Date -f yyyy-MM-dd)
#Pull Permissions
$Permissions = ForEach ($Mailbox in (Get-Mailbox -ResultSize Unlimited )) {
ForEach ($Folder in 'Contents','Calendar','Inbox'){
Get-MailboxFolderPermission -identity "$($Mailbox.Name):\$($Folder)" -ErrorAction SilentlyContinue |
Where-Object {$_.User -notlike "Default" -and $_.User -notlike "Anonymous" -and $_.AccessRights -notlike "None" -and $_.AccessRights } |
Select #{N="Mailbox";E={$Mailbox.SamAccountName}},
#{N="Folder";E={$_.FolderName}},
#{N="User With Access";E={$_.User}},
#{N="Access";E={$_.AccessRights}}
}
}
#Export to Desktop
$Permissions | Sort User | Export-Csv "$env:USERPROFILE\Desktop\ExchangePermissions-$Date.csv" -NoTypeInformation

#Date
$date = (Get-Date -f yyyy-MM-dd)
#Pull Permissions
$Permissions = ForEach ($Mailbox in (Get-Mailbox -ResultSize Unlimited )) {
$userInfo = get-user $Mailbox.name | select Title
ForEach ($Folder in 'Contacts','Calendar','Inbox'){
Get-MailboxFolderPermission -identity "$($Mailbox.Name):\$($Folder)" -ErrorAction SilentlyContinue |
Where-Object {$_.User -notlike "Default" -and $_.User -notlike "Anonymous" -and $_.AccessRights -notlike "None" -and $_.AccessRights } |
Select #{N="Mailbox";E={$Mailbox.SamAccountName}},
#{N="Office";E={$Mailbox.Office}},
#{N="Title";E={$userInfo.Title}},
#{N="Folder";E={$_.FolderName}},
#{N="User With Access";E={$_.User}},
#{N="Access";E={$_.AccessRights}}
}
}
#Export to Desktop
$Permissions | Sort User | Export-Csv
"$env:USERPROFILE\Desktop\ExchangePermissions-$Date.csv" -NoTypeInformation

Related

Get-ADUser is not returning anything when I use the UPN returned from Get-MailboxPermissions as a variable

I am trying to get the SamAccountName from Get-ADUser, but when I pass in the variable $member.User I get no results. $member.User when I print it out with Write-Host returns a variable, but used in the code below I get nothing. Also, if I copy/paste the $member.User value into that $add = Get-ADUser I get the SamAccountName. Why isn't Get-ADUser -Filter {EmailAddress -eq "$member.User" } returning anything? It is driving me nuts. Thank you in advance.
$Send = #()
$SendAs = #()
# Displaying FullAccess permissions for shared mailboxes
$Send = Get-MailboxPermission -Identity $MailboxUPN | Where-Object { -not ($_.User -like “NT AUTHORITY\SELF”) } | Select-Object Identity,User,AccessRights
$Send
# Displaying SendAs permissions for shared mailboxes
# $SendAs = Get-RecipientPermission -Identity $MailboxUPN | Where-Object {($_.IsInherited -eq $False) -and -not ($_.Trustee -like “NT AUTHORITY\SELF”) } | Select-Object Trustee, AccessRights
# $SendAs
forEach ($member in $Send){
Write-Host "In here"
Write-Host $member
$add = Get-ADUser -Filter {EmailAddress -eq "$member.User" }| Select-Object -ExpandProperty SamAccountName
Write-Host $add.SamAccountName
}

Exchange 2010 Powershell - Return Users With SendAs Permissions But Filter Disabled Users

so I have a script that works fine that I found online and changed to suit my needs. I have pasted this script below. However, in the output there is a lot of disabled users that have permissions to the mailboxes. E.g. I'd get an Output like "Mailbox Name^Mailbox#email.com^ActiveUser ActiveUser DisabledUser" So I am wondering if there is a way to make the script skip disabled users, same way how it leaves out self permissions.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
Connect-ExchangeServer -auto
$OutFile = “C:\Send_As_Permissions.txt”
“DisplayName” + “^” + “Email Address” + “^” + “Send As” | Out-File $OutFile -Force
$Mailboxes = Get-Mailbox -resultsize unlimited | Select Identity, Alias, DisplayName, DistinguishedName, WindowsEmailAddress
ForEach ($Mailbox in $Mailboxes) {
$SendAs = Get-ADPermission $Mailbox.identity | where {($_.ExtendedRights -like “*Send-As*”) -and -not ($_.User -like “NT AUTHORITY\SELF”) -and -not ($_.User -like “s-1-5-21*”)} | % {$_.User}
$Mailbox.DisplayName + “^” + $Mailbox.WindowsEmailAddress + “^” + $SendAs | Out-File $OutFile -Append
}
If you want to report on enabled mailboxes only, filter the output from Get-Mailbox on the IsMailboxEnabled property:
$Mailboxes = Get-Mailbox -resultsize unlimited | Where-Object { $_.IsMailboxEnabled } | Select ...
If you want to report on individual rights assignments for enabled accounts only, you'll have to query AD based on the value of the User property you extract:
$SendAs = Get-ADPermission $Mailbox.identity | where {($_.ExtendedRights -like “*Send-As*”) -and -not ($_.User -like “NT AUTHORITY\SELF”) -and -not ($_.User -like “s-1-5-21*”)} | % {$_.User}
$domain,$username = $SendAs.Split('\')
$ADUser = Get-ADUser -Identity $username -Server $domain
if($ADUser.Enabled){
# output to report
}

Combining 2 cmdlets for one result/output using pscustomobject

Basically what i'm trying to achieve here is an output with 4 column/list (in this case i'm exporting as a text)
Get-MailboxPermission gives me a property of identity, user, accessrights but it doesn't give me a property of "Manager". I need to identify where that particular user reports to. So, i tried PSCustomObject and hoping i can put the results in an array. See script below
$GETMAILBOXPERM = Get-Content C:\Users\Account\Desktop\MailboxUsers\MAILBOXESUSERS.txt | ForEach-Object {Get-MailboxPermission $_ |
where {
($_.User -notlike ‘*NT AUTHORITY*’) -and
($_.User -notlike ‘*S-1-5-21-*’) -and
($_.User -notlike ‘*NAMPRD08*’) -and
($_.User -notlike ‘*PRDTSB01*’) -and
($_.User -notlike ‘*0365Admin*’) -and
($_.User -notlike ‘*Discovery Management*’) -and
($_.User -notlike ‘*NAMPR08A005*’) -and
($_.User -notlike ‘*NT AUTHORITY*’)
}
}
$Results = foreach( $Mailbox in (get-content C:\Users\Account\Desktop\MailboxUsers\MAILBOXESUSERS.txt))
{
$Users = Get-User $Mailbox
if ($Users){
foreach ($User in $Users){
[pscustomobject]#{
DisplayName = $User.name
Account = $GETMAILBOXPERM.user
Manager = $User.manager
Access = $GETMAILBOXPERM.accessrights
}
}
}
}
$Results | Format-List -Property DisplayName, Account, Manager, Access | Out-File C:\Users\Account\Desktop\MailboxUsers\mailbox4.txt
Here's the output in text file. I get the DisplayName and Manager right but the Account and Access just doesn't seem to loop from the text file.
DisplayName : MAILBOX1
Account : {user1#domain.ca, user2#domain.ca, user3#domain.ca, user4#domain.ca...}
Manager : MANAGER1
Access : {FullAccess, FullAccess, FullAccess, FullAccess...}
DisplayName : MAILBOX2
Account : {user1#domain.ca, user2#domain.ca, user3#domain.ca, user4#domain.ca...}
Manager : MANAGER2
Access : {FullAccess, FullAccess, FullAccess, FullAccess...}
The user manager attribute is normally in ADDS, not Exchange. Yet, that text file seems to be where you are getting this from vs dynamically from ADDS.
Why are you using Format-List?
PowerShell will automatically format as a list the moment you columns exceed 5.
This is untested, since I do not have an environment to try it on, but a refactor of what you have here. Give it a shot.
$GetMailboxPerm = Get-Content -Path 'C:\Users\Account\Desktop\MailboxUsers\MAILBOXESUSERS.txt' |
ForEach-Object {Get-MailboxPermission $PSitem |
where {
($PSitem.User -notlike ‘*NT AUTHORITY*|
*S-1-5-21-*|
*NAMPRD08*|
*PRDTSB01*|*0365Admin*|
*Discovery Management*|
*NAMPR08A005*|
*NT AUTHORITY*’)
}
}
foreach( $Mailbox in (Get-Content -Path 'C:\Users\Account\Desktop\MailboxUsers\MailboxUsers.txt'))
{
$Users = Get-User $Mailbox
if ($Users)
{
foreach ($User in $Users)
{
[pscustomobject]#{
DisplayName = $User.name
Account = $GetMailboxPerm.user
Manager = $User.manager
Access = $GetMailboxPerm.accessrights
} | Out-File -FilePath 'C:\Users\Account\Desktop\MailboxUsers\mailbox4.txt' -Append
}
}
}

Empty element not allowed [duplicate]

This question already has answers here:
pipes and foreach loops
(2 answers)
pipe foreach loop CSV PowerShell
(3 answers)
Closed 4 years ago.
I can't seem to export anything into CSV. I did some browsing and reading, but having hard time converting my script.
$allmailbox = Get-Mailbox -ResultSize 20
foreach ($Mailbox in $allmailbox) {
Get-MailboxFolderPermission -Identity ($mailbox.alias+':\calendar') |
Where {
$_.User -like "Anonymous" -and
$_.AccessRights -ne "None" -or
$_.User -like "Default" -and
$_.AccessRights -ne "None" -or
$_.User -like "Default" -and
$_.AccessRights -ne "AvailabilityOnly"
} |
select Identity, User, AccessRights
} | Export-Csv C:\CSVs\calstest.csv
The empty element not allowed is referring to the | at the end of your foreach. The way that your loop is structured does not allow the pipe. Below shows a different approach that can work.
Below should get you everything in one CSV file:
Get-Mailbox -ResultSize 20 | foreach {Get-MailboxFolderPermission -Identity $($_.Alias+":\calendar") | Where {$_.User -like "Anonymous" -and $_.AccessRights -ne "None" -or $_.User -like "Default" -and $_.AccessRights -ne "None" -or $_.User -like "Default" -and $_.AccessRights -ne "AvailabilityOnly"}| select Identity,User,AccessRights} | Export-Csv C:\CSVs\calstest.csv -NoTypeInformation
I tested this without the Where-Object and it exported successfully. If you are not receiving any information you might want look more into your Where . Start with one condition and increase as needed.
$allmailbox = Get-Mailbox -ResultSize 20
Foreach ($Mailbox in $allmailbox){Get-MailboxFolderPermission –Identity ($mailbox.alias+':\calendar') |
Where {
($_.User -like "Anonymous" -and $_.AccessRights -ne "None") -or
($_.User -like "Default" -and $_.AccessRights -ne "None") -or
($_.User -like "Default" -and $_.AccessRights -ne "AvailabilityOnly")
}| select Identity,User,AccessRights} | Export-CSV C:\CSVs\calstest.csv
If that's what you're looking for, though you'll have to add backticks I think for it to be seen as a complete query
This works:
$allmailbox = Get-Mailbox -ResultSize 500
$result = Foreach ($Mailbox in $allmailbox){Get-MailboxFolderPermission –Identity ($mailbox.alias+':\calendar') | Where {$_.User -like "Anonymous" -and $_.AccessRights -ne "None" -or $_.User -like "Default" -and $_.AccessRights -ne "None" -or $_.User -like "Default" -and $_.AccessRights -ne "AvailabilityOnly"} | select Identity,User,AccessRights}
$result | Export-CSV C:\CSVs\calstest.csv -NoType

powershell - getting last users last login from local server

I have been working on a script to show the the last login of each of the users that have been logging into their terminal server.
The script works if they are not on a domain but when they are on a domain, it would show users that have not logged into that particular server.
Is there a way for me to edit the script to where it only shows users that have logged into that specific server?
Here is the code:
#This script will check which users have logged on in the last X days
#Set Variables
#Change the number in the parenthesis after adddays to change how far back
to filter
#example (get-date).adddays(-30) gets all logins for the last 30 days from
today (-60) would be the last 60 days
$AuditDate = Get-Date (get-date).adddays(-30) -format "MM/dd/yyyy h:mm:ss
tt"
$ComputerName = $env:COMPUTERNAME
$CurrentDate = Get-Date -UFormat "%Y-%m-%d"
#Delete any previously created files
Get-ChildItem -Path "C:\PowerShellScripts\LastLogon\Results" -Recurse |
Where-Object CreationTime -lt (Get-Date).AddDays(-0) | Remove-Item -
ErrorAction SilentlyContinue
#The Login Profile is filtered here
Get-WmiObject -class Win32_NetworkLoginProfile -ComputerName $ComputerName|
#Where-Object -FilterScript {$_.LogonServer -like $ComputerName}|
Where-Object -FilterScript {$_.FullName -notlike "*Agvance*"} |
Where-Object -FilterScript {$_.FullName -notlike "*Sophos*"} |
Where-Object -FilterScript {$_.FullName -ne "AgvAdmin"} |
Where-Object -FilterScript {$_.FullName -ne ""} |
Where-Object {$_.Name -notlike "*ssi1*"}|
Where-Object {$_.Name -notlike "*ssi2*"}|
Where-Object {$_.Name -notlike "*ssi3*"}|
Where-Object {$_.Name -notlike "*ssi4*"}|
Where-Object {$_.Name -notlike "*ssi5*"}|
Where-Object {$_.Name -notlike "*ssi6*"}|
Where-Object {$_.Name -notlike "*ssi7*"}|
Where-Object {$_.Name -notlike "*ssi8*"}|
Where-Object {$_.Name -notlike "*ssi9*"}|
Where-Object {$_.Name -notlike "*ssiadmin*"}|
Where-Object -FilterScript {$_.Name -notlike "*SYSTEM*"} |
Where-Object -FilterScript {$_.Name -notlike "*SERVICE*"} |
Where-Object -FilterScript {!
[System.String]::IsNullOrWhiteSpace($_.LastLogon)} |
Where-Object -FilterScript {$_.ConvertToDateTime($_.LastLogon) -ge
$AuditDate} |
Select-Object Name,LogonServer,#{label='LastLogon';expression=
{$_.ConvertToDateTime($_.LastLogon)}} -ErrorAction SilentlyContinue | sort-
object Name | Export-Csv
C:\PowerShellScripts\Lastlogon\Results\LastLogon.csv -NoTypeInformation
#Extra filter to filter out SSI users
#Import-Csv C:\PowerShellScripts\Results\LastLogon.csv | Where-Object
{$_.Name -notlike "*ssi*"} |Export-Csv
C:\PowerShellScripts\Lastlogon\Results\LastLogon.csv -NoTypeInformation -Force
#The user count is created here
$number = (Import-Csv C:\PowerShellScripts\Lastlogon\Results\LastLogon.csv |
measure | % { $_.Count})
#The file is renamed to include computername, date, and user count
rename-item -path C:\PowerShellScripts\Lastlogon\Results\LastLogon.csv -NewName C:\PowerShellScripts\Lastlogon\Results\LastLogon-$ComputerName-$CurrentDate-UserCount-$number.csv
You can give this a try and see if it provides what you need.
$time = (Get-Date) – (New-TimeSpan -Day 30)
# You can additional filters in ? { $_.Properties[1].Value -ne 'SYSTEM' } by
# modifying it with -and statements
# i.e. ? { ($_.Properties[1].Value -ne 'SYSTEM') -and ($_.Properties[1].Value -ne 'USER')}
Get-WinEvent -FilterHashtable #{Logname='Security';ID=4672;starttime=$time} -ComputerName $ComputerName | ? { $_.Properties[1].Value -ne 'SYSTEM' } | select #{N='User';E={$_.Properties[1].Value}}, #{N='TimeCreated';E={$_.TimeCreated}}