Recipient Preview Filter for particular recipient container

Just quick post. You have dynamic distribution group, you need to scope it for special container and you need to preview recipients for that DDL just inside the container. Solution is easy. Use Where condition and with definition of recipient container in for of distinguished name:

 


$x = Get-DynamicDistributionGroup mailNY
GetRrecipient -RecipientPreviewFilter $x.recipientfilter |Where {$_.Distinguishedname -like "*OU=subou,OU=ou,DC=domain,DC=suffix"} |select *city*,distinguishedname

Easy? Yes, but I always forgot how I did it, so that is why I posted it.

Advertisements

SPF validation Powershell script

I have created a script to validate SPF records of your domains against kitterman´s WEB site.

  • Import functions Get-DNS and Validate-SPF into your Powershell profile or Powershell session.
  • Use is very easy. run Validate-SPF <domainname>, it returns if SPF is valid (PASS), invalid (FAIL) or not present (OK) and kittermann´s message as an object.

Update:Requires Windows 8 and newer (Thanks Wojciech)


function Validate-SPF ($domain){
$y = $null
$y = get-dns $domain | where {$_.strings -like "*spf1*"} | select name,strings
$res = $null
$res = "" | select domain,result,message,txt
$res.domain = $domain
if ($y -ne $null){
Write-Host "SPF present: $($y.strings). Checking validity ..." -ForegroundColor Green
$web = Invoke-WebRequest -Uri http://www.kitterman.com/spf/validate.html
$web.forms[0].fields.domain = "$($y.name)"
$result = Invoke-RestMethod http://www.kitterman.com/getspf2.py -Body $web.forms[0].fields
$message = $result.replace("`r`n","--")
$res.message = $result
$res.txt = $message
if ($message -like "*passed*"){
$res.result = "Passed"
} else {
$res.result = "FAIL"}
} else {
$res.message = "N/A"
$res.result = "OK"
$res.txt = "N/A"
}
return $res
}


function Get-DNS ([String]$domain){
resolve-dnsname $domain -type MX
resolve-dnsname $domain -type TXT

}spfvalidator

 

Exchange 2013,2010 – Event logs gathering (Health Check part 2.)

I have mede a script, which connects to all Exchange servers in organization using remote powershell and gathers all event logs for you to central place. Then it analyses event logs based on previous article (https://wordpress.com/post/40179192/2178/) (database of event IDs must be stored as CSV file delimited by semicolon). The result is again XLSX file with two worksheets. One is event ID raw data and second is analyzed event IDs. If there is event ID not present in the database, script marks it with “NEW IN DB, must be found first” in the Action row. If you run the script with empy CSV for database, it will generate XLSX as well, but you have to find solution for every event.

The script utilizes Export-XLSX.ps1. Thanks guys for the great job! https://gallery.technet.microsoft.com/office/Export-XLSX-PowerShell-f2f0c035

Example of script:

# Event logs gathering
Write-Host "Event logs gathering ... " -ForegroundColor White
#Event log variables
$exservers = get-exchangeserver
$evtlogdaysback = 1
$experfwizserver = hostname
$experfwizfilepath = "\\$($experfwizserver)\c$\ExchangeHealthCheck"   #  zmeneno z c:...
$outpath = "\\$($experfwizserver)\c$\ExchangeHealthCheck"
$WellKnownEventLogDB = import-csv .\wellknownevents.csv -Delimiter ";"

############## evt log gathering
$evtlogout = @()
  foreach ($exsvr in $exservers){
                Write-Host "Processing Exchange server $($exsvr.fqdn) ...."
                
                $evtlogout +=Invoke-Command -computername $exsvr.fqdn -ScriptBlock {
                $dat = ((get-date).adddays(-$args[0]))
                Get-eventlog -LogName * | select log | foreach {get-eventlog -LogName $_.log -EntryType Error,warning | where {$_.TimeGenerated -gt $dat} | select eventID,MachineName,Category,CategoryNumber,EntryType,Message,Source,TimeGenerated,PSComputerName}
                } -ArgumentList $evtlogdaysback

       }
       $bck = $evtlogout
$evtlogout = $evtlogout
#EVTlog cleaning
$i = 0
$out = @()
foreach ($line in $evtlogout){
$melio = ""
$line.message = $line.message.replace("`r`n","--")
foreach ($meli in $line.message){$melio = "$($melio) " + $meli}
$line.message = $melio
$out +=$line
}
# Event logs grouping, counting and comparing with WellKnownEventLogs Flat File DB
$res = @()
$WellKnownEventLogDB = import-csv .\wellknownevents.csv -Delimiter ";"
$analysedevents = "" | select count,eventid,entrytype,source,Message,action,affectedservers
$groupedlogs = $out | group eventID,source | sort name
foreach ($evtgroup in $groupedlogs){
        $match = 0
        foreach ($dbline in $WellKnownEventLogDB){

            if($dbline.Eventid -match $evtgroup.name.split(",")[0]){
              if($dbline.Source -match $evtgroup.name.split(",")[1].trim()){
                            $analysedevents = "" | select count,eventid,entrytype,source,Message,action,affectedservers
                            $analysedevents.eventid = $dbline.Eventid                        
                            $analysedevents.entrytype = $dbline.EntryType
                            $analysedevents.source = $dbline.Source
                            $analysedevents.Message  = $dbline.Message
                            $analysedevents.action =  $dbline.action
                            $analysedevents.affectedservers = "$($evtgroup.group | select machinename | group machinename | select name)"
                            $analysedevents.count = $evtgroup.count
                            $res +=$analysedevents
                            $match = 1
                            }
                }
        }
 $match
       if ($match -eq 1){}else{
            $analysedevents = "" | select count,eventid,entrytype,source,message,action,affectedservers
            $analysedevents.eventid = $evtgroup.name.split(",")[0]                        
            $analysedevents.EntryType = $evtgroup.group[0].EntryType
            $analysedevents.source = $evtgroup.name.split(",")[1].trim()
            $analysedevents.message  = $evtgroup.group[0].message
            $analysedevents.action =  "NEW IN DB, must be found first"
            $analysedevents.affectedservers = "$($evtgroup.group | select machinename | group machinename | select name)"
            $analysedevents.count = $evtgroup.count
                $res +=$analysedevents
               }

}
$res | .\Export-xlsx -path "$($xlsout)\EventLogs.xlsx" -WorKsheetname "Analyzed EVENT logs" -Append
$EvtNotExchrelLOGS  = $out
$EvtNotExchrelLOGS | .\Export-xlsx -path "$($xlsout)\EventLogs.xlsx" -WorKsheetname "Event logs raw data" -Append






################################################################################################################################################################################################################################


################################
#   Ends HERE                  #
################################


 Download:

https://onedrive.live.com/redir?resid=3941F86AC9A4F457!9241&authkey=!AG73DJErvetxKsM&ithint=file%2czip

 

Script to run and collect all Exchange performance counters from your environment to server running the tool

Script runs the remote PowerShell session against all Exchange servers, copies the Experfwiz utility to each one and runs performance counters for the time defined by administrator and exports results to the folder, from which it was run.

1. Copy ExPerfWiz.ps1 from: https://experfwiz.codeplex.com/ to some server running Exchange Management Shell to c:\ExchangeHealthCheck
2. Run the script
3. Enter Organization Admin Credentials
4. will be asked to confirm to run perfmon on each server

perfwiz

#Author: Zbynek Salon

#Description: This is small script to collect performace counters from All servrers in your environment to single folder on the server running perfwiz.

#Variables experfwiz

$date = get-date

$UserCredential = Get-Credential

$experfwizstart = $date.AddHours(1)

$experfwizduration = "04:00:00"

$experfwizinterval = 5

$experfwizserver = hostname

$experfwizfilepath = "\\$($experfwizserver)\c$\ExchangeHealthCheck" # zmeneno z c:...

$experfwizmaxsize = 512

###################################################################################################################################################################################################

#Performance counters

$localhost = hostname

$script = get-content "\\$($localhost)\c$\ExchangeHealthCheck\experfwiz.ps1"

$exservers = get-exchangeserver

 foreach ($exsvr in $exservers){

 Write-Host "Processing Exchange server $($exsvr.fqdn) ...."

 Invoke-Command -computername $exsvr.fqdn -ScriptBlock {

 #copying script to EXBIN

 Write-Host "Copying PerfWiz to $($args[1])."

 Test-Path $args[1]

 $exinstall = $args[1]

 $x = $args[0] 

 $x | out-file "$($exinstall)Scripts\experfwiz.ps1"

 Start-Sleep 1

 Write-Host "Importing Exchange PS Session." 

 $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$($args[8])/PowerShell/" -Authentication Kerberos -Credential $args[9] -AllowRedirection

 Import-PSSession $Session

 cd "$($exinstall)Scripts"

 Set-ExecutionPolicy Unrestricted -Confirm:$false

 .\experfwiz.ps1 -delete #-FilePath $args[5] -Server $args[6] -MaxSize $args[7]

 .\experfwiz.ps1 -Duration "$($args[3])" -interval "$($args[4])" -FilePath "$($args[5])" #-Server "$($args[6])" #-MaxSize $args[7]

 #running perfmon

 } -ArgumentList $script, $exinstall, $experfwizstart, $experfwizduration, $experfwizinterval, $experfwizfilepath, $experfwizserver, $experfwizmaxsize, $exsvr.fqdn, $usercredential

}

##################################################################################################################################################################################################

The script can be downloaded from my OneDrive:
OneDrive

Log Search script

This is just a small easy script to search log content in defined location and time range for string value. If you know what to search in many log files, it can help you to narrow search.

#logsearch
#Author: Zbynek Salon
#Path to search
$path = "D:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\FrontEnd\ProtocolLog\SmtpReceive"
#What to search (the best would be for example e-mail address for some SMTP log)
$str = "PRX5"
#Range (Start must be lower then end)
$start = "5/25/2014 8:00AM"
$end = "5/28/2014 9:00AM"
Get-ChildItem $path | where {($_.LastWriteTime -gt $Start) -and ($_.LastWriteTime -lt $End)} | foreach {$_
 $x = Get-Content -Path "$($path)\$_"
 if ($x -like "*$($str)*"){Write-Host "$_ contains $($str)" -ForegroundColor Green}
}

Script to gather FullAccess and SendAs permissions

I wrote this script to gather FullAccess and SendAs permissions to divide mailboxes into logical batches. May be somebody find it helpful.

#Purpose of this script is to gather full access and Send-As permissions of all mailboxes in organization
#Author: Zbynek Salon
#importing needed module
Import-Module Servermanager
$out = @()
$path = "c:\temp\FASA.txt"
$out +="Identity-email;Full Access;Send AS"
set-adserversettings -ViewEntireForest $true
#gathering info
$list = Get-Mailbox -resultsize unlimited | select alias,displayname,primarysmtpaddress,userprincipalname,distinguishedname
$i = 0
Foreach ($line in $list){
$sa = $null
$fa = $null
$fa = get-mailbox "$($line.distinguishedname)" | get-mailboxpermission | where {($_.IsInherited -like $false) -and ($_.accessrights -like "*Full*") -and ($_.user -notlike "*SELF*")}
$sa = get-mailbox "$($line.distinguishedname)" | get-adpermission | where {($_.extendedrights -like "*Send*") -and ($_.IsInherited -like $false) -and ($_.Deny -like $false)  -and ($_.user -notlike "*SELF*")}
Write-host "°°°°°°°°°°°°°°$($line.alias)"
#Full Access section
write-host "Full Access $($line.displayname)"
$fapo=$null
$sapo=$null
if ($fa -ne $null){
$fapo = "FA:"
            foreach ($fap in $fa){
                $o2=$null
                $o=$null
                #query object from AD using LDAP (translate SID to DN)
                $o = [adsi]"LDAP://<SID=$($fap.user.securityidentifier)>"
                #query needed properties of AD object (AD object is used to query for all object types
                $o2 = get-adobject "$($o.distinguishedname)" -properties * | select displayname,userprincipalname
                $o2
                if($o2 -ne $null){
                    $fapo = $fapo + "|$($o2.displayname)*$($o2.userprincipalname)"
                }
                else{$fapo = $fapo + "|NoExist*$($fap.user.securityidentifier)" }
            }
}else{}
#Send As section
write-host "Send - AS $($line.displayname)"
if ($sa -ne $null){
$sapo = "SA:"
            foreach ($sap in $sa){
                $u2=$null
                $u=$null
                $u = [adsi]"LDAP://<SID=$($sap.user.securityidentifier)>"
                $u2 = get-adobject "$($u.distinguishedname)" -properties * | select displayname,userprincipalname
                $u2
                if($u2 -ne $null){
                    $sapo = $sapo + "|$($u2.displayname)*$($u2.userprincipalname)"
                }
                else{$sapo = $sapo + "|NoExist*$($fap.user.securityidentifier)" }
            }
 }else{}
$out += "$($line.displayname)*$($line.userprincipalname);$($fapo);$($sapo)"
}

$out | out-file "$($path)"

Office 365 – Adding SMTP addresses while DirSync without ADFS/Hybrid

Background

There are limitations, when you deploy Office 365 without ADFS/Hybrid. In this article I would like to write about SMTP addresses.

  • This attribute is synchronized to Office 365
  • You cannot add SMTP addresses on the cloud side, so you have to use attribute editor or Powershell On-Premise instead
  • To use Powershell you need to import module for Server manager and one of the methods to add / remove or replace SMTP addresses is to use Set-ADUser cmdlet, where you add string values to multivalue property “ProxyAddresses”
  • More proxy addresses can be added at the time
get-aduser -identity "stokurev" | set-aduser -add @{'ProxyAddresses'=@("SMTP:anatolij.stokurev@domain.com","smtp:stokurev@domain.com")}

Example

As an example here is the script to double existing aliases with another domain suffix

#Purpose of this script is to double aliases of domain.suffix to domain.suffix2 as secondary SMTP addresses
#Author: Zbynek Salon
#importing needed module
Import-Module Servermanager
#gathering and adding aliases
$x = get-aduser -SearchBase "OU=SUFFIX2,OU=Office365,OU=People,DC=DOMAIN,DC=SUFFIX2" -filter * -pr * | select SAMAccountname,UserPrincipalName,proxyaddresses
foreach ($line in $x){
    foreach ($addr in $line.proxyaddresses){
                if ($addr -like "smtp:*"){
                $addr = $addr.replace("DOMAIN.SUFFIX","DOMAIN.SUFFIX2")
                $addr = $addr.replace("SMTP:","")
                $addr = $addr.replace("smtp:","")
                $addr
                get-aduser -identity "$($line.samaccountname)" | set-aduser -add @{'ProxyAddresses'=@("smtp:$($addr)")}

                }
                }
               
}
#check results
$y = get-aduser -SearchBase "OU=SUFFIX2,OU=Office365,OU=People,DC=DOMAIN,DC=SUFFIX2" -filter * -pr * | select SAMAccountname,UserPrincipalName,proxyaddresses
foreach ($line in $y){
$line.samaccountname
    foreach ($addr in $line.proxyaddresses){
                if ($addr -like "smtp:*"){
                $addr
                }
                }
               
}