Simple MIM Sync Run Profiles Scheduler using PowerShell and Task Scheduler – GG EZ

Today I’m going to share one weird trick to schedule MIM Run Profiles using PowerShell. Consultants hate me. Let’s get started.


We are going to create two folders. The first folder is where we are going to store the PowerShell script and configuration. The second folder is where we are going to store our logfiles. I will use C:\MIMRunScheduler and C:\MIMRunScheduler\Log.

param([string]$configfile=$(Read-Host -prompt "Configfile"))

### Load Configuration Data ###
[xml]$maconfig=(Get-Content $configfile)
"" > $maconfig.runcycle.logfile
### Functions ###
$line = "---------------------------------------------------------------------------------"
function Write-Output-Banner([string]$msg) {
       Write-Output $line,(" "+$msg),$line
    Write-Output $line,(" "+$msg),$line | Add-Content $sourceFolder"Log\$(Get-Date -f yyyy-MM-dd).log"

function Write-Output-Text([string]$msg) {
       Write-Output $msg
    Write-Output $msg | Add-Content $sourceFolder"Log\$(Get-Date -f yyyy-MM-dd).log"

### Get Management Agent Data ###
$allMA = @(get-wmiobject -class "MIIS_ManagementAgent" -namespace "root\MicrosoftIdentityIntegrationServer" -computername $maconfig.runcycle.computername)
$numOfExecDone = 0

### Main Script ###
do {
       Write-Output-Banner("Execution #:"+(++$numOfExecDone)+" - Date: "+(date))
       foreach($MANextRun in $ {
             $found = $false;
             foreach($MA in $allMA) {   
               if(!$found) {
                    if($MA.Name.Equals($ {
                           Write-Output-Banner("MA: "+$MA.Name+" [Type: "+$MA.Type+"]")
                           Write-Output-Text(" - Starting Pre-Script: "+$MANextRun.preScript)
                           invoke-expression $MANextRun.preScript | Out-Null
                           Write-Output-Text(" - Done`n")
                           foreach($profileName in $MANextRun.profilesToRun) {
                                  Write-Output-Text(" - Starting Profile: "+$profileName)
                                  $datetimeBefore = Get-Date;
                                  $result = $MA.Execute($profileName);
                                  $datetimeAfter = Get-Date;
                                  $duration = $datetimeAfter - $datetimeBefore;
                                  Write-Output-Text(" - Done with status: "+$result.ReturnValue+" - Duration: "+$duration.Hours+":"+$duration.Minutes+":"+$duration.Seconds+"`n")
                           Write-Output-Text(" - Starting Post-Script: "+$MANextRun.postScript)
                           invoke-expression $MANextRun.postScript | Out-Null
                           Write-Output-Text(" - Done`n")
                           Start-Sleep -s $MANextRun.waitSeconds
             if(!$found) { Write-Output-Text("Not found MA name :"+$; }

       $continue = ($maconfig.runcycle.cycleWaitSeconds -EQ 0) -OR ($numOfExecDone -lt $maconfig.runcycle.numOfExecs) -OR ($maconfig.runcycle.numOfExecs -EQ -1)
       if($continue) { 
             Write-Output-Banner("Sleeping "+$maconfig.runcycle.cycleWaitSeconds+" seconds")
             Start-Sleep -s $maconfig.runcycle.cycleWaitSeconds
} while($continue)

Save the PowerShell script as C:\MIMRunScheduler\MIMRunCycle.ps1.

The PowerShell script accepts an XML configuration file as a parameter and causes the MIM Synchronization Engine runs to be performed. How the runs are performed is described in the configuration file.

Within the PowerShell script, there is a $sourceFolder variable. This is responsible for the location where the log files will reside.

Script Syntax

.\MIMRunCycle.ps1 [-configFile] <location>

-configFile <location>

The <location> refers to the location of the configuration file. The following example shows how this can be done:

-configfile C:\MIMRunScheduler\FULLConfig.XML

Accept wildcard characters?False
Accept pipeline input?False


We are going to create two additional scripts called C:\MIMRunScheduler\pre.ps1 and C:\MIMRunScheduler\post.ps1. If you want to perform an action right before or after a run, you can use these two scripts. We are going to leave them empty.

<?xml version="1.0" encoding="UTF-8"?>
<runcycle numOfExecs="0" cycleWaitSeconds="15" computerName=".">

Save the configuration file as C:\MIMRunScheduler\FULLConfig.xml.

Configuration Syntax

Each configuration file starts with the XML declaration.

<?xml version="1.0" encoding="UTF-8"?>

After that, run cycles (runcycle in XML) can be defined. A runcycle contains three parameters.

<runcycle numOfExecs="0" cycleWaitSeconds="15" computerName=".">
numOfExecsInteger0 = perform the run once
-1 = perform the runs in perpetuity
>0 = define how often the runs should be performed
cycleWaitSecondsIntegerTime between performing run cycles in seconds.
computerNameStringSpecify the computer name in FQDN or in NetBIOS on which MIM is installed. Use the value “.” if the PowerShell script is running on the same server on which MIM is installed.

In a runcycle, multiple MA elements (<MA>) can be defined. In each MA element contains the following elements.

nameStringSpecify the name of the Management Agent.
preScriptStringSpecify the location of the PowerShell script to be performed before the run.
profilesToRunStringSpecify the run profile of the selected Management Agent from the name element.
postScriptStringSpecify the location of the PowerShell script to be performed after the run.
waitSecondsIntegerSpecify how many seconds to wait between running the Management Agents.

Task Scheduler

Create a new task in Windows Task Scheduler.

In the General tab, ensure that the task is run by a service account with sufficient rights in MIMSync. Furthermore, pay attention to the Local Security PolicyLocal PoliciesUser Rights Management > Log on as a batch job permission.

Go to the Actions tab.

Press New… to create a new action.

Action:Start a program
Program/script:Powershell.exe “C:\MIMRunScheduler\MIMRunCycle.ps1”
Add arguments (optional):-configfile “C:\MIMRunScheduler\FULLConfig.XML”

Click on OK to save.

Side note: In some environments, the PowerShell execution policy is set to restricted so make sure that’s dealt with first with the system administrator and security officer.

Action:Start a program
Program/script:Powershell.exe -ExecutionPolicy Bypass “C:\MIMRunScheduler\MIMRunCycle.ps1”
Add arguments (optional):-configfile “C:\MIMRunScheduler\FULLConfig.XML”
Disclaimer: Use -ExecutionPolicy Bypass at your own discretion. CISO’s hate this one trick.

Save and run the task.


That’s all folks! I really prefer this method of scheduling MIMSync runs because the script is very lightweight and easy to understand. Hope that you can make use of this. Have a good one.


FIM Service Management Agent (MIMMA) is not responsive and ends with a stopped-server error – [sadness noises]

The stopped-server error is difficult to troubleshoot because of its indistinct error reporting and multiple causes. It is basically saying that something has happened but Microsoft Identity Manager Synchronization Service (MIMSync) doesn’t know what exactly. It is indicating that the error is beyond the scope of MIMSync. We should focus on what the MIMMA is trying to do in order to troubleshoot this correctly.

Let’s take a look at the architecture of MIM in general. The architecture diagram is based on FIM but this still apply to MIM. As for naming convention we’ll continue to use MIMSync and MIMService.

FIM Architecture Diagram by Brad Turner and David Lundell

We can see that the MIMSync is located in the application tier between the MIMService and the database servers. Most of the time the MIMService is also installed on the MIMPortal server but as shown in the diagram, they are two separate entities. This means that if I disable every Microsoft Internet Information Services (IIS) instances that is hosting MIMPortal, MIMService will continue to run as this is a stand-alone web service (Microsoft.ResourceManagement.Service.exe). As for the scope of this problem, we have established that the stopped-server error doesn’t involve MIMPortal nor IIS.

The MIMMA behaves like a SQLMA with additional ECMA/XMA properties. It connects to the database server and to the MIMService’s base address. The export run in particular connects to the MIMService. Should the MIMService endpoint be unavailable, the export will generate the following error.

An error occurred in executing a Web service object request. 
Type: System.ServiceModel.EndpointNotFoundException 

Message: There was no endpoint listening at http://mim.identandy.local:5725/ResourceManagementService/MEX that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

Stack Trace:    at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   at System.Net.HttpWebRequest.GetRequestStream()
   at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()

Inner Exception: Unable to connect to the remote server


There are multiple causes that could make the stopped-server error occur. I have categorized them as the following four suspects:

  • The MIMService is unreachable. We need to establish what is preventing the connection between MIMSync and MIMService.
    • Check the Windows Services Manager (services.msc) whether or not MIMService is running.
    • If the MIMService isn’t running, check if the service account has sufficient rights.
    • Check the firewall whether or not port 5725 is blocked.
    • Check the connectivity to the MIMService endpoint using a browser. It should display a default WCF services page.
  • The SQL Server is unreachable. We need to confirm that the management agent can connect to the SQL database and server.
    • Check the SQL Server Configuration Manager whether or not SQL Server and the concerning instance are running.
    • Check the firewall if the necessary ports are open.
    • Check the SQL Server Client Network Utility (cliconfg.exe) whether or not the correct network library and server name is being used. Normally I would use TCP/IP with “Dynamically determine port” enabled.
    • Check the SQL Server Management Studio (SSMS) whether or not the service account has login permissions.
  • The SQL Server is unresponsive. We can assume that MIMSync can successfully (or partially) connect to the database server.
    • Check the Event Viewer for SQL timeout exceptions such as “Net SqlClient Data Provider: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding“.
      • This indicates that there are performance problems that needs to be addressed.
    • Check the Event Viewer for SQL permission exceptions such as “System.Data.SqlClient.SqlException: The EXECUTE permission was denied on the object 'StoredProcedureName', database 'FIMService', schema 'sync'.“.
      • This should be easily fixed by adding the service account to the db_owner role of the FIMService database.
    • Check the Event Viewer for SQL tempdb exceptions such as “Could not allocate space for object ‘dbo.SORT temporary run storage: ***************‘ in database ‘tempdb’ because the ‘PRIMARY’ filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.”.
      • While I haven’t fully established the source of this problem, I have managed to work around this by stopping the MIMSync and MIMService instances and clearing the TempDB’s by either a SQL Server restart or via SQL scripts.
  • The MIMMA, MIMService or SQL Server is taking forever to complete requests. This one is by far the most difficult to troubleshoot.
    • Check if the implementation is following the best practices defined by Microsoft.
    • Check the SQL Server Management Studio (SSMS) to find deadlocks in the FIMService and FIMSynchronization databases.
    • Check the Management Policy Rules (MPR) in MIM Portal to find contradicting rules or erroneous workflows.
    • Check if the server infrastructure is adequately equipped. Ensure that the SQL Server has enough IOPS, memory and CPU to limit bottlenecking.

If you are still experiencing problems, consider getting a MIM health check done by a Microsoft Professional to discover underlying issues that might be the cause of this problem. Contact me for more information.


Unable to disconnect a connector in MIM – Errors… Errors everywhere.

I was greeted with an ambiguous error that occured in Microsoft Identity Manager (MIM) Synchronization Service Manager. (MIMSync) The error message in question:

Could not find any resources appropriate for the specified culture or the neutral culture.
Make sure Microsoft.DirectoryServices.MetadirectoryServices.UI.PropertySheetBase.MMSErrorMessages.resources" was correctly embedded or linked into assembly "PropertySheetBase" at compile time, or that all the satellite assemblies required are loadable and fully signed. [OK]

Let’s start from the beginning. I was trying to disconnect a connector from the connector space in MIMSync and I was greeted with a warning:

You are about to disconnect an unconfirmed provisioned connector or an object that is a pending import delete. This operation will immediately delete the object from connector space. Do you want to continue? [YES/NO]

Sure, I wanted to make it a disconnector but having the object disappear completely would be a viable alternative as well. I clicked on [YES] and then I was shown the “Could not find any resources…” error. What’s going on? The error indicates as if something is wrong with MIMSync itself but it could also be something entirely else.

Upon looking further I’ve found that the object/connector that I was trying to disconnect is having a synchronization error. The synchronization error was “connector-filter-rule-violation” under the synchronization step: “Connector filter (export)”. Then I generated a Full Synchronization preview and here’s what I’ve found in the preview; under the MIM Service management agent, there’s a match with a defined connection filter rule. This is what is causing all the problems!

I opened the MIM Service management agent (MIMMA) and checked the Connector Filter configuration. I found the matched filter that was causing the problem and I deleted it. I went back to the Metaverse Search and opened the connector I wanted to disconnect. Clicked on Disconnect, another “You are about to disconnect an unconfirmed provisioned…” error, clicked on YES and it’s successfully disconnected! I did not have to perform any Import/Syncs/Exports after deleting the connection filter. After that’s done, I restored the connection filter back on the MIMMA.

Job done. ✅

Update (2021-06-27) I’ve noticed that the “Could not find any resources appropriate…” error is directly related to a synchronization error on a management agent. This is because I’ve seen the error happen again but this time, it wasn’t a “connection-filter-rule-violation” error. So if you could fix the synchronization error on one of the connectors of the object you’re trying to disconnect, that will fix the problem.


How to start any program from the Command Prompt (cmd) or the Run dialog – “Sometimes My Genius… It’s Almost Frightening”

We’ve all been here before. We installed some application e.g. OpenSSL and you want to start the application in a directory other than where the OpenSSL executable is actually located. Bam! Error. You can resolve this by adding the folder where the executable is located to the PATH environment variable.

Error: ‘applicationName’ is not recognized as an internal or external command, operable program or batch file.


PATH is an environment variable on Unix-like operating systems, DOS, OS/2, and Microsoft Windows, specifying a set of directories where executable programs are located. In general, each executing process or user session has its own PATH setting.

Wikipedia – PATH (variable)

Well, that’s still not very clear on what it does. Basically, a PATH is a variable that can be set to directories in which executable programs are located so that it can be started without specifying the entire path to the file. This will work in the Command Prompt (cmd) and in the Run dialog in the Start Menu.

To do this you will have to go to the Environment Variables dialog to add new directories to the PATH variable. You can open Control Panel > System > Advanced > Environment Variables or I prefer the more simple method of running the following command in the Run dialog:

%windir%\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables

Select the PATH variable in the User variables list and click on Edit…

Click on New and add the directory path of where the executable is located. We will use OpenSSL as an example.

Click on OK to finish.

And we’re done! You’ve successfully added the OpenSSL bin directory, where the OpenSSL executable is located, to the Path variable. Now we can start OpenSSL from the Command Prompt or the Run dialog without specifying the directory path.

OpenSSL is able to start because the directory of where the executable is located is added to the PATH variable

Creating a Certificate Signing Request (CSR) with multiple Subject Alternative Names (SAN) using OpenSSL – Wait, it’s all secure? Always has been.


When you want to use digital certificates (also known als public key certificate) to establish a secure connection between computers, you will need to create a certificate signing request. A certificate is most commonly used for SSL/TLS, which is to provide confidentiality and integrity between two communicating applications.

The Subject Alternative Name (SAN or subjectAltName) is a field which allows you to define additional host names to be secured by a single certificate (also known as a Multi-Domain Certificate). For example, this can be useful when you have many domains/subdomains that needs to be secured. In terms of finances and pragmatism, you may not want to purchase different certificates as this might get expensive or having multiple certificates can be bothersome to implement.

You might be thinking, this sounds like a wildcard certificate! You’re not wrong as both type of certificates are quite similar. Both SAN and wildcard certificates allows you to secure multiple (sub)domains. However, a wildcard certificate cannot protect both and as the top-level domain (TLD) is different. A wildcard certificate only protects the primary domain (as defined in the Common Name) and any subdomains. Plus, wildcard certificates shouldn’t be used anymore since it’s deprecated as shown in section 7.2 of RFC 6125.

7.2. Wildcard Certificates This document states that the wildcard character ‘*’ SHOULD NOT be included in presented identifiers but MAY be checked by application clients (mainly for the sake of backward compatibility with deployed infrastructure).


  1. Ensure that you have the latest version of OpenSSL installed.
  2. Create a new text file using your favorite simple text editor and name it request.config.
  3. Copy the following text to the request.config file and change the C\ST\L\O\OU\CN\DNS.* attributes accordingly. Go to chapter Definitions and Examples for more information regarding these attributes.

Syntax of a request.config file:

distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
C = <countryName>
ST = <stateOrProvinceName>
L = <localityName>
O = <organizationName>
OU = <organizationalUnit>
CN = <commonName>
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
DNS.1 = <hostName>
DNS.2 = <hostName>

Example of a request.config file:

distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
C = NL
ST = Noord-Holland
L = Amsterdam
O = Identandy
OU = Public Relations
CN =
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
DNS.1 =
DNS.2 =
DNS.3 =
  1. Ensure that there aren’t any whitespaces at the beginning or the end of the lines.
  2. Start the following command to create the certificate signing request.

Syntax of an OpenSSL command to create a CSR:

openssl req -new -out <csr_file> -newkey rsa:2048 -nodes -sha256 -keyout <private_key> -config <request.config>

Example of an OpenSSL command to create a CSR:

openssl req -new -out identandy_com.csr -newkey rsa:2048 -nodes -sha256 -keyout identandy_com_private.key -config request.config
  1. After executing the OpenSSL command you will be greeted with the following message and your CSR (identandy_com.csr) and private key (identandy_com_private.key) have been created.
Generating a RSA private key
writing new private key to 'identandy_com_private.key'
  1. Start the following command to verify the certificate signing request
openssl req -text -noout -verify -in identandy_com.csr

verify OK
Certificate Request:
        Version: 1 (0x0)
        Subject: C = NL, ST = Noord-Holland, L = Amsterdam, O = Identandy, OU = Public Relations, CN =
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
        Requested Extensions:
            X509v3 Key Usage:
                Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
    Signature Algorithm: sha256WithRSAEncryption

And there you have it! That’s all you need to do to generate a CSR using OpenSSL. I hope that you have find it useful and if you have any questions leave a comment below.

Definitions and Examples

Confidentiality is the concept of the measures used to ensure the protection of the secrecy of data, objects, or resources. The goal of confidentiality protection is to prevent or minimize unauthorized access to data. Confidentiality focuses security measures on ensuring that no one other than the intended recipient of a message receives it or is able to read it. Confidentiality protection provides a means for authorized users to access and interact with resources, but it actively prevents unauthorized users from doing so. A wide range of security controls can provide protection for confidentiality, including, but not limited to, encryption, access controls, and steganography.

Integrity is the concept of protecting the reliability and correctness of data. Integrity protection prevents unauthorized alterations of data. It ensures that data remains correct, unaltered, and preserved. Properly implemented integrity protection provides a means for authorized changes while protecting against intended and malicious unauthorized activities (such as viruses and intrusions) as well as mistakes made by authorized users (such as mistakes and oversights).

Country Name (CN) Use the two-letter country code based on ISO 3166-1 alpha-2. Example: NL

State or Province (S) Spell out the state completely; do not abbreviate the state or province name. Example: Noord-Holland

Locality or City (L) Spell out the city or town name completely; do not abbreviate the locality or city name. Example: Amsterdam

Organization (O) If the company or department has an &, @, or any other symbol, the symbol must be spelled out or omitted. Example: XY & Z Corporation would be XYZ Corporation or XY and Z Corporation. 

Organizational Unit (OU)  The Organizational Unit (OU) field is the name of the department or organization unit making the request.

Common Name (CN) The Common Name (CN), also known as the Fully Qualified Domain Name (FQDN), is the characteristic value within a Distinguished Name. Example:

CategoriesWindows Update

Windows Update 2020 July – DNS is as leaky as a basket

Microsoft released a patch for CVE-2020-1350, a Critical Remote Code Execution (RCE) vulnerability in Windows DNS Server that is classified as a ‘wormable’ vulnerability and has a CVSS base score of 10.0.

Let’s start with the vulnerability also known as SIGRed. According to the researcher Sagi Tzadik from Checkpoint Research, this bug existed for over 17 years and it’s an integer overflow vulnerability. What does this all mean?

The DNS service (dns.exe) in Microsoft Windows Server fails to validate a 16-bit register for a SIG Record. An attacker can exploit this and because the DNS Service runs under the SYSTEM context, remote code execution is a possibility or even granting Domain Administrator rights. The CVSS score of 10.0 means that this must be patched as soon as possible. As of writing, Microsoft confirms that the vulnerability hasn’t been exploited yet but I’m sure that this will change soon. A proof-of-concept has shown that this vulnerability can be exploited remotely through an HTTP payload to non-chromium browsers.

Affected Systems

  • Windows Server 2008 for 32-bit Systems Service Pack 2
  • Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core)
  • Windows Server 2008 for x64-based Systems Service Pack 2
  • Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core)
  • Windows Server 2008 R2 for x64-based Systems Service Pack 1
  • Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core)
  • Windows Server 2012
  • Windows Server 2012 (Server Core)
  • Windows Server 2012 R2
  • Windows Server 2012 R2 (Server Core)
  • Windows Server 2016
  • Windows Server 2016 (Server Core)
  • Windows Server 2019
  • Windows Server 2019 (Server Core)
  • Windows Server version 1909 (Server Core)
  • Windows Server version 1903 (Server Core)
  • Windows Server version 2004 (Server Core)


It is highly recommended to patch the affected Windows DNS Servers to prevent the exploitation of this vulnerability as soon as possible. The July update should already been made available in Microsoft Update and WSUS. See Microsoft’s Security Update Guide for more information regarding which security update you need. A system reboot is required after installing the update.


You can define a maximum length of a DNS message over TCP in the registry. Make sure to restart the DNS Service for the registry change to take effect.

Subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters 
Value: TcpReceivePacketSize 
Type: DWORD 
Value data: 0xFF00

You can also do the same by running the following command in an elevated command prompt.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters" /v "TcpReceivePacketSize" /t REG_DWORD /d 0xFF00 /f
net stop DNS && net start DNS

After applying the patch, you can remove the workaround by removing the TcpReceivePacketSize value and its corresponding data.