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.

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

 

Outlook 2013 shows only Online Archive while connected to Office 365

This is just a quick heads up. It started to happen in some environments after last Office 2013 patch in mid January 2015. When Outlook 2013 is restarted after patching, it shows only Online Archive, no primary mailbox and user is unable to send e-mails.

Root cause:

It has not yet been defined, however fix is to disable MAPI over HTTPS on affected client, so I suppose it will be network device, which does not understand MAPI over HTTPS protocol.

Temporary fix:

When changing the below registry key (disable MAPI/HTTP and re-enable RPC/HTTP), the problem disappears:

HKEY_CURRENT_USER\Software\Microsoft\Exchange\MapiHttpDisabled = 1 DWORD

 Permanent fix:

Install Exchange 2013 CU7.

Office 365 – Multi Factor Authentication support part 2. – Enable MFA from user point of view

In previous article I have enabled MFA for user alsajid@salonovi.cz and now I will test its behavior, while MFA Enabled and Enforced

User setup

When I log on for the first time with new user or try to access https://portal.onmicrosoft.com with user with just enabled MFA, Login window will look different and after typing my password it will require to set up MFA.

TEST-setup1

Office 365 talks to you in your prefered language, you can choose mobile application or mobile phone or normal phone to contact and pick up whether to be contacted by SMS or phone call.

MFA setup2

I choose Mobile phone and SMS, next and I am required to verify my device

setup 3

I have received SMS code

setup4

Verification went OK and in next step I am warned, that my password will be working only in browser (1) and for other aplications named in (2) I need to generate App Passwords (3) or agree, that these applications will not be used for my account (4)

setup5

APP Passwords (support for thick clients)

To generate App Passwords I was redirected to Windows Azure Active Directory logon screen, where I have been MFAuthenticated via SMS 🙂

appp1

Now I can create App Passwords

appp2

Next is name of application and then the password is generated and displayed once. You must copy it to clipboard

apppol1 apppol2

Now use the password as you have used your password for Office 365 previously. So basically you use your App Password instead of your Office 365 password.

Described here. This is most important link for support persons on MFA enabled customer´s helpdesk:

http://technet.microsoft.com/library/en-us/dn270518.aspx#apppasswordchange

User´s output with MFA defined and registration process completed in Azure Active Directory (in my case default one way SMS)

PS C:\Windows\system32> get-msoluser -UserPrincipalName testuser@zbycha.onmicrosoft.com | select *au* | select strongaut
henticationmethods -expandproperty strongauthenticationmethods

StrongAuthenticationMethods   ExtensionData                                     IsDefault MethodType
---------------------------   -------------                                     --------- ----------
{Microsoft.Online.Administ... System.Runtime.Serializati...                          True OneWaySMS
{Microsoft.Online.Administ... System.Runtime.Serializati...                         False TwoWayVoiceMobile

 
PS C:\Windows\system32> get-msoluser -UserPrincipalName testuser@zbycha.onmicrosoft.com | select *au* | select strongaut
henticationrequirements -expandproperty strongauthenticationrequirements |fl
StrongAuthenticationRequirements : {Microsoft.Online.Administration.StrongAuthenticationRequirement}
ExtensionData                    : System.Runtime.Serialization.ExtensionDataObject
RelyingParty                     : *
State                            : Enforced

Well so far so good but now , what I finally don´t like. Lets say, that App Passwords are need for not MFA ready apps..ok, you can define as much App Passwords as you want, you can name those, but you can use all of them to all aplications. That is a bit strange. I have generated two App Passwords and I was able to use both for LYNC client.

Office 365 – Multi Factor Authentication support part 1. – Enable MFA in tenant from admin point of view

As you probably know, Microsoft recently updated their information about MFA in Office 365, so here is overview what it can, cannot do, its support and how to set it up.

Description

What do you need to know is http://technet.microsoft.com/en-us/library/dn383636.aspx , but I will place it here as well:

Multi-Factor Authentication for Office 365 is:

  • powered by Azure Multi-Factor Authentication
  • free for Microsoft Office 365 applications
  • works exclusively for Office 365 applications
  • managed from the Office 365 portal

Multi-Factor Authentication for Office 365 offers the following subset of Azure Multi-Factor Authentication capabilities. Each will be described later on or in the next part:

  • Ability to enable and enforce multi-factor authentication for end users
  • Use of a mobile app (online and one-time password [OTP]) as a second authentication factor
  • Use of a phone call as a second authentication factor
  • Use of an SMS message as a second authentication factor
  • Application passwords for non-browser clients (for example, Microsoft Outlook messaging and collaboration client and Microsoft Lync communications software)
  • Default Microsoft greetings during authentication phone calls

Options for MFA

You can use 2 options.

  • First is full featured Azure MFA, which is paid (I don´t have Azure subscription nor want to pay for it, so I will use second option.
  • Second option is to use it for free for Office 365 application which means to enable it in Office 365 portal

How to enable MFA in Office 365 (Admin point of view)

Prerequisites are obvious. You must have working tenant, licenses, test users and so on. After all prerequisites are fulfilled, use the following:

  • Log on to tenant
  • In Office 365 admin center page  go to Users -> Active Users and Set Up in Set Multi Factor Authentication requirements

MFAenableMFAEnable 2 - bulk

  • Process consists of two steps. In first step you enable MFA for user. This allows user to start registration proces in which user select methods of additional verification. supported clients and browsers.

enable2

  • After MFA is enabled, provide user with a link to manage his MFA options. User can visit the link and manage his profile after successful sign in to Office 365

enable3

  • Enforce option is second step to force user, to use MFA after successful registration. Create APP Passwords for not supported clients such as Outlook as a second authentication factor besides username and password is described in part 2.

enforce2

Enforce option is not enabled for admins for security reasons so do not use enforce options for admins, because it will force admins to use browsers only

enforce

While MFA is enabled, you can force user to re-create App Passwords by deleting old ones, provide contact info again and restore MFA for devices, which were previously suspended from MFA, because those devices were registered and user selected to skip MFA for known devices.

Powershell management

To gather if MFA is enabled for user

Get-MSOLUser -UserPrincipalName <UPN> | select strong*

and output (red without MFA, green with enabled MFA)enabledpshaout

To enable MFA

Enable:

#Create the StrongAuthenticationRequirement object + required settings
$mfa= New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$mfa.RelyingParty = "*"
$omfa = @($mfa)
#Enable MFA for a user
Set-MsolUser -UserPrincipalName alsajid@salonovi.cz -StrongAuthenticationRequirements $omfa

Thanks to: http://365lab.net/2014/02/15/office-365-enable-multi-factor-authentication-with-powershell/

Next part describes MFA´s user point of view.

 

 

ADFS migration – part 1. – intro

It is a Cloud age and as a Microsoft fan I use and work with Office 365 and Azure (slightly), so I wanted to post a guide about the key stone of the cloud and on-premise authentication – ADFS. As you probably know, Microsoft has so far relased several versions of ADFS and upgrade is not so easy, especially if there is Office 365 involved.

Versions released:

  • ADFS 1.0 (Windows Server 2003)
  • ADFS 1.1 (Windows Server 2008)
  • ADFS 2.0 (Windows Server 2008 R2)
  • ADFS 2.1 (Windows Server 2012)
  • ADFS 3.0 (Windows Server 2012 R2)

I will write articles about upgrade from ADFS 2.0 -> 2.1 -> 3.0

Prerequisites:

  • 3rd party trusted certificate with host name of ADFS service published in external DNS (in my case *.salonovi.cz by Comodo)
  • Office 365 tenant with verified domains (I use tenant zbycha.onmicrosoft.com with verified domain salonovi.cz)
  • ADFS servers and AADSync to synchronize identities from on-premise to cloud.

As this is the intro part of the series, let me use it, to show, how to connect to multiple Office 365 customers. It is easy, and if you need more security,do not fill passwords but use (get-credential) instead.

function Open-Office365Session (){
$customers = @()
$customers +=( ,("0","Cust1","admin@cust1.onmicrosoft.com","Passwordstring"))
$customers +=( ,("1","Cust2","admin@cust2.onmicrosoft.com","Passwordstring"))
$customers +=( ,("2","Cust3","admin@cust3.onmicrosoft.com","Passwordstring"))
Write-host "Configured customers:"  -ForegroundColor DarkYellow
foreach($cust in $customers){Write-host "$($cust[0]) - $($cust[1])"}
Write-host "Select customer to connect:" -ForegroundColor Green
$selection = Read-Host
$usr = "$($customers[$selection][2])"
$pass = "$($customers[$selection][3])"

                $psw = ConvertTo-SecureString -Force -AsPlainText -String "$($pass)"
                $cred = New-Object System.Management.Automation.PSCredential ($usr, $psw)
                $s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $cred -Authentication Basic -AllowRedirection
                import-pssession $s
                import-module msonline
                connect-MsolService -credential $cred
}

Save it to your profile PS1 file: C:\Users\<username>\Documents\WindowsPowershell\Microsoft.PowerShell_profile.ps1

To run function just open new powershell session everytime, you want to connect to Office 365, type: Open-Office365Session and from menu type number you want.

ADFSp1-1

Thats it. I have prepared Office 365 tenant, I have ADFS servers, 3rd party trusted certificate and I can start working on identity sync between On-Premise and Office 365 using AADSync. Latest AAD Sync can be dowloaded from the following link:

http://www.microsoft.com/en-us/download/details.aspx?id=44225