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



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.


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


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)


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 ūüôā


Now I can create App Passwords


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:


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.

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


  • 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.


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:



Exchange 2013 CU5 – Organization preparation failure – An Active Directory error 0x51 occurred when trying to check the suitability of server DC1.domainexample.com

When you run setup to upgrade Exchange server 2013, it checks prerequisites and one of its actions is to contact Active Directory to check schema version for possible need to update. In my case the problem was, that error 0x51 occured. I was checking what is happening. The first thing was to run netdom query fsmo command to gather which FSMO roles were placed on failing DC1. As it was during Schema version check, I was mostly iterested if Schema master role is present there…. and it was, No I was wondering what is the problem. I went to OU=Domain controllers in ADUC and checked DCs. I realised that Schema master role is running on non GC domain controller.

Solution: To run setup successfully seize FSMO Schema master role on DC with GC in the same AD site as Exchange server.

KPCS is finalist in Microsoft Awards 2014 wordwide!

I am proud to announce, that company I work for KPCS.CZ is second worldwide in Server platform implementation projects category. Besides this nice placement we won 3 categories in Czech Republic and once we are finalist.

So total 5 awards within 1 year! What the great success!

More here:






Extending schema for Exchange 2013 – error id: 8224 #2

I have faced another kind of Error ID: 8224, which was, however on virtual machine, not caused by TCP chimney issue, so here is the solution.


When running command

.\setup /PrepareSchema

I have received error 8224 as shown in picture:

In my previous article the problem was caused by incorrect settings of TCP interface (http://ficility.net/2012/09/06/extending-schema-for-exchange-2013-error-id-8224/), which caused delays in replication and change actually solved the problem. In this case TCP interface was set correctly and I still experienced delays in replication. Here is how to deal with this kind of problem.


Before extending schema domain controllers hosting FSMO roles (at least Schema master) must be accessible and replication should work correctly. In my case there was a problem replicating Schema and Forest zones to secondary DC, which was connected via VPN. I have resolved VPN connection problems and after that I forced replication between DCs. Note, that MS have incorrect syntax on their technet site. You have to use quotations to run command successfully.
Replication errors:

replication problems

To force replication run the following command from elevated command prompt. http://technet.microsoft.com/cs-cz/library/cc742152(v=ws.10).aspx

force replication

repadmin /replicate <SOURCE_DC> <DESTINATION_DC> "<DC=domain,DC=local>"


extending schema

After successful replication it is possible to extend schema.

How to revive Exchange server 2013 + Windows Server 2012 DC from ash – part 2. – DC installation

This part has been done in GUI in my case, however, better is to do it in PowerShell and here are the steps. To install DC on Windows Server 2012 we just need to:

1. Install windows feature Active Directory Domain Services
Open PowerShell and type “Add-WindowsFeature AD-Domain-Services” Enter

Add-WindowsFeature AD-Domain-Services

2. Install windows feature DNS
type “Add-WindowsFeature DNS” Enter

Add-WindowsFeature DNS

3. Install windows features for administration (RSAT*)
type “Add-WindowsFeature RSAT*” Enter

Add-WindowsFeature RSAT*

Once windows features are installed, we can promote computer to DC:
4. Install new DC to existing forest / domain / Site
DC should be GC as well.

Install-ADDSDomainController -CreateDnsDelegation:$false -DatabasePath 'C:\Windows\NTDS' -DomainName 'domain.local' -InstallDns:$true -LogPath 'C:\Windows\NTDS' -NoGlobalCatalog:$false -SiteName 'Default-First-Site-Name' -SysvolPath 'C:\Windows\SYSVOL' -NoRebootOnCompletion:$true -Force:$true -Credential (Get-Credential) -ReplicationSourceDC Server2.domain.local

Next step is to recover Exchange server on the DC.

How to revive Exchange server 2013 + Windows Server 2012 DC from ash – part 1. – DC cleanup


Before error there was 1 Exchange server 2013 + DC (Server1) and second server with backup DC (Server2). Server1 hosted all FSMO roles. Server2 was only DC + GC + Sharepoint server.


SSD disk as system drive on Exchange server + DC is not a good idea and one of my friends wanted to have it. It worked 6 months and then crashed. Everything is lost, but one last DC in forest. I started to solve the problem. First of all I needed to install the server with same name and promote it to DC. It is not easy task, because first of all it is needed to seize FSMO role to live domain controller. I started to seize the roles, but it is not so easy task when FSMO role holder is dead server. Finally use of NTDSUTIL will help but steps needed are quite hard so here are the steps. Thanks to Petri.co.il article: http://www.petri.co.il/delete_failed_dcs_from_ad.htm


The goal is to seize roles from Server1 to Server2 and remove old server computer account from AD. In other words make primary domain controller from Server2. We need to use NTDSUTIL.EXE (already part of Windows Server 2012 with installed DC).

1. Run NTDSUTIL.EXE – commands of NTDSUTIL will be opened

PS D:\>ntdsutil

2.At the Ntdsutil: type “metadata cleanup” Enter.

ntdsutil: metadata cleanup
metadata cleanup:

3.At the metadata cleanup: type “connections” Enter.

metadata cleanup: connections
server connections:

4.At the server connections: type “connect to server ServerEnter, where Server is working domain controller, to clean up the metadata of the failed DC.

server connections: connect to server Server2
Binding to Server2 ...
Connected to Server2 using credentials of locally logged on user.
server connections:
Note: Windows Server 2003 Service Pack 1 eliminates the need for the above step.

5.Type “quit” Enter to return you to the metadata cleanup: prompt.

server connections: quit
metadata cleanup:

6.Type “select operation target” Enter.

metadata cleanup: Select operation target
select operation target:

7.Type “list domains” Enter. This lists all domains in the forest with a number associated with each.

select operation target: list domains
Found 1 domain(s)
0 - DC=domain,DC=local
select operation target:

8.Type “select domain number“, where number is the number of domain with failed server.

select operation target: Select domain 0
No current site
Domain - DC=domain,DC=local
No current server
No current Naming Context
select operation target:

9.Type “list sites” Enter.

select operation target: List sites
Found 1 site(s)
0 - CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
select operation target:

10.Type “select site numberEnter, where number is the number of the site, where failed DC was member.¬®

select operation target: Select site 0
Site - CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
Domain - DC=domain,DC=local
No current server
No current Naming Context
select operation target:

11.Type “list servers in site” Enter. This will list all servers in previously selected site.

select operation target: List servers in site
Found 2 server(s)
0 - CN=Server1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
1 - CN=Server2,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
select operation target:

12.Type “select server numberEnter, where number refers to the DC to be removed.

select operation target: Select server 0
Site - CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
Domain - DC=domain,DC=local
Server - CN=Server1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
 DSA object - CN=NTDS Settings,CN=Server1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local
 DNS host name - Server1.dpetri.net
 Computer object - CN=Server1,OU=Domain Controllers,DC=domain,DC=local
No current Naming Context
select operation target:

13.Type “quit” Enter. The Metadata cleanup menu is displayed.

select operation target: quit
metadata cleanup:

14.Type “remove selected server” Enter.

Warning message appears. Read it, and if you agree, select Yes.

metadata cleanup: Remove selected server
"CN=Server1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=local" removed from server "Server2"
metadata cleanup:

AD confirms DC is removed. First part is over. Roles should be seized to server2:

15. Type “netdom query fsmo” Enter and check results:

PS D:\> netdom query fsmo
Schema master               Server2.domain.local
Domain naming master        Server2.domain.local
PDC                         Server2.domain.local
RID pool manager            Server2.domain.local
Infrastructure master       Server2.domain.local
The command completed successfully.

PS D:\>

16. Delete computer account for Server2 from AD
To perform this step you must give yourself permission to full control this computer object.

17. Check DNS records and remove DNS records for this computer account.

TLS / SSL cipher strength change

One of my customers asked me today what is the configuration of their send connectors, because they need to establish new boundary encryption between them and business partner. One of the settings was to check connectors what ciphers does it use.

I havent seen that setting before on Exchange side, so I start googling a bit and after few dead ends I have found this article: http://social.technet.microsoft.com/Forums/en-US/exchangesvrgeneral/thread/5830c533-38eb-4d88-92fe-6e1a02d7bac4

Thanks to JShan99 here it is.

Cipher is the combination of hash and encryption algorithm which can be used and is compatible on all ends of communication channel. Ciphers are used to protect data and communication against unauthorised access, so strength of cipher is the most important. Ciphers can be set via group policy by the following settings. The first cipher in the list should be the strongest one and then the list should fall beck to less stronger ones and so on to lowest, however standard cipher set by default in Windows Server 2008 R2 is not the strongest one.

Default Settings

open: gpedit.msc -> Computer Settings -> Administrative templates -> Network -> SSL Configuration Settings ->SSL Cipher Suite Order and you will see Not Configured and default list of ciphers in order from 1st to last to try.


Change settings

  • Click Enabled radio button and on the left side fill in the correct order of ciphers from strongest or most preferred to use to weak ones or less preferred.


  • Apply settings
  • Reboot computer

Settings can be managed via GPO.

Update: Exchange 2013 is not supported on servers running FIPS (algoritnms for hashing and signing supported by US Federated Information Oricessing Standard: http://support.microsoft.com/?kbid=811833)