This post will cover how to run the SCOM or OperationsManager module from a windows container, make sure to install just the SCOM Admin Console and Powershell modules from the ISO’s installer on a donor server so we can grab the files needed.

In my previous post I show how to build containers for AzureDevops agents, sometimes we end up with powershell dependencies which are not available from PowershellGalary.

To install the Powershell OperationsManager module, Microsoft bundles it with the Console which when you try to to install on a container reports an error due to the lack of GUI.

Below will cover which .dlls’s are required, the folder structure that needs to be created within the container.

An easy way to check which dependencies is to run the following command before and after the module has been registered.

[AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object { $_.Location }

Before

Then we run Import-Module OperationsManager to check which .dll’s are loaded after the module is imported and run [AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object { $_.Location } again.

After

Copy all the folder below into a folder as we will zip up the contents into a file called SCOM.zip, ensure to keep the same folder structure from \System Center Operations Manager\ as we will need to extract these into the container as part of the dockerfile image build process.

C:\Program Files\System Center Operations Manager

So now create a file called RegisterDlls.ps1 and copying the contents below into it, this file will again be used within the dockerfile to build the image with the OperationsManager modules.

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -force

#Update PSModulePath
$CurrentValue = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
[Environment]::SetEnvironmentVariable("PSModulePath", $CurrentValue + ";C:\Program Files\System Center Operations Manager\Powershell", "Machine")

# Register DLL's
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object System.EnterpriseServices.Internal.Publish
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Server\SDK Binaries\Microsoft.EnterpriseManagement.Core.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Server\SDK Binaries\Microsoft.EnterpriseManagement.OperationsManager.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Server\SDK Binaries\Microsoft.EnterpriseManagement.Runtime.dll") 
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\OperationsManager\OM10.Commands\Microsoft.SystemCenter.OperationsManagerV10.Commands.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\OperationsManager\OM10.CoreCommands\Microsoft.EnterpriseManagement.Core.Cmdlets.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\OperationsManager\OM10.CoreCommands\Microsoft.EnterpriseManagement.SqmBase.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\OperationsManager\OM10.CrossPlatform\Microsoft.SystemCenter.CrossPlatform.PowerShell.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\EN\Microsoft.EnterpriseManagement.Core.Cmdlets.resources.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\EN\Microsoft.SystemCenter.OperationsManagerV10.Commands.resources.dll")
$publish.GacInstall("C:\Program Files\System Center Operations Manager\Powershell\OperationsManager\OM10.CrossPlatform\Microsoft.SystemCenter.CrossPlatform.ClientLibrary.ClientTasks.dll")

So now that you have the files and have the zip ready, add the following lines into the dockerfile.

#Install SCOM module into container
COPY SCOM.zip .
RUN powershell "Expand-Archive -Path SCOM.zip -DestinationPath 'C:\Program Files\'"

Now lets copy and add the lines to run the RegisterDlls.ps1 in the container, add the following lines into the dockerfile.

#Register dependencies for SCOM in container
COPY RegisterDlls.ps1 .
RUN powershell .\RegisterDlls.ps1

Now we add the lines below to clean up the SCOM.zip and RegisterDlls.ps1 files which are no longer needed in the container (save space and keep the image lean and clean)

#Cleanup
RUN powershell "Remove-Item SCOM.zip"
RUN powershell "Remove-Item RegisterDlls.ps1"

So in the end your dockerfile should look something like this

FROM mcr.microsoft.com/windows/servercore:ltsc2022
WORKDIR /azp

#Disable UAC
RUN powershell "Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0"

#Install SCOM module into container
COPY SCOM.zip .
RUN powershell "Expand-Archive -Path SCOM.zip -DestinationPath 'C:\Program Files\'"

#Register dependencies for SCOM in container
COPY RegisterDlls.ps1 .
RUN powershell .\RegisterDlls.ps1

#Cleanup
RUN powershell "Remove-Item SCOM.zip"
RUN powershell "Remove-Item RegisterDlls.ps1"

#Enable UAC
RUN powershell "Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 1"

#Run the Script on Container Start
COPY RunAgent.ps1 .
CMD powershell .\RunAgent.ps1

Now just run the docker image build command, sit back and drink your coffee as you are now one very smug cookie.

Hope it was helpful

vMan