Automate SCOM 2016 installation with PowerShell

This blog post demonstrates how to automate installation of SCOM 2016 and its requirements using PowerShell. If you’d like, you can also use it partly to install just software prerequisites or service accounts.

My demo lab is configured in the following way:

  • SCOM Server –  VM with up to 8Gb RAM, 4vCPU, Windows Server 2016
  • SCOM VMs has an Internet Connection (to get Report Viewer/Runtime)
  • SQL Server – VM with up to 4Gb RAM. Windows Server 2016
  • Database Services, Full Text and Reporting Services – Native were installed on the SQL Server VM.
  • These machines are also joined to the same domain
  • SCOM media copied to the <systemdrive>\SCOM2016
  • I checked the script using my domain administrator account
  • Download link is available at the bottom
What does the script do?
  • Downloads and installs Report Viewer Controls and required Runtime
New-Item $env:systemdrive\SCOM2016Reqs -ItemType Directory
Invoke-WebRequest -OutFile $env:systemdrive\SCOM2016Reqs\ReportViewer.msi
Invoke-WebRequest -OutFile $env:systemdrive\SCOM2016Reqs\SQLSysClrTypes.msi
Start-Process "$env:systemdrive\SCOM2016Reqs\SQLSysClrTypes.msi" /qn -Wait
Start-Process "$env:systemdrive\SCOM2016Reqs\ReportViewer.msi" /quiet -Wait
Write-Host "The Report Viewer Controls and Runtime have been installed" -ForegroundColor DarkCyan
  • Creates required service accounts, SCOM administrator group in the specified OU and configures required permissions (local admin rights for the SCOM admin group)
Install-WindowsFeature RSAT-AD-PowerShell
New-AdUser SCOM-AccessAccount -SamAccountName scom.aa -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
New-AdUser SCOM-DataWareHouse-Reader -SamAccountName scom.dwr -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
New-AdUser SCOM-DataWareHouse-Write -SamAccountName scom.dww -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
New-AdUser SCOM-Server-Action -SamAccountName -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
New-AdGroup -Name SCOM-Admins -GroupScope Global -GroupCategory Security -Path "OU=$ouname,$adcn"
Add-AdGroupMember SCOM-Admins scom.aa,scom.dwr,scom.dww,
Add-LocalGroupMember -Member $dname\SCOM-Admins -Group Administrators
#SQL Server service accounts (SQLSSRS is a service reporting services account)
New-AdUser SQLSVC -SamAccountName sqlsvc -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
New-AdUser SQLSSRS -SamAccountName sqlssrs -AccountPassword (ConvertTo-SecureString -AsPlainText $svcpass -Force) -PasswordNeverExpires $true -Enabled $true -Path "OU=$ouname,$adcn"
Write-Host "The service Accounts and SCOM-Admins group have been added to OU=$ouname,$adcn" -ForegroundColor DarkCyan

  • Configures SQL Server by creating required Windows Firewall rules and adding SCOM-Admins group to the administrators on the server
$secpasswd = ConvertTo-SecureString $sqlpass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("$dname\$sqluser", $secpasswd)
$psrem = New-PSSession -ComputerName $sqlsrv -Credential $cred
Invoke-Command -Session $psrem -ScriptBlock{
Install-WindowsFeature RSAT-AD-Powershell
Set-NetFirewallRule -Name WMI-WINMGMT-In-TCP -Enabled True
New-NetFirewallRule -Name "SQL DB" -DisplayName "SQL Database" -Profile Domain -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL Server Admin Connection" -DisplayName "SQL Admin Connection" -Profile Domain -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL Browser" -DisplayName "SQL Browser" -Profile Domain -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow
New-NetFirewallRule -Name "SQL SRRS (HTTP)" -DisplayName "SQL SRRS (HTTP)" -Profile Domain -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL SRRS (SSL)" -DisplayName "SQL SRRS (SSL)" -Profile Domain -Direction Inbound -LocalPort 443 -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL Instance Custom Port" -DisplayName "SQL Instance Custom Port" -Profile Domain -Direction Inbound -LocalPort $sqlserverport -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL Server 445" -DisplayName "SQL Server 445" -Profile Domain -Direction Inbound -LocalPort 445 -Protocol TCP -Action Allow
New-NetFirewallRule -Name "SQL Server 135" -DisplayName "SQL Server 135" -Profile Domain -Direction Inbound -LocalPort 135 -Protocol TCP -Action Allow
Add-LocalGroupMember -Member $arg[0]\SCOM-Admins -Group Administrators} -ArgumentList $dname
Write-Host "The SQL Server $sqlsrv has been configured" -ForegroundColor DarkCyan
  • Installs Web Console prerequisites (ISS and so on)
Install-WindowsFeature NET-WCF-HTTP-Activation45,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors, `
Write-Host "The Web Console prerequisites have been installed" -ForegroundColor DarkCyan
  • Installs the SCOM Server (OMServer, OMConsole and OMWebConsole).
$arglist= @("/install /components:OMServer,OMConsole,OMWebConsole /ManagementGroupName:$mgmtgroup /SqlServerInstance:$sqlsrv\$sqlinstancename /SqlInstancePort:$sqlserverport",
"/DatabaseName:OperationsManager /DWSqlServerInstance:$sqlsrv\$sqlinstancename /DWDatabaseName:OperationsManagerDW /ActionAccountUser:$dname\",
"/ActionAccountPassword:$svcpass /DASAccountUser:$dname\scom.aa /DASAccountPassword:$svcpass /DataReaderUser:$dname\scom.dwr",
"/DataReaderPassword:$svcpass /DataWriterUser:$dname\scom.dww /DataWriterPassword:$svcpass /WebSiteName:""Default Web Site""",
'/WebConsoleAuthorizationMode:Mixed /EnableErrorReporting:Always /SendCEIPReports:1 /UseMicrosoftUpdate:1 /AcceptEndUserLicenseAgreement:1 /silent')
Start-Process -FilePath $env:systemdrive\SCOM2016\setup.exe -ArgumentList $arglist -Wait
Write-Host "The SCOM has been installed. Don't forget to license SCOM" -ForegroundColor DarkCyan
  • Once SCOM is installed, verify installation logs located at  <username>\AppData\Local\SCOM\LOGS\OpsMgrSetupWizard.txt .
    Additionally, don’t forget to set a valid SCOM 2016 product key by using the  Set-SCOMLicense –ProductId <key>


That’s it. Just run the script, provide values for SQL Server connection/credentials and etc and wait until the SCOM installation is complete.

I uploaded the script, so feel free to use it (please mention my blog once you shared the script or part of it. Let’s respect each other!)


Deploying VMFleet to test S2D performance

VMfleet is a storage load generator to stress your S2D. Actually it burns your disks/cpu/storage network to check whether S2D is stable or not. VMFleet is also used to get performance results of S2D storage subsystem.

To get started, you need to do the following:

  1. Download VMFleet located at , click on Clone/Download and then extract archive to the folder named C:\VMFleet, for example.

  2. Download DiskSpd tool from and extract to C:\diskspd

  3. Prepare gold image of Windows Server 2016 Core. After OS installation, provide admin credentials and shutdown the VM. Sysprep is not required.

  4. Prepare VMFleet :

#Create new virtual disks for VMFleet by running this command:

Get-ClusterNode |% { New-Volume -StoragePoolFriendlyName S2D* -FriendlyName $_ -FileSystem CSVFS_ReFS -Size 1Tb }

#Create new volume for VMFleet files with friendly name Collect:

New-Volume -StoragePoolFriendlyName S2D* -FriendlyName Collect -FileSystem CSVFS_ReFS -Size 500GB

#Install VMFleet by running the following one-liner:

.\install-vmfleet.ps1 -Source C:\VMFleet\diskspd-master\diskspd-master\Frameworks\VMFleet

#Copy the DISKSPD.exe to the Tools folder:

 Copy-Item c:\diskspd\diskspd.exe -Destination c:\clusterstorage\collect\control\tools

#Copy gold image (VHDX) with Windows Server 2016 Core (not sysprepped) to the Collect folder:

 Copy-Item C:\ClusterStorage\Volume03_test\VMFleet-Gold\VMFleet-Gold_disk_1.vhdx `
 -Destination C:\ClusterStorage\Collect

# Run update-csv.ps1 script to manage the placement of CSV volumes and VMs per a naming convention.
# This script also changes ownership of test CSV volumes if required.

.\update-csv.ps1 -renamecsvmounts $true

# Start creating VMs for VMfleet environment.
# In the following example, 15 VMs will be created on each host,
# adminpass represents my local administrator password used in the gold image
#  connectuser and connectpass are credentials with cluster management rights:

.\create-vmfleet.ps1 -basevhd 'C:\ClusterStorage\Collect\VMFleet-Gold_disk_1.vhdx'-vms 15 `
-adminpass 'Pass123' -connectuser 'rllab\rlevchenko' -connectpass '''RTM$nRdT@5J5'''

#Once VMs are created, change their configuration if required:

.\set-vmfleet.ps1 -ProcessorCount 2 -MemoryStartupBytes 4GB `
-MemoryMinimumBytes 4GB -MemoryMaximumBytes 4GB

At this step, you are ready to start VMFleet VMs and then check system’s status:

#To start VMs

#To check cluster health

#To get the current status of cluster

To run stress test, execute start-sweep.ps1 script that uses the following parameters for diskspd.exe:

  • b: list of buffer sizes (KiB)
  • t: list of thread counts
  • o: list of outstanding IO counts
  • w: list of write ratios
  • p: list of patterns (random: r, sequential: s, sequential interlocked: si)
  • warm: duration of pre-measurement warmup (seconds)
  • d: duration of measured interval (seconds)
  • cool: duration of post-measurement cooldown (seconds)

In the following example, I run 100% read test with 20 outstanding IOs and 8 threads, duration is set to 60 seconds excluding default 120 seconds for cooldown and warmup.

.\Start-Sweep.ps1 -b 4 -t 8 -o 20 -w 0 -d 60

To get the live test results, use then watch-cluster.ps1:


To stop VMFleet VMs after testing:

.\stop-vmfleet.ps1 -method Shutdown

To destroy VMFleet (CAUTION! This script stops and removes all clustered VMs) :