This post will cover how to run the System Center Configuration Manager (SCCM) or ConfigurationManager module from a windows container.

Just like my previous post for SCOM, ConfigurationManager is not available from PowershellGalary and requires an install from the GUI. Make sure to install just the SCCM Admin Console and Powershell modules from the ISO’s installer on a donor server so we can grab the files needed.

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

Lets start off by checking the dependencies by running following command before and after the module has been registered.

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

Before

Now lets run Import-Module ConfigurationManager to and then [AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object { $_.Location } again.

Below shows all the additional modules were enabled.

After

Copy all the files identified above into a folder as we will zip up the contents into a file called SCCM.zip, ensure to keep the same folder structure from \Microsoft Endpoint Manager\ as we will need to extract these into the container as part of the dockerfile image build process.

You will also need to copy these files into the Zip

C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.PS.psm1
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\ConfigurationManager\ConfigurationManager.psd1
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.PS.psm1
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\CalTracking.format.ps1xml
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\CalTracking.Types.ps1xml
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.PowerShell.Provider.format.ps1xml
C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.PowerShell.Types.ps1xml

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 ConfigurationManager modules.

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -force

#Update PSModulePath
$CurrentValue = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
[Environment]::SetEnvironmentVariable("PSModulePath", $CurrentValue + ";C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin", "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 (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.Application.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.AutoDeployment.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.AzureServices.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.BitlockerManagement.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.ClientAgentSettings.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.CloudServicesManagement.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.CollectionProperty.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.Common.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.Controls.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.CreateDT.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.FeaturesUtilities.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.MigrationAssistant.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.OsdCommon.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.PS.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.Scripts.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.SoftwareUpdateManagementPoint.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.WqlInitializer.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\AdminUI.WqlQueryEngine.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\DcmObjectModel.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.AppV5xInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.AppVInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.MacInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.MobileMsiInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.MsiInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.TaskSequenceInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.WebAppInstaller.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.Win8Installer.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ApplicationManagement.WinPhone8Installer.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.ManagementProvider.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.Migration.ConfigMgr2012.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.Migration.ObjectSerialization.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManagement.NotificationCommon.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManager.CloudBase.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.ConfigurationManager.PhasedDeploymentModel.dll")
$publish.GacInstall("C:\Program Files (x86)\Microsoft Endpoint Manager\AdminConsole\bin\Microsoft.Diagnostics.Tracing.EventSource.dll")

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

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

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 SCCM in container
COPY RegisterDlls.ps1 .
RUN powershell .\RegisterDlls.ps1

Now we add the lines below to clean up the SCCM.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 SCCM.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 SCCM module into container
COPY SCCM.zip .
RUN powershell "Expand-Archive -Path SCCM.zip -DestinationPath 'C:\Program Files (x86)\'"

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

#Cleanup
RUN powershell "Remove-Item SCCM.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 relax!

Hope it was helpful

vMan