Start or Stop All D365 F&O Services on a Dev VM with One PowerShell Script

Why you need one script to start and stop D365 F&O services

If you develop on a Dynamics 365 Finance & Operations (D365 F&O) one-box dev VM, you start and stop the same services every week. This post gives you one PowerShell script that does it in a single command: pass 1 to start every D365 F&O service, or 0 (the default) to stop them all.

You need to stop the D365 F&O services more often than you think:

  • Before a database restore or refresh. Microsoft's own steps stop the AOSService app pool and the Batch Management Service before replacing AxDB (Microsoft Learn).
  • Before deleting a model. Microsoft Learn says to stop the AOS and Batch services first, then run a full database sync after restarting (Microsoft Learn).
  • When a build fails with locked DLLs in the PackagesLocalDirectory bin folder.
  • To free RAM and CPU when you only need Visual Studio, or before shutting the VM down.

The script covers IIS and the AOSService app pool (the AOS), DynamicsAxBatch (Batch), MR2012ProcessService (Financial Reporting), the Data Import/Export Framework (DIXF) service, SSRS and the LCS diagnostics client. It skips any service your VM does not have and prints a status table at the end.

The PowerShell script to start or stop all D365 F&O services

Save this as D365-Services.ps1 on your dev VM, for example in C:\Scripts.

<#
.SYNOPSIS
    Start or stop all D365 F&O services on a dev (one-box) VM.

.PARAMETER Action
    1 = Start all services
    0 = Stop all services (default)

.EXAMPLE
    .\D365-Services.ps1          # stops everything (default)
    .\D365-Services.ps1 0        # stops everything
    .\D365-Services.ps1 1        # starts everything

.NOTES
    Run as Administrator.
#>

param(
    [ValidateSet(0, 1)]
    [int]$Action = 0
)

# --- Must run elevated ---------------------------------------------------------
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
    [Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
    Write-Host "Please run this script as Administrator." -ForegroundColor Red
    exit 1
}

# --- Services in START order (stop runs in reverse) ---------------------------
$services = @(
    'W3SVC',                                                            # IIS / AOS
    'DynamicsAxBatch',                                                  # Batch Management Service
    'MR2012ProcessService',                                             # Management Reporter / Financial Reporting
    'Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelperService.exe',  # Data Import/Export Framework
    'SQLServerReportingServices',                                       # SSRS (optional; 'ReportServer' on older VMs)
    'LCSDiagnosticClientService'                                        # LCS diagnostics (optional; may not exist)
)

Import-Module WebAdministration -ErrorAction SilentlyContinue

if ($Action -eq 1) {
    # ============================== START =====================================
    Write-Host "Starting D365 F&O services...`n" -ForegroundColor White

    foreach ($name in $services) {
        $svc = Get-Service -Name $name -ErrorAction SilentlyContinue
        if (-not $svc) {
            Write-Host "[skip]    $name not installed" -ForegroundColor DarkGray
            continue
        }
        if ($svc.StartType -eq 'Disabled') {
            Set-Service -Name $name -StartupType Automatic
            Write-Host "[enable]  $name was Disabled -> set to Automatic" -ForegroundColor Yellow
        }
        if ($svc.Status -ne 'Running') {
            try {
                Start-Service -Name $name -ErrorAction Stop
                Write-Host "[start]   $name" -ForegroundColor Green
            } catch {
                Write-Host "[error]   $name : $($_.Exception.Message)" -ForegroundColor Red
            }
        } else {
            Write-Host "[running] $name" -ForegroundColor Cyan
        }
    }

    # AOS app pool (W3SVC alone doesn't guarantee it)
    if ((Get-WebAppPoolState -Name 'AOSService' -ErrorAction SilentlyContinue).Value -ne 'Started') {
        Start-WebAppPool -Name 'AOSService' -ErrorAction SilentlyContinue
        Write-Host "[start]   AOSService app pool" -ForegroundColor Green
    } else {
        Write-Host "[running] AOSService app pool" -ForegroundColor Cyan
    }
}
else {
    # ============================== STOP ======================================
    Write-Host "Stopping D365 F&O services...`n" -ForegroundColor White

    # Stop the AOS app pool first
    if ((Get-WebAppPoolState -Name 'AOSService' -ErrorAction SilentlyContinue).Value -eq 'Started') {
        Stop-WebAppPool -Name 'AOSService' -ErrorAction SilentlyContinue
        Write-Host "[stop]    AOSService app pool" -ForegroundColor Yellow
    } else {
        Write-Host "[stopped] AOSService app pool" -ForegroundColor DarkGray
    }

    # Stop services in reverse order (IIS last)
    $stopOrder = $services.Clone()
    [array]::Reverse($stopOrder)

    foreach ($name in $stopOrder) {
        $svc = Get-Service -Name $name -ErrorAction SilentlyContinue
        if (-not $svc) {
            Write-Host "[skip]    $name not installed" -ForegroundColor DarkGray
            continue
        }
        if ($svc.Status -ne 'Stopped') {
            try {
                Stop-Service -Name $name -Force -ErrorAction Stop
                Write-Host "[stop]    $name" -ForegroundColor Yellow
            } catch {
                Write-Host "[error]   $name : $($_.Exception.Message)" -ForegroundColor Red
            }
        } else {
            Write-Host "[stopped] $name" -ForegroundColor DarkGray
        }
    }
}

# --- Final status --------------------------------------------------------------
Write-Host "`nFinal status:"
Get-Service -Name $services -ErrorAction SilentlyContinue |
    Select-Object Name, Status, StartType |
    Format-Table -AutoSize

How the script works

  • Safe default. [ValidateSet(0, 1)] accepts only 0 or 1, and no argument means stop.
  • Admin check. It exits with a clear message if PowerShell is not elevated.
  • Correct order. It starts IIS first and stops it last. When stopping, it takes the AOSService app pool down first so no new requests reach the AOS.
  • No hard failures. Missing services show [skip], and a service that fails shows [error] while the rest still run.
Note: on start, any Disabled service is switched to Automatic permanently. If you disabled a service on purpose to save memory, remove it from the list.

How to run it

Open PowerShell as Administrator and run:

cd C:\Scripts
.\D365-Services.ps1      # stop all D365 F&O services (default)
.\D365-Services.ps1 0    # stop all
.\D365-Services.ps1 1    # start all

Typical flow for a database restore or package deployment: run with 0, do the restore or deploy, run with 1, then do a full database sync.

Quick tips

  • Script blocked? Run Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass first.
  • SSRS shows [skip]? Older VMs name it ReportServer. Change the name in the list.
  • Batch stuck in Stopping? A batch task is still running. Wait, or end Batch.exe in Task Manager.
  • Want it automatic? Add the script to Windows Task Scheduler with argument 0 in the evening and 1 in the morning.
  • Tier-1 only. Sandbox and production environments are Microsoft-managed, so use this on dev VMs only.
  • Prefer a module? d365fo.tools offers Stop-D365Environment and Start-D365Environment (PowerShell Gallery). This script needs no install and also covers SSRS.

Conclusion

One command now starts or stops every D365 F&O service on your dev VM: .\D365-Services.ps1 1 to start and .\D365-Services.ps1 0 to stop. If this saved you a few clicks, share it with your D365 F&O team, and leave a comment if your VM uses a service name the script misses.

References

Comments

Popular posts from this blog

SSRS Report error "The parameter panel layout for this report contains more parameters than total cells available D365" Finance and Operation

Simplifying the Connection of Your Dev VM to Tier 2 Environment in D365D

Mastering Container Functions in X++: A Developer's Guide