On Windows PowerShell and other admin-related topics

Invoke Best Practices Analyzer on remote servers using PowerShell

Best Practices Analyzer (BPA) is a management tool integrated in Windows Server 2008 R2 used to scan server roles according to Microsoft best practice guidelines.

Included in the initial release for Windows Server 2008 R2 are the following BPA models:

  • Active Directory Domain Services
  • Active Directory Certificate Services
  • Domain Name System (DNS) Server
  • Remote Desktop Services
  • Web Server (IIS)

Since then several new BPA models are released and available both as separate downloads as well as through Windows Update:

At the time of this writing, a BPA model for 12 of 17 server roles in Windows Server 2008 R2 are available.
The 5 that are not available are:

  • Active Directory Federation Services (ADFS)
  • Active Directory Lightweight Directory Services (AD LDS)
  • Fax Server
  • Print and Document Services
  • Windows Deployment Services

In Server Manager, a BPA summary are available for each installed server role that an BPA Model exists for:


When looking at the properties for an item in BPA you get more information as well as a link to Microsoft TechNet where more information are available for the specific subject:


BPA are built as a PowerShell module, meaning that a PowerShell cmdlet (Invoke-BPAModel) are run in the background when you scan a server role from Server Manager:


This is a great feature to examine if your server roles are configured according to Microsoft`s best practices, however, if you got many servers it will take some time to log on to each server and scan each server role. In addition you don`t get any centralized reporting this way.

Since BPA are based upon Windows PowerShell it`s possible to solve this using the BPA PowerShell module and PowerShell remoting:



I`ve created a sample script to accomplish this, named Invoke-BPAModeling, with the following functionality:

  • Invoke BPA for all available server roles on specified remote servers
  • E-mail reporting
  • File reporting to CSV and HTML

You need to customize the initial variables on the top of the script. You can enable/disable reporting using these variables, as well as specify which servers to work against, SMTP server for e-mail reporting and paths to CSV/HTML reports.
By default, only items with a severity of “Error” and “Warning” are reported. You can change this to also include “Informational” severities by configuring IncludeAllSeverities to true.
On the server running the script from, the Active Directory module for PowerShell must be installed if you want to retrieve computer names from Active Directory. In the sample,  the script are configured to retrieve all computer accounts listed with Windows Server 2008 R2 as operating system.
You might choose alternate methods, like importing the computer names from a csv-file.
I would recommend that you approve the new BPA models mentioned at the beginning of this blog post in WSUS prior to running the script.
The script requires that PowerShell remoting are enabled and configured on the remote servers. Also note that there is a known issue with the BPA module; When the PowerShell execution policy are set to any other than “Undefined” or “Unrestricted” , an error occurs. I`ll update this blog-post as soon as a fix are provided from Microsoft.

When the script executes, it displays the progress based upon the total number of computers running against:


Sample e-mail report containing both CSV and HTML reports as attachment:


Sample HTML-report:


Sample CSV-report converted to an Excel spreadsheet:


Feel free to customize the script for your needs, as well as suggest improvements.


Best Practices Analyzer on Microsoft TechNet


August 17, 2010 - Posted by | Best Practices, Scripting, Windows PowerShell, Windows Server 2008 R2 |


  1. […] short, Invoke-BPAModeling.ps1 queries your Active Directory for any machines that run Windows Server 2008 R2, runs BPA on them […]

    Pingback by Powershell: Scripting Best Practices Analyzer remotely | | January 18, 2011 | Reply

  2. Great script, thank you very much. Two questions:

    – in the reports that are generated, is it possible to hide the results that are already excluded?
    – for each server, role I get:
    Could not find a part of the path ‘C:\Tasks\BPAReports\CA-CertificateServices-13-02-12_08-48.csv’.
    + CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

    Could not find a part of the path ‘C:\Tasks\BPAReports\CA-CertificateServices-13-02-12_08-48.html’.
    + CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

    Why the error is it somehow related to the PowerShell culture?

    Comment by CypherBit | February 13, 2012 | Reply

  3. Thanks, this is exactly what I was looking for. I recently found out about the BPA PowerShell options, and wanted to find a way to centralize it. From the link provided I was able to download the script, but when I did the “copy code” and pasted into notepad and saved, it really butchered the line breaks – notepad++ was MUCH happier about it.

    I’m having a problem wiht getting the file output the the BPAReports share, other than from one of my systems. I suspect it’s a security issue, but I’ve tried making it wide open and still had no luck. E-mail reports are running just fine though, so I know the reports themselves are being generated and working. What account ends up being hte active account for security when the remote PowerShell is running?


    Comment by vNetWise | May 21, 2012 | Reply

  4. […] didn’t have to look long before I found this excellent post (…) by Jan Egil Ring.  I don’t think I could have asked for much better.   The script itself is […]

    Pingback by Invoking Best Practices Analyzer across the network « vNetWise | May 21, 2012 | Reply

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: