In the below script $recexternal and $recinternal always return zero as if there are some issues with the second block.
However, the first executes successfully and gets correct $i and $e output.
What am I doing wrong?
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
$e = 0;
$i = 0;
$recexternal = 0;
$recinternal = 0;
$array = #("JayanManniath.Nair#contoso.com")
foreach ($user in $array) {
$sender = Get-TransportServer |
Get-MessageTrackingLog -ResultSize Unlimited -Sender $user
$sender | %{
if (($_.Source -eq "SMTP") -and ($_.EventId -eq "SEND")) {$e++}
if (($_.Source -eq "STOREDRIVER") -and ($_.EventId -eq "DELIVER")) {$i++}
}
$recipient = Get-TransportServer |
Get-MessageTrackingLog -ResultSize Unlimited -Recipients $user
$reipient | %{
if (($_.Source -eq "SMTP") -and ($_.EventId -eq "RECEIVE")) {$recexternal++}
if (($_.Source -eq "STOREDRIVER") -and ($_.EventId -eq "DELIVER" )) {$recinternal++}
}
}
Write-Host "$user has sent $i emails internally"
Write-Host "$user has sent $e emails externally"
Write-Host "$user has received $recexternal emails from outside organization"
Write-Host "$user has received $recinternal emails from inside the organization"
Aside from the obvious typo your code has the output placed wrongly,
in case of more than one $user in $array the Write-Host commands
should be placed inside the ForEach.
A Where-Object and ().count instead of
the ForEach-Object (%) and the IFs is possibly more efficient.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
$array = #("JayanManniath.Nair#contoso.com")
ForEach ($user in $array) {
$sender = Get-TransportServer |
Get-MessageTrackingLog -ResultSize Unlimited -Sender $user
$e = ($sender | Where-Object {($_.Source -eq "SMTP") -and
($_.EventId -eq "SEND")} ).Count
$i = ($sender | Where-Object {($_.Source -eq "STOREDRIVER") -and
($_.EventId -eq "DELIVER")} ).Count
$recipient = Get-TransportServer |
Get-MessageTrackingLog -ResultSize Unlimited -Recipients $user
$recexternal = ($recipient | Where-Object {($_.Source -eq "SMTP") -and
($_.EventId -eq "RECEIVE")} ).Count
$recinternal = ($recipient | Where-Object {($_.Source -eq "STOREDRIVER") -and
($_.EventId -eq "DELIVER")} ).Count
Write-Host "$user has sent $i emails internally"
Write-Host "$user has sent $e emails externally"
Write-Host "$user has received $recexternal emails from outside organization"
Write-Host "$user has received $recinternal emails from inside the organization"
}
Related
After reading many of the posted solutions here, none fully applies mine.
This works (returns expected number of instancesNames based on criteria):
$response.result | Where-Object {$_.targetType -eq "webserver" -and ($_.agentHostName -eq "ServerA" -or $_.agentHostName -eq "ServerB")} | select-Object "instanceName"
However, since n number of servers may be found, I created a loop to dynamically create this query:
[System.Text.StringBuilder]$clause = " {`$_.targetType -eq ""webserver"" -and ("
$i = 1;
foreach ($server in $serversArray) {
if ( $i -eq $serversArray.Count ) {
$clause.Append("`$_.agentHostName -eq ""${server}"")}")
} else {
$clause.Append( "`$_.agentHostName -eq ""${server}"" -or ")
}
$i++
}
$clause.Append(" | select-Object ""instanceName""")
$filter = [scriptblock]::Create($clause)
$instances = $response.result | where-object $filter
debugging:
the $clause variable contains:
{$_.targetType -eq "webserver" -and ($_.agentHostName -eq "serverA" -or $_.agentHostName -eq "serverB")} | select-Object "instanceName"
However, it returns all instanceNames (not filtered) instead of the ones that meet the criteria. What am I doing wrong here?
The -in operator would simplify your code. For example:
$response.result |
Where-Object {($_.targetType -eq 'webserver') -and ($_.agentHostName -in $serversArray)} |
Select-Object 'instanceName'
$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
I must be doing something wrong here results are empty, I tried converting html with PsObject it requires -Append that creates multiple html tables and not suited to send an email, any help appreciated.
Foreach($sender in $senders){
$users=Get-TransportServer|Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |?{$_.Recipients -notlike "*#domain.us" -and $_.RecipientCount -eq "1" -and $_.RecipientStatus -notlike "*,*" -and $_.eventid -eq 'RECEIVE' }
}
$users | % {
$t = New-Object PSObject -Property #{
Sender = $_.Sender
Receiver = $_.Recipients
Messagesubject=$_.Messagesubject
RecipientCount =$_.RecipientCount
TimeStamp=$_.TimeStamp
}
$outtbl += $t
}
$outtbl
Why do you need $users, $outtbl, or $t?
foreach ( $sender in $senders ) {
Get-TransportServer |
Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |
Where-Object { ($_.Recipients -notlike "*#domain.us") -and
($_.RecipientCount -eq 1) -and
($_.RecipientStatus -notlike "*,*") -and
($_.eventid -eq 'RECEIVE') } | ForEach-Object {
[PSCustomObject] #{
Sender = $_.Sender
Receipients = $_.Recipients
MessageSubject = $_.MessageSubject
RecipientCount = $_.RecipientCount
TimeStamp = $_.TimeStamp
}
}
}
(Not tested - this is just an example of how to eliminate unnecessary variables and write clearer code.)
This code sample requires PowerShell 3.0 or newer because it uses [PSCustomObject].
This was it
foreach ( $sender in $senders ) {
Get-TransportServer |
Get-MessageTrackingLog -Start (Get-Date).AddHours(-4) -ResultSize Unlimited -Sender $sender.PrimarySmtpAddress |
Where-Object { ($_.Recipients -notlike "*#domain.us") -and
($_.RecipientCount -eq 1) -and
($_.RecipientStatus -notlike "*,*") -and
($_.eventid -eq 'RECEIVE') } | ForEach-Object {
$results += New-Object PSObject -Property #{
Sender = $_.Sender
Receiver = $_.Recipients
MessageSubject = $_.MessageSubject
RecipientCount = $_.RecipientCount
TimeStamp = $_.TimeStamp
}
}
}
$results| ConvertTo-Html -Head $style| Out-File $reportpath
I need to make a CSV file with the name of the mailbox (mb Identity), user, accessrights and deny. But I only want to that for ADUsers who have a givenname AND a surname not only a surname.
I thought of something like that:
$File_Path = $args[0]
$File_Path = ((Get-Item -Path ".\" -Verbose).FullName) + "\" + $File_Path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines($File_Path, "Mailbox;RightHolder;Rights;Deny", $Utf8NoBomEncoding)
$Mailboxes = Get-Mailbox -ResultSize Unlimited
Foreach ($Mailbox in $Mailboxes) {
$mbPermissions = get-mailboxpermission $Mailbox
$str_DN = $Mailbox.DistinguishedName
$ad_obj = [ADSI]"GC://$str_DN"
Foreach ($mbPermission in $mbPermissions) {
If ($mbPermission.IsInherited -eq $False -and $mbPermission.User -notlike "NT-AUTORITÄT\SELBST") {
[System.IO.File]::AppendAllText($File_Path, "$($mbPermission.Identity);$($mbPermission.User);$($mbPermission.AccessRights);$($mbPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
$ADPermissions = get-ADPermission $Mailbox.Identity
Foreach ($ADPermission in $ADPermissions) {
If ($ADPermission.ExtendedRights -like "Send-As" -and $ADPermission.User -notlike "NT-AUTORITÄT\SELBST" -and $ADPermission.Deny -eq $false) {
[System.IO.File]::AppendAllText($File_Path, "$($ADPermission.Identity);$($ADPermission.User);$($ADPermission.ExtendedRights);$($ADPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
}
This works perfectly fine for creating the csv file with all credentials I need, but it doesn't exclude mailboxes from users who have no givenname. I'm a little bit stuck here.
Thanks for your help!
EDIT:
Solved it! Just put these lines instead of the $Mailboxes part:
$Mailboxes = get-mailbox -ResultSize Unlimited | select -ExpandProperty samaccountname
$Filter = foreach ($Obj in $Mailboxes) { get-aduser $Obj | select -property givenname,samaccountname }
$NoGivenName = $Filter | where { $_.givenname -ne $null } | select -ExpandProperty samaccountname
$BoxesFiltered = foreach ($Box in $NoGivenName) { get-mailbox $Box }
Can you try the following, it may take a little longer as the it has to filter out with a Get-ADUser to regenerate the list.
Import-Module ActiveDirectory
$File_Path = $args[0]
$File_Path = ((Get-Item -Path ".\" -Verbose).FullName) + "\" + $File_Path
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines($File_Path, "Mailbox;RightHolder;Rights;Deny", $Utf8NoBomEncoding)
$Mailboxes = Get-Mailbox -ResultSize Unlimited
$Mailboxes = Foreach ($Mailbox in $Mailbox){ (get-aduser $mailbox | where { ([string]::IsNullOrEmpty($_.givenname) -eq $false) }).samaccountname }
Foreach ($Mailbox in $Mailboxes)
{
$mbPermissions = get-mailboxpermission $Mailbox
$str_DN = $Mailbox.DistinguishedName
$ad_obj = [ADSI]"GC://$str_DN"
Foreach ($mbPermission in $mbPermissions)
{
If ($mbPermission.IsInherited -eq $False -and $mbPermission.User -notlike "NT-AUTORITÄT\SELBST")
{
[System.IO.File]::AppendAllText($File_Path, "$($mbPermission.Identity);$($mbPermission.User);$($mbPermission.AccessRights);$($mbPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
$ADPermissions = get-ADPermission $Mailbox.Identity
Foreach ($ADPermission in $ADPermissions)
{
If ($ADPermission.ExtendedRights -like "Send-As" -and $ADPermission.User -notlike "NT-AUTORITÄT\SELBST" -and $ADPermission.Deny -eq $false)
{
[System.IO.File]::AppendAllText($File_Path, "$($ADPermission.Identity);$($ADPermission.User);$($ADPermission.ExtendedRights);$($ADPermission.Deny)`r", $Utf8NoBomEncoding)
}
}
}
I want to generate a list of users, with the exception of a list of names. This exclusion list changes from week to week.
$exclude = #('smith, bob', 'jones, tom', ...)
$csvmaster = #()
$uacct = 'User Account'
$UserID = 'User ID'
$lastname = 'Last Name'
... other attributes
$ulist = get-aduser -filter {enabled -eq 'true'} -properties * | ? {$_.Distinguishedname -like '*Standard User*' -and $_.title -ne $null -and $_.employeenumber -ne $null}
foreach ($u in $ulist)
{
if ($u.name -notmatch $exclude) {
$csvline = New-Object System.Object
$csvline | Add-Member -MemberType NoteProperty -name $UserID -value $u.EmployeeNumber
$csvline | Add-Member -MemberType NoteProperty -name $lastname -value $u.surname
...other attributes
$csvmaster += $csvline
}
}
...Output to csv
When I run this, the names I want to exclude still make it into the list. I also tried -notcontains and excluding them like this:
$ulist = get-aduser -filter {enabled -eq 'true'} -properties * | ? {$_.Distinguishedname -like '*Standard User*' -and $_.title -ne $null -and $_.employeenumber -ne $null -and $_.name -notmatch $exclude}
This behaves the same way.
Cheers.
So I think my problem was the way Get-ADUser accepts input value. And/Or my logic in general. I changed the code to this:
$exclude = #( ..list..of..names..)
$csvline = #()
$ulist = get-aduser ...
foreach ($u in $ulist)
{
if ($exclude -notcontains $u.name)
{
...
$csvline += $u.name
}
}
And it is doing what I need.