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

 

Dirsync errors nad solutions: Event ID 0: Invalid namespace while automatic Sync or Start-OnlineCoexistenceSync, Object not found on the server

I have been facing errors with one of my customers lately. There is hybrid deployment with Exchange on premise and Office 365 with ADFS.

Symptoms:

  • Dirsync stopped to work, because automatic synchronization started to throw invalid namespace errors (Event ID 0)
  • DirSync cannot be run via Start-OnlineCoexistenceSync
  • Dirsync could run manually from GUI

invalid namespace

Cause:

When DirSync is installed on the server, after its configuration DirSync installator creates a service, which by default run synchronization every 3 hours to populate changes of local AD´s objects to the cloud and if Hybrid deplouyment checkbox is ticked during configuration, it also updates few attributes in opposite direction (From Cloud -> On premise).

Behind the scenes this service also creates performance counters to WMI and this is also the problem! In my case CCM agent´s (installed by SCCM) old version has been uninstalled and during uninstallation of CCM agent the repository of WMI has been corrupted. This caused the FIM Synchronization service to fail to run.

Solution:

The solution is not easy and here are the steps need to be run in the following order to make it work and make it work permanenty:

  • Fix MOF files – MOF files are used to register performance counters to WMI. These files can be registered once per product installation or everytime the product upgrades and this is problem. Dirsync Product has by default MOF files, which are registered only once and not during upgrades. This problems come up when CCM agent is uninstalled and MOF files are not re-registered. To prevent this to happen again add the following text to the first line of MOF files for dirsync product:

MOF file location:
%Program Files%\Windows Azure Active Directory Sync\SYNCBUS\Synchronization Service\Bin

MOF files name:
mmswmi.mof

mmswmi-x.mof is used for product uninstallation. Do not change it.

 #PRAGMA AUTORECOVER
//********************************************************
//*                                                      *
//*   Copyright (C) Microsoft. All rights reserved.      *
//*                                                      *
//********************************************************
//
// mmswmi.MOF
//
//===================================================================

  • Repair WMI repository permanently

To repair WMI you must run the following command from the same location as previous step and restart FIM Synchronization service. The result should be “Done!”

mofcomp mmswmi.mof
  • Re-Register FIM Sync Service DLL and restart win management service

From the same location under elevated permissions run:

regsvr32 /s mmswmi.dll
net stop winmgmt
net start winmgmt
  • Re-Run configuration of DirSync

From the location %Program Files%\Windows Azure Active Directory Sync run ConfigWizard.exe

If you receive the following error, move service accounts (MSOL* to OU=Users in root domain of your Onpremise AD)

No object on server

DirSync to Office 365 synchronization failed – Event ID:6126, Event ID:109, Event ID:6801, Event ID:6803, Event ID:6110

I have faced problems with Dirsync synchronization with the following Event IDs:6126,0,109,6801,6803,6110,0

Solution:

Password reset for Dirsync cloud account and its configuration in MIIS client.

Description:

Here is, what I have found in the event log
001

1. Event ID 6126

Synchronization has beedo done but changes of the rules occured
000-6126

2. Event ID 109

Error statest, that synchronization didn´t perform and that change password might help
002-109

3. Event IDs 6801,6803

States the same as Event ID 109. Authentication failure and final state that error has occued.
003-6801
004-6803

4. Event ID 6110

Watermark of delta synchronization was not saved.
005-6110

5. Password needs to be changed in the cloud

Just logon to the cloud and change password via WEB interface

6. Password never expires

As additional stem I have set password to never expire to prevent these problems to occur again
010-password change

7. Set new password in DirSync

In the Windows Azure Active Directory connector you should set new password.

8. OK

009-OK

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
                }
                }
               
}