<br />
<b>Warning</b>:  strpos() expects parameter 1 to be string, array given in <b>/home/theserverside/public_html/wp-includes/blocks.php</b> on line <b>20</b><br />
{"id":1426,"date":"2019-11-02T15:48:29","date_gmt":"2019-11-02T15:48:29","guid":{"rendered":"https:\/\/www.theserverside.technology\/?p=1426"},"modified":"2019-11-07T22:00:42","modified_gmt":"2019-11-07T22:00:42","slug":"","status":"publish","type":"post","link":"https:\/\/www.theserverside.technology\/it\/2019\/11\/02\/how-to-containerize-windows-admin-center\/","title":{"rendered":"How to containerize Windows Admin Center","raw":"How to containerize Windows Admin Center"},"content":{"rendered":"\n<p class=\"has-drop-cap\">Microsoft is investing a lot into its new <em>Server Manager<\/em> though Redmond is not encouraging that parallelism and often says that Windows Admin Center is not a 1-to-1 replacement for Server Manager. That is true because Server Manager and its underlying technology has a deeper connection with the operating system and it can be considered a <em>platform<\/em> while Winows Admin Center can be considered a very sophisticated shell that mostly works through WMI\/Powershell connections.<\/p>\n\n\n\n<p>However, Windows Admin Center is gaining a lot of traction and it&#8217;s quickly gaining support because its Web UI allows to embed important tasks into simple to access and to use widgets called tools and access them through a simple browser. Productivity is enhanced especially when used with the Core version of Windows operating systems and I&#8217;m not surprised that Microsoft <a rel=\"noreferrer noopener\" aria-label=\"is experiencing a growth in adoption for the Core SKUs (opens in a new tab)\" href=\"https:\/\/cloudblogs.microsoft.com\/windowsserver\/2019\/10\/03\/windows-admin-center-unleashes-server-core-adoption\/\" target=\"_blank\">is experiencing a growth in adoption for the Core SKUs<\/a> because of it.<\/p>\n\n\n\n<h3>Why containerizing Windows Admin Center ?<\/h3>\n\n\n\n<p>So the first question would be: why would someone want to containerize Windows Admin Center ? First, a containerized WAC would be very easy to deploy on multiple systems in a very straightforward way. Furthermore, multiple copies of WAC, possibly in use by different teams, could be deployed and used thanks to the isolation provided by containers and their flexibility. Containers could be also useful to mitigate any security issue that could arise even if Windows Admin Center showed no security vulnerabilities as far as I know. Finally, by using Hyper-V isolation multiple instances of WAC could be isolated and provided to multiple tenants.<\/p>\n\n\n\n<h3>Prepare the environment<\/h3>\n\n\n\n<p>To deploy WAC into a container we will use Windows Server 2019. We must first enable containers support by selecting and adding the feature in Roles&amp;Features section of Server Manager:<\/p>\n\n\n\n<p>Then we must <a rel=\"noreferrer noopener\" aria-label=\"install Docker as per Microsoft Docs (opens in a new tab)\" href=\"https:\/\/docs.microsoft.com\/en-us\/virtualization\/windowscontainers\/deploy-containers\/deploy-containers-on-server\" target=\"_blank\">install Docker as per Microsoft Docs<\/a> : <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Module -Name DockerMsftProvider -Repository PSGallery -Force<\/pre>\n\n\n\n<p>and then<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Package -Name docker -ProviderName DockerMsftProvider<\/pre>\n\n\n\n<p>and finally restore Windows Server 2019 to complete installation<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Restart-Computer -Force<\/pre>\n\n\n\n<p>When server restarts we can pull the Windows Server 2019 Core image that we will use to run Windows Admin Center. Note that WAC doesn&#8217;t need IIS because it will self-host so downloading the base OS image will be enough<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker pull mcr.microsoft.com\/windows\/servercore:ltsc2019<\/pre>\n\n\n\n<p>After downloading the image we are now ready to spin our new container and install <em>Windows Admin Center<\/em>.<\/p>\n\n\n\n<h3>Create the WAC container <\/h3>\n\n\n\n<p>We have a choice to make before creating the container for WAC and that is the port we want to expose WAC onto. That would be the port we connect to in order to use WAC. To make our life easier now, we will expose this port to the host but more sophisticated deployments might be appropriate depending on what you&#8217;re trying to achieve. We need to decide that first because we will then need this information when installing Windows Admin Center. We will make it available on port 8443.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker run -it -p 8443:8443 mcr.microsoft.com\/windows\/servercore:ltsc2019 cmd.exe<\/pre>\n\n\n\n<p>If everything goes well you will have CMD prompt ready after starting the container. Now we need to copy the installation files into the container. You probably downloaded the WAC MSI from Microsoft website: please place that file inside the <em>c:\\<\/em> folder on the host. Get the Docker container ID by opening another command prompt and issuing a &#8220;docker ps&#8221; command:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"2\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CONTAINER ID        IMAGE                                           COMMAND             CREATED             STATUS              PORTS                    NAMES\n9a4bb5975ee8        mcr.microsoft.com\/windows\/servercore:ltsc2019   \"cmd.exe\"           10 minutes ago      Up 11 seconds       0.0.0.0:8443->8443\/tcp   hardcore_bouman\n<\/pre>\n\n\n\n<p>Container ID in my case is <em>9a4bb5975ee8.<\/em> Now you can copy the WAC MSI file into the container. Note that if you created an Hyper-V instance (which is not our case) you will need to stop container before you can copy files into it but in our case we used process isolation so we can issue a command file this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp WindowsAdminCenter1910-RC4.msi 9a4bb5975ee8:c:\\<\/pre>\n\n\n\n<p>Now we should be able to type a simple &#8220;dir&#8221; inside the container to display available files:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Microsoft Windows [Version 10.0.17763.805]\n(c) 2018 Microsoft Corporation. All rights reserved.\n\nC:\\>dir\n Volume in drive C has no label.\n Volume Serial Number is 4E9D-71E0\n\n Directory of C:\\\n\n09\/15\/2018  10:42 AM             5,510 License.txt\n10\/06\/2019  11:04 AM    &lt;DIR>          Program Files\n10\/06\/2019  11:02 AM    &lt;DIR>          Program Files (x86)\n10\/06\/2019  11:05 AM    &lt;DIR>          Users\n11\/02\/2019  06:21 PM    &lt;DIR>          Windows\n10\/28\/2019  08:55 PM        62,529,536 WindowsAdminCenter1910-RC4.msi\n               2 File(s)     62,535,046 bytes\n               4 Dir(s)  21,033,639,936 bytes free\n<\/pre>\n\n\n\n<p>In my case, file is for 1910 RC4 of Windows Admin Center but obiviously the name depends on what you downloaded. You can now issue a &#8220;exit&#8221; command and end container since we will need to perform other tasks before we can actually install.<\/p>\n\n\n\n<h3>Installation errors<\/h3>\n\n\n\n<p>What we should do now is starting a unattended installation for Windows Admin Center, which is pretty straightforward. However installation will fail because of the installer will attempt to change settings for firewall and CredSSP and that is probably not allowed in a container thus we need to transform the MSI installer to skip such actions.<\/p>\n\n\n\n<p>Orca comes at the rescue! If you don&#8217;t know it, Orca is a tool by which you can generate <em>transformations<\/em> for the installer, that is changes to the installation process. There&#8217;s a lot of things that you can change and I&#8217;ll leave any experiment to the reader but what we are looking for it configuring <em>msiexec<\/em> to skip some custom actions. <\/p>\n\n\n\n<p>First of all, download Orca and install it. You can easily download it from somewhere on the Web. After installation open Orca and open the MSI installer for Windows Admin Center: it will list all those settings that you could change. After the MSI settings load up, select <em>Trasform<\/em> menu and click on <em>New transform<\/em>, then look for <em>Custom action<\/em> on the list on the left and look for the actions listed below. Right click + &#8220;Drop row&#8221; to disable them.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" width=\"1024\" height=\"617\" src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1024x617.jpg\" alt=\"\" class=\"wp-image-1468\" srcset=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1024x617.jpg 1024w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-300x181.jpg 300w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-768x463.jpg 768w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-16x10.jpg 16w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-32x19.jpg 32w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-28x17.jpg 28w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-56x34.jpg 56w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-64x39.jpg 64w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1000x603.jpg 1000w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1200x723.jpg 1200w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01.jpg 2024w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Disable custom actions to update firewall<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" width=\"1024\" height=\"617\" src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1024x617.jpg\" alt=\"\" class=\"wp-image-1470\" srcset=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1024x617.jpg 1024w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-300x181.jpg 300w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-768x463.jpg 768w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-16x10.jpg 16w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-32x19.jpg 32w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-28x17.jpg 28w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-56x34.jpg 56w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-64x39.jpg 64w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1000x603.jpg 1000w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1200x723.jpg 1200w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02.jpg 2024w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Yet more actions to disable for firewall<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" width=\"1024\" height=\"617\" src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1024x617.jpg\" alt=\"\" class=\"wp-image-1472\" srcset=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1024x617.jpg 1024w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-300x181.jpg 300w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-768x463.jpg 768w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-16x10.jpg 16w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-32x19.jpg 32w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-28x17.jpg 28w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-56x34.jpg 56w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-64x39.jpg 64w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1000x603.jpg 1000w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1200x723.jpg 1200w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03.jpg 2024w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>We also need to disable actions for CredSSP settings<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" width=\"1024\" height=\"617\" src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1024x617.jpg\" alt=\"\" class=\"wp-image-1474\" srcset=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1024x617.jpg 1024w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-300x181.jpg 300w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-768x463.jpg 768w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-16x10.jpg 16w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-32x19.jpg 32w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-28x17.jpg 28w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-56x34.jpg 56w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-64x39.jpg 64w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1000x603.jpg 1000w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1200x723.jpg 1200w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04.jpg 2024w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>And yet more things related to firewall<\/figcaption><\/figure><\/div>\n\n\n\n<p>After you do this, click on <em>Tranform<\/em> menu and select <em>Generate transform<\/em> to create a new MST file that contains our transformations. Name it &#8220;<em>WAC-NoFirewall-CredSSP.mst<\/em>&#8220;. Time to go back to our container&#8230;<\/p>\n\n\n\n<p><strong>P.S.<\/strong> Remember that transformation files are only valid for the file they are generated from. If you change your MSI source file, you will need to regenerate your transformations.<\/p>\n\n\n\n<h3>Windows Admin Center installation<\/h3>\n\n\n\n<p>Ok, so we are ready. Back to the host restart your container by issuing<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker start 9a4bb5975ee8<\/pre>\n\n\n\n<p>As you probably remember, <em>9a4bb5975ee8<\/em> is my container ID. Now we have to copy our MST file inside our container<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp c:\\WAC-NoFirewall-CredSSP.mst 9a4bb5975ee8:C:\\<\/pre>\n\n\n\n<p>When done we have both our WAC MSI file and our transformation file MST inside the root of our container so it&#8217;s time to install. On your host issue a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker attach 9a4bb5975ee8<\/pre>\n\n\n\n<p>to connect to container console. Ensure that you are inside the C:\\ path and issue<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msiexec \/i WindowsAdminCenter1910-RC4.msi \/qn \/L*v log.txt SME_PORT=8443 SSL_CERTIFICATE_OPTION=generate \/TRANSFORMS=WAC-NoFirewall-CredSSP.mst<\/pre>\n\n\n\n<p>Ensure that the MSI filename is set to the one that you are actually using. Pay attention to the <em>SME_PORT<\/em> parameter: this must be set to the same port you opened in your container or you won&#8217;t be able to connect to Windows Admin Center. We are also generating a self-signed SSL certificated by this command and, most important, we ask <em>msiexec<\/em> to use our <em>WAC-NoFirewall-CredSSP.MST<\/em> file as a tranformation. A log of the installation will be stored inside <em>log.txt<\/em>.<\/p>\n\n\n\n<p>If everything goes well you will read inside <em>log.txt <\/em>that WAC has been installed successfully.<\/p>\n\n\n\n<h3> Connecting to Windows Admin Center<\/h3>\n\n\n\n<p>Now that Windows Admin Center has been installed, you can open your browser on your host OS and browse to <em>https:\/\/localhost:8443<\/em>, ignore that self-signed certificate we generated and&#8230; you won&#8217;t be able to connect to WAC ! \ud83d\ude04<\/p>\n\n\n\n<p>The reason for that is that you need to login using credentials for an administrator user but you don&#8217;t actually know the password for <em>ContainerAdministrator<\/em> user that is part of the container and your Administrator password won&#8217;t work inside your container. So go back to the console, attach container using &#8220;docker attach&#8221; if needed and issue the following commands<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">net user MyAdmin Pa$$w0rd! \/add\nnet localgroup administrators MyAdmin \/add<\/pre>\n\n\n\n<p>What you&#8217;re doing is adding a new <em>MyAdmin<\/em> user using <em>Pa$$w0rd!<\/em> as his password and add him to the <em>Administrators<\/em> group. That user won&#8217;t be part of the hosting OS and it will only exist in that specific container. Now you can connect back to Windows Admin Center and type <em>MyAdmin<\/em> \/ <em>Pa$$w0rd!<\/em> as your credentials.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" width=\"1024\" height=\"808\" src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1024x808.jpg\" alt=\"\" class=\"wp-image-1484\" srcset=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1024x808.jpg 1024w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-300x237.jpg 300w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-768x606.jpg 768w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-16x13.jpg 16w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-32x25.jpg 32w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-28x22.jpg 28w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-56x44.jpg 56w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-64x50.jpg 64w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1000x789.jpg 1000w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1200x947.jpg 1200w, https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05.jpg 1639w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Windows Admin Center running inside a container<\/figcaption><\/figure><\/div>\n\n\n\n<p>Note that your gateway will be displaied as the container ID (<em>899aa7b9d38f<\/em>, in that image) and your current user will be displaied as as <em>[containerid]\\MyAdmin<\/em> (<em>899aa7b9d38f\\testadmin<\/em> in that image).<\/p>\n\n\n\n<h3>Errors and limitations <\/h3>\n\n\n\n<p>There are a few quirks or limitations that you will face when working with Windows Admin Center installed inside a container. I wasn&#8217;t able to make Powershell tool to work fine when connecting to remote servers. Not sure what the problem is and I&#8217;m working with Microsoft to understand if this can be fixed. Other tools seem to work fine though I didn&#8217;t test them all.<\/p>\n\n\n\n<p> This is by far the worst problem and I hope we can fix it. Then you have some tools not working when trying to connect back to container itself, that is the <em>gateway<\/em> in WAC terms. If you run a process-isolated container, you will be able administer it by using Windows Admin Center even if some tools won&#8217;t work: Powershell, files, firewall and so on. That is somewhat expected and not a real limitation. If you run Hyper-V-isolated container, you won&#8217;t be able to connect back to gateway, which as I said it is not a problem at all since you basically don&#8217;t need to manage your gateway.<\/p>\n\n\n\n<p>If there&#8217;s a way for Powershell tool to work, deploying into containers could be a very handy option in many scenarios.<\/p>\n","protected":false,"raw":"<!-- wp:paragraph {\"dropCap\":true} -->\n<p class=\"has-drop-cap\">Microsoft is investing a lot into its new <em>Server Manager<\/em> though Redmond is not encouraging that parallelism and often says that Windows Admin Center is not a 1-to-1 replacement for Server Manager. That is true because Server Manager and its underlying technology has a deeper connection with the operating system and it can be considered a <em>platform<\/em> while Winows Admin Center can be considered a very sophisticated shell that mostly works through WMI\/Powershell connections.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>However, Windows Admin Center is gaining a lot of traction and it's quickly gaining support because its Web UI allows to embed important tasks into simple to access and to use widgets called tools and access them through a simple browser. Productivity is enhanced especially when used with the Core version of Windows operating systems and I'm not surprised that Microsoft <a rel=\"noreferrer noopener\" aria-label=\"is experiencing a growth in adoption for the Core SKUs (opens in a new tab)\" href=\"https:\/\/cloudblogs.microsoft.com\/windowsserver\/2019\/10\/03\/windows-admin-center-unleashes-server-core-adoption\/\" target=\"_blank\">is experiencing a growth in adoption for the Core SKUs<\/a> because of it.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Why containerizing Windows Admin Center ?<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>So the first question would be: why would someone want to containerize Windows Admin Center ? First, a containerized WAC would be very easy to deploy on multiple systems in a very straightforward way. Furthermore, multiple copies of WAC, possibly in use by different teams, could be deployed and used thanks to the isolation provided by containers and their flexibility. Containers could be also useful to mitigate any security issue that could arise even if Windows Admin Center showed no security vulnerabilities as far as I know. Finally, by using Hyper-V isolation multiple instances of WAC could be isolated and provided to multiple tenants.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Prepare the environment<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>To deploy WAC into a container we will use Windows Server 2019. We must first enable containers support by selecting and adding the feature in Roles&amp;Features section of Server Manager:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Then we must <a rel=\"noreferrer noopener\" aria-label=\"install Docker as per Microsoft Docs (opens in a new tab)\" href=\"https:\/\/docs.microsoft.com\/en-us\/virtualization\/windowscontainers\/deploy-containers\/deploy-containers-on-server\" target=\"_blank\">install Docker as per Microsoft Docs<\/a> : <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Module -Name DockerMsftProvider -Repository PSGallery -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and then<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Package -Name docker -ProviderName DockerMsftProvider<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and finally restore Windows Server 2019 to complete installation<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Restart-Computer -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When server restarts we can pull the Windows Server 2019 Core image that we will use to run Windows Admin Center. Note that WAC doesn't need IIS because it will self-host so downloading the base OS image will be enough<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker pull mcr.microsoft.com\/windows\/servercore:ltsc2019<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>After downloading the image we are now ready to spin our new container and install <em>Windows Admin Center<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Create the WAC container <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>We have a choice to make before creating the container for WAC and that is the port we want to expose WAC onto. That would be the port we connect to in order to use WAC. To make our life easier now, we will expose this port to the host but more sophisticated deployments might be appropriate depending on what you're trying to achieve. We need to decide that first because we will then need this information when installing Windows Admin Center. We will make it available on port 8443.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker run -it -p 8443:8443 mcr.microsoft.com\/windows\/servercore:ltsc2019 cmd.exe<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will have CMD prompt ready after starting the container. Now we need to copy the installation files into the container. You probably downloaded the WAC MSI from Microsoft website: please place that file inside the <em>c:\\<\/em> folder on the host. Get the Docker container ID by opening another command prompt and issuing a \"docker ps\" command:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"highlight\":\"2\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"2\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CONTAINER ID        IMAGE                                           COMMAND             CREATED             STATUS              PORTS                    NAMES\n9a4bb5975ee8        mcr.microsoft.com\/windows\/servercore:ltsc2019   \"cmd.exe\"           10 minutes ago      Up 11 seconds       0.0.0.0:8443->8443\/tcp   hardcore_bouman\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Container ID in my case is <em>9a4bb5975ee8.<\/em> Now you can copy the WAC MSI file into the container. Note that if you created an Hyper-V instance (which is not our case) you will need to stop container before you can copy files into it but in our case we used process isolation so we can issue a command file this:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp WindowsAdminCenter1910-RC4.msi 9a4bb5975ee8:c:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Now we should be able to type a simple \"dir\" inside the container to display available files:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Microsoft Windows [Version 10.0.17763.805]\n(c) 2018 Microsoft Corporation. All rights reserved.\n\nC:\\>dir\n Volume in drive C has no label.\n Volume Serial Number is 4E9D-71E0\n\n Directory of C:\\\n\n09\/15\/2018  10:42 AM             5,510 License.txt\n10\/06\/2019  11:04 AM    &lt;DIR>          Program Files\n10\/06\/2019  11:02 AM    &lt;DIR>          Program Files (x86)\n10\/06\/2019  11:05 AM    &lt;DIR>          Users\n11\/02\/2019  06:21 PM    &lt;DIR>          Windows\n10\/28\/2019  08:55 PM        62,529,536 WindowsAdminCenter1910-RC4.msi\n               2 File(s)     62,535,046 bytes\n               4 Dir(s)  21,033,639,936 bytes free\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>In my case, file is for 1910 RC4 of Windows Admin Center but obiviously the name depends on what you downloaded. You can now issue a \"exit\" command and end container since we will need to perform other tasks before we can actually install.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Installation errors<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>What we should do now is starting a unattended installation for Windows Admin Center, which is pretty straightforward. However installation will fail because of the installer will attempt to change settings for firewall and CredSSP and that is probably not allowed in a container thus we need to transform the MSI installer to skip such actions.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Orca comes at the rescue! If you don't know it, Orca is a tool by which you can generate <em>transformations<\/em> for the installer, that is changes to the installation process. There's a lot of things that you can change and I'll leave any experiment to the reader but what we are looking for it configuring <em>msiexec<\/em> to skip some custom actions. <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>First of all, download Orca and install it. You can easily download it from somewhere on the Web. After installation open Orca and open the MSI installer for Windows Admin Center: it will list all those settings that you could change. After the MSI settings load up, select <em>Trasform<\/em> menu and click on <em>New transform<\/em>, then look for <em>Custom action<\/em> on the list on the left and look for the actions listed below. Right click + \"Drop row\" to disable them.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1468,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1024x617.jpg\" alt=\"\" class=\"wp-image-1468\"\/><\/a><figcaption>Disable custom actions to update firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1470,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1024x617.jpg\" alt=\"\" class=\"wp-image-1470\"\/><\/a><figcaption>Yet more actions to disable for firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1472,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1024x617.jpg\" alt=\"\" class=\"wp-image-1472\"\/><\/a><figcaption>We also need to disable actions for CredSSP settings<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1474,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1024x617.jpg\" alt=\"\" class=\"wp-image-1474\"\/><\/a><figcaption>And yet more things related to firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>After you do this, click on <em>Tranform<\/em> menu and select <em>Generate transform<\/em> to create a new MST file that contains our transformations. Name it \"<em>WAC-NoFirewall-CredSSP.mst<\/em>\". Time to go back to our container...<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p><strong>P.S.<\/strong> Remember that transformation files are only valid for the file they are generated from. If you change your MSI source file, you will need to regenerate your transformations.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Windows Admin Center installation<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Ok, so we are ready. Back to the host restart your container by issuing<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker start 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>As you probably remember, <em>9a4bb5975ee8<\/em> is my container ID. Now we have to copy our MST file inside our container<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp c:\\WAC-NoFirewall-CredSSP.mst 9a4bb5975ee8:C:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When done we have both our WAC MSI file and our transformation file MST inside the root of our container so it's time to install. On your host issue a<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker attach 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>to connect to container console. Ensure that you are inside the C:\\ path and issue<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msiexec \/i WindowsAdminCenter1910-RC4.msi \/qn \/L*v log.txt SME_PORT=8443 SSL_CERTIFICATE_OPTION=generate \/TRANSFORMS=WAC-NoFirewall-CredSSP.mst<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Ensure that the MSI filename is set to the one that you are actually using. Pay attention to the <em>SME_PORT<\/em> parameter: this must be set to the same port you opened in your container or you won't be able to connect to Windows Admin Center. We are also generating a self-signed SSL certificated by this command and, most important, we ask <em>msiexec<\/em> to use our <em>WAC-NoFirewall-CredSSP.MST<\/em> file as a tranformation. A log of the installation will be stored inside <em>log.txt<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will read inside <em>log.txt <\/em>that WAC has been installed successfully.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3> Connecting to Windows Admin Center<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Now that Windows Admin Center has been installed, you can open your browser on your host OS and browse to <em>https:\/\/localhost:8443<\/em>, ignore that self-signed certificate we generated and... you won't be able to connect to WAC ! \ud83d\ude04<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>The reason for that is that you need to login using credentials for an administrator user but you don't actually know the password for <em>ContainerAdministrator<\/em> user that is part of the container and your Administrator password won't work inside your container. So go back to the console, attach container using \"docker attach\" if needed and issue the following commands<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">net user MyAdmin Pa$$w0rd! \/add\nnet localgroup administrators MyAdmin \/add<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>What you're doing is adding a new <em>MyAdmin<\/em> user using <em>Pa$$w0rd!<\/em> as his password and add him to the <em>Administrators<\/em> group. That user won't be part of the hosting OS and it will only exist in that specific container. Now you can connect back to Windows Admin Center and type <em>MyAdmin<\/em> \/ <em>Pa$$w0rd!<\/em> as your credentials.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1484,\"align\":\"center\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1024x808.jpg\" alt=\"\" class=\"wp-image-1484\"\/><figcaption>Windows Admin Center running inside a container<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Note that your gateway will be displaied as the container ID (<em>899aa7b9d38f<\/em>, in that image) and your current user will be displaied as as <em>[containerid]\\MyAdmin<\/em> (<em>899aa7b9d38f\\testadmin<\/em> in that image).<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Errors and limitations <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>There are a few quirks or limitations that you will face when working with Windows Admin Center installed inside a container. I wasn't able to make Powershell tool to work fine when connecting to remote servers. Not sure what the problem is and I'm working with Microsoft to understand if this can be fixed. Other tools seem to work fine though I didn't test them all.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p> This is by far the worst problem and I hope we can fix it. Then you have some tools not working when trying to connect back to container itself, that is the <em>gateway<\/em> in WAC terms. If you run a process-isolated container, you will be able administer it by using Windows Admin Center even if some tools won't work: Powershell, files, firewall and so on. That is somewhat expected and not a real limitation. If you run Hyper-V-isolated container, you won't be able to connect back to gateway, which as I said it is not a problem at all since you basically don't need to manage your gateway.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If there's a way for Powershell tool to work, deploying into containers could be a very handy option in many scenarios.<\/p>\n<!-- \/wp:paragraph -->"},"excerpt":{"rendered":"","protected":false,"raw":""},"author":9,"featured_media":1427,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_en_post_content":"<!-- wp:paragraph {\"dropCap\":true} -->\n<p class=\"has-drop-cap\">Microsoft is investing a lot into its new <em>Server Manager<\/em> though Redmond is not encouraging that parallelism and often says that Windows Admin Center is not a 1-to-1 replacement for Server Manager. That is true because Server Manager and its underlying technology has a deeper connection with the operating system and it can be considered a <em>platform<\/em> while Winows Admin Center can be considered a very sophisticated shell that mostly works through WMI\/Powershell connections.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>However, Windows Admin Center is gaining a lot of traction and it's quickly gaining support because its Web UI allows to embed important tasks into simple to access and to use widgets called tools and access them through a simple browser. Productivity is enhanced especially when used with the Core version of Windows operating systems and I'm not surprised that Microsoft <a rel=\"noreferrer noopener\" aria-label=\"is experiencing a growth in adoption for the Core SKUs (opens in a new tab)\" href=\"https:\/\/cloudblogs.microsoft.com\/windowsserver\/2019\/10\/03\/windows-admin-center-unleashes-server-core-adoption\/\" target=\"_blank\">is experiencing a growth in adoption for the Core SKUs<\/a> because of it.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Why containerizing Windows Admin Center ?<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>So the first question would be: why would someone want to containerize Windows Admin Center ? First, a containerized WAC would be very easy to deploy on multiple systems in a very straightforward way. Furthermore, multiple copies of WAC, possibly in use by different teams, could be deployed and used thanks to the isolation provided by containers and their flexibility. Containers could be also useful to mitigate any security issue that could arise even if Windows Admin Center showed no security vulnerabilities as far as I know. Finally, by using Hyper-V isolation multiple instances of WAC could be isolated and provided to multiple tenants.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Prepare the environment<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>To deploy WAC into a container we will use Windows Server 2019. We must first enable containers support by selecting and adding the feature in Roles&amp;Features section of Server Manager:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Then we must <a rel=\"noreferrer noopener\" aria-label=\"install Docker as per Microsoft Docs (opens in a new tab)\" href=\"https:\/\/docs.microsoft.com\/en-us\/virtualization\/windowscontainers\/deploy-containers\/deploy-containers-on-server\" target=\"_blank\">install Docker as per Microsoft Docs<\/a> : <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Module -Name DockerMsftProvider -Repository PSGallery -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and then<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Package -Name docker -ProviderName DockerMsftProvider<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and finally restore Windows Server 2019 to complete installation<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Restart-Computer -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When server restarts we can pull the Windows Server 2019 Core image that we will use to run Windows Admin Center. Note that WAC doesn't need IIS because it will self-host so downloading the base OS image will be enough<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker pull mcr.microsoft.com\/windows\/servercore:ltsc2019<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>After downloading the image we are now ready to spin our new container and install <em>Windows Admin Center<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Create the WAC container <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>We have a choice to make before creating the container for WAC and that is the port we want to expose WAC onto. That would be the port we connect to in order to use WAC. To make our life easier now, we will expose this port to the host but more sophisticated deployments might be appropriate depending on what you're trying to achieve. We need to decide that first because we will then need this information when installing Windows Admin Center. We will make it available on port 8443.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker run -it -p 8443:8443 mcr.microsoft.com\/windows\/servercore:ltsc2019 cmd.exe<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will have CMD prompt ready after starting the container. Now we need to copy the installation files into the container. You probably downloaded the WAC MSI from Microsoft website: please place that file inside the <em>c:\\<\/em> folder on the host. Get the Docker container ID by opening another command prompt and issuing a \"docker ps\" command:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"highlight\":\"2\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"2\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CONTAINER ID        IMAGE                                           COMMAND             CREATED             STATUS              PORTS                    NAMES\n9a4bb5975ee8        mcr.microsoft.com\/windows\/servercore:ltsc2019   \"cmd.exe\"           10 minutes ago      Up 11 seconds       0.0.0.0:8443->8443\/tcp   hardcore_bouman\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Container ID in my case is <em>9a4bb5975ee8.<\/em> Now you can copy the WAC MSI file into the container. Note that if you created an Hyper-V instance (which is not our case) you will need to stop container before you can copy files into it but in our case we used process isolation so we can issue a command file this:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp WindowsAdminCenter1910-RC4.msi 9a4bb5975ee8:c:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Now we should be able to type a simple \"dir\" inside the container to display available files:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Microsoft Windows [Version 10.0.17763.805]\n(c) 2018 Microsoft Corporation. All rights reserved.\n\nC:\\>dir\n Volume in drive C has no label.\n Volume Serial Number is 4E9D-71E0\n\n Directory of C:\\\n\n09\/15\/2018  10:42 AM             5,510 License.txt\n10\/06\/2019  11:04 AM    &lt;DIR>          Program Files\n10\/06\/2019  11:02 AM    &lt;DIR>          Program Files (x86)\n10\/06\/2019  11:05 AM    &lt;DIR>          Users\n11\/02\/2019  06:21 PM    &lt;DIR>          Windows\n10\/28\/2019  08:55 PM        62,529,536 WindowsAdminCenter1910-RC4.msi\n               2 File(s)     62,535,046 bytes\n               4 Dir(s)  21,033,639,936 bytes free\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>In my case, file is for 1910 RC4 of Windows Admin Center but obiviously the name depends on what you downloaded. You can now issue a \"exit\" command and end container since we will need to perform other tasks before we can actually install.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Installation errors<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>What we should do now is starting a unattended installation for Windows Admin Center, which is pretty straightforward. However installation will fail because of the installer will attempt to change settings for firewall and CredSSP and that is probably not allowed in a container thus we need to transform the MSI installer to skip such actions.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Orca comes at the rescue! If you don't know it, Orca is a tool by which you can generate <em>transformations<\/em> for the installer, that is changes to the installation process. There's a lot of things that you can change and I'll leave any experiment to the reader but what we are looking for it configuring <em>msiexec<\/em> to skip some custom actions. <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>First of all, download Orca and install it. You can easily download it from somewhere on the Web. After installation open Orca and open the MSI installer for Windows Admin Center: it will list all those settings that you could change. After the MSI settings load up, select <em>Trasform<\/em> menu and click on <em>New transform<\/em>, then look for <em>Custom action<\/em> on the list on the left and look for the actions listed below. Right click + \"Drop row\" to disable them.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1468,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1024x617.jpg\" alt=\"\" class=\"wp-image-1468\"\/><\/a><figcaption>Disable custom actions to update firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1470,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1024x617.jpg\" alt=\"\" class=\"wp-image-1470\"\/><\/a><figcaption>Yet more actions to disable for firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1472,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1024x617.jpg\" alt=\"\" class=\"wp-image-1472\"\/><\/a><figcaption>We also need to disable actions for CredSSP settings<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1474,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1024x617.jpg\" alt=\"\" class=\"wp-image-1474\"\/><\/a><figcaption>And yet more things related to firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>After you do this, click on <em>Tranform<\/em> menu and select <em>Generate transform<\/em> to create a new MST file that contains our transformations. Name it \"<em>WAC-NoFirewall-CredSSP.mst<\/em>\". Time to go back to our container...<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p><strong>P.S.<\/strong> Remember that transformation files are only valid for the file they are generated from. If you change your MSI source file, you will need to regenerate your transformations.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Windows Admin Center installation<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Ok, so we are ready. Back to the host restart your container by issuing<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker start 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>As you probably remember, <em>9a4bb5975ee8<\/em> is my container ID. Now we have to copy our MST file inside our container<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp c:\\WAC-NoFirewall-CredSSP.mst 9a4bb5975ee8:C:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When done we have both our WAC MSI file and our transformation file MST inside the root of our container so it's time to install. On your host issue a<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker attach 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>to connect to container console. Ensure that you are inside the C:\\ path and issue<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msiexec \/i WindowsAdminCenter1910-RC4.msi \/qn \/L*v log.txt SME_PORT=8443 SSL_CERTIFICATE_OPTION=generate TRANSFORMS=WAC-NoFirewall-CredSSP.mst<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Ensure that the MSI filename is set to the one that you are actually using. Pay attention to the <em>SME_PORT<\/em> parameter: this must be set to the same port you opened in your container or you won't be able to connect to Windows Admin Center. We are also generating a self-signed SSL certificated by this command and, most important, we ask <em>msiexec<\/em> to use our <em>WAC-NoFirewall-CredSSP.MST<\/em> file as a tranformation. A log of the installation will be stored inside <em>log.txt<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will read inside <em>log.txt <\/em>that WAC has been installed successfully.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3> Connecting to Windows Admin Center<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Now that Windows Admin Center has been installed, you can open your browser on your host OS and browse to <em>https:\/\/localhost:8443<\/em>, ignore that self-signed certificate we generated and... you won't be able to connect to WAC ! \ud83d\ude04<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>The reason for that is that you need to login using credentials for an administrator user but you don't actually know the password for <em>ContainerAdministrator<\/em> user that is part of the container and your Administrator password won't work inside your container. So go back to the console, attach container using \"docker attach\" if needed and issue the following commands<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">net user MyAdmin Pa$$w0rd! \/add\nnet localgroup administrators MyAdmin \/add<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>What you're doing is adding a new <em>MyAdmin<\/em> user using <em>Pa$$w0rd!<\/em> as his password and add him to the <em>Administrators<\/em> group. That user won't be part of the hosting OS and it will only exist in that specific container. Now you can connect back to Windows Admin Center and type <em>MyAdmin<\/em> \/ <em>Pa$$w0rd!<\/em> as your credentials.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1484,\"align\":\"center\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1024x808.jpg\" alt=\"\" class=\"wp-image-1484\"\/><figcaption>Windows Admin Center running inside a container<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Note that your gateway will be displaied as the container ID (<em>899aa7b9d38f<\/em>, in that image) and your current user will be displaied as as <em>[containerid]\\MyAdmin<\/em> (<em>899aa7b9d38f\\testadmin<\/em> in that image).<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Errors and limitations <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>There are a few quirks or limitations that you will face when working with Windows Admin Center installed inside a container. I wasn't able to make Powershell tool to work fine when connecting to remote servers. Not sure what the problem is and I'm working with Microsoft to understand if this can be fixed. Other tools seem to work fine though I didn't test them all.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p> This is by far the worst problem and I hope we can fix it. Then you have some tools not working when trying to connect back to container itself, that is the <em>gateway<\/em> in WAC terms. If you run a process-isolated container, you will be able administer it by using Windows Admin Center even if some tools won't work: Powershell, files, firewall and so on. That is somewhat expected and not a real limitation. If you run Hyper-V-isolated container, you won't be able to connect back to gateway, which as I said it is not a problem at all since you basically don't need to manage your gateway.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If there's a way for Powershell tool to work, deploying into containers could be a very handy option in many scenarios.<\/p>\n<!-- \/wp:paragraph -->","_en_post_name":"how-to-containerize-windows-admin-center","_en_post_excerpt":"","_en_post_title":"How to containerize Windows Admin Center","_it_post_content":"<!-- wp:paragraph {\"dropCap\":true} -->\n<p class=\"has-drop-cap\">Microsoft is investing a lot into its new <em>Server Manager<\/em> though Redmond is not encouraging that parallelism and often says that Windows Admin Center is not a 1-to-1 replacement for Server Manager. That is true because Server Manager and its underlying technology has a deeper connection with the operating system and it can be considered a <em>platform<\/em> while Winows Admin Center can be considered a very sophisticated shell that mostly works through WMI\/Powershell connections.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>However, Windows Admin Center is gaining a lot of traction and it's quickly gaining support because its Web UI allows to embed important tasks into simple to access and to use widgets called tools and access them through a simple browser. Productivity is enhanced especially when used with the Core version of Windows operating systems and I'm not surprised that Microsoft <a rel=\"noreferrer noopener\" aria-label=\"is experiencing a growth in adoption for the Core SKUs (opens in a new tab)\" href=\"https:\/\/cloudblogs.microsoft.com\/windowsserver\/2019\/10\/03\/windows-admin-center-unleashes-server-core-adoption\/\" target=\"_blank\">is experiencing a growth in adoption for the Core SKUs<\/a> because of it.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Why containerizing Windows Admin Center ?<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>So the first question would be: why would someone want to containerize Windows Admin Center ? First, a containerized WAC would be very easy to deploy on multiple systems in a very straightforward way. Furthermore, multiple copies of WAC, possibly in use by different teams, could be deployed and used thanks to the isolation provided by containers and their flexibility. Containers could be also useful to mitigate any security issue that could arise even if Windows Admin Center showed no security vulnerabilities as far as I know. Finally, by using Hyper-V isolation multiple instances of WAC could be isolated and provided to multiple tenants.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Prepare the environment<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>To deploy WAC into a container we will use Windows Server 2019. We must first enable containers support by selecting and adding the feature in Roles&amp;Features section of Server Manager:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Then we must <a rel=\"noreferrer noopener\" aria-label=\"install Docker as per Microsoft Docs (opens in a new tab)\" href=\"https:\/\/docs.microsoft.com\/en-us\/virtualization\/windowscontainers\/deploy-containers\/deploy-containers-on-server\" target=\"_blank\">install Docker as per Microsoft Docs<\/a> : <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Module -Name DockerMsftProvider -Repository PSGallery -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and then<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Package -Name docker -ProviderName DockerMsftProvider<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>and finally restore Windows Server 2019 to complete installation<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Restart-Computer -Force<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When server restarts we can pull the Windows Server 2019 Core image that we will use to run Windows Admin Center. Note that WAC doesn't need IIS because it will self-host so downloading the base OS image will be enough<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"shell\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker pull mcr.microsoft.com\/windows\/servercore:ltsc2019<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>After downloading the image we are now ready to spin our new container and install <em>Windows Admin Center<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Create the WAC container <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>We have a choice to make before creating the container for WAC and that is the port we want to expose WAC onto. That would be the port we connect to in order to use WAC. To make our life easier now, we will expose this port to the host but more sophisticated deployments might be appropriate depending on what you're trying to achieve. We need to decide that first because we will then need this information when installing Windows Admin Center. We will make it available on port 8443.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker run -it -p 8443:8443 mcr.microsoft.com\/windows\/servercore:ltsc2019 cmd.exe<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will have CMD prompt ready after starting the container. Now we need to copy the installation files into the container. You probably downloaded the WAC MSI from Microsoft website: please place that file inside the <em>c:\\<\/em> folder on the host. Get the Docker container ID by opening another command prompt and issuing a \"docker ps\" command:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"highlight\":\"2\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"2\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CONTAINER ID        IMAGE                                           COMMAND             CREATED             STATUS              PORTS                    NAMES\n9a4bb5975ee8        mcr.microsoft.com\/windows\/servercore:ltsc2019   \"cmd.exe\"           10 minutes ago      Up 11 seconds       0.0.0.0:8443->8443\/tcp   hardcore_bouman\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Container ID in my case is <em>9a4bb5975ee8.<\/em> Now you can copy the WAC MSI file into the container. Note that if you created an Hyper-V instance (which is not our case) you will need to stop container before you can copy files into it but in our case we used process isolation so we can issue a command file this:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp WindowsAdminCenter1910-RC4.msi 9a4bb5975ee8:c:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Now we should be able to type a simple \"dir\" inside the container to display available files:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Microsoft Windows [Version 10.0.17763.805]\n(c) 2018 Microsoft Corporation. All rights reserved.\n\nC:\\>dir\n Volume in drive C has no label.\n Volume Serial Number is 4E9D-71E0\n\n Directory of C:\\\n\n09\/15\/2018  10:42 AM             5,510 License.txt\n10\/06\/2019  11:04 AM    &lt;DIR>          Program Files\n10\/06\/2019  11:02 AM    &lt;DIR>          Program Files (x86)\n10\/06\/2019  11:05 AM    &lt;DIR>          Users\n11\/02\/2019  06:21 PM    &lt;DIR>          Windows\n10\/28\/2019  08:55 PM        62,529,536 WindowsAdminCenter1910-RC4.msi\n               2 File(s)     62,535,046 bytes\n               4 Dir(s)  21,033,639,936 bytes free\n<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>In my case, file is for 1910 RC4 of Windows Admin Center but obiviously the name depends on what you downloaded. You can now issue a \"exit\" command and end container since we will need to perform other tasks before we can actually install.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Installation errors<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>What we should do now is starting a unattended installation for Windows Admin Center, which is pretty straightforward. However installation will fail because of the installer will attempt to change settings for firewall and CredSSP and that is probably not allowed in a container thus we need to transform the MSI installer to skip such actions.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Orca comes at the rescue! If you don't know it, Orca is a tool by which you can generate <em>transformations<\/em> for the installer, that is changes to the installation process. There's a lot of things that you can change and I'll leave any experiment to the reader but what we are looking for it configuring <em>msiexec<\/em> to skip some custom actions. <\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>First of all, download Orca and install it. You can easily download it from somewhere on the Web. After installation open Orca and open the MSI installer for Windows Admin Center: it will list all those settings that you could change. After the MSI settings load up, select <em>Trasform<\/em> menu and click on <em>New transform<\/em>, then look for <em>Custom action<\/em> on the list on the left and look for the actions listed below. Right click + \"Drop row\" to disable them.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1468,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_01-1024x617.jpg\" alt=\"\" class=\"wp-image-1468\"\/><\/a><figcaption>Disable custom actions to update firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1470,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_02-1024x617.jpg\" alt=\"\" class=\"wp-image-1470\"\/><\/a><figcaption>Yet more actions to disable for firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1472,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_03-1024x617.jpg\" alt=\"\" class=\"wp-image-1472\"\/><\/a><figcaption>We also need to disable actions for CredSSP settings<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:image {\"id\":1474,\"align\":\"center\",\"linkDestination\":\"media\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_04-1024x617.jpg\" alt=\"\" class=\"wp-image-1474\"\/><\/a><figcaption>And yet more things related to firewall<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>After you do this, click on <em>Tranform<\/em> menu and select <em>Generate transform<\/em> to create a new MST file that contains our transformations. Name it \"<em>WAC-NoFirewall-CredSSP.mst<\/em>\". Time to go back to our container...<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p><strong>P.S.<\/strong> Remember that transformation files are only valid for the file they are generated from. If you change your MSI source file, you will need to regenerate your transformations.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Windows Admin Center installation<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Ok, so we are ready. Back to the host restart your container by issuing<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker start 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>As you probably remember, <em>9a4bb5975ee8<\/em> is my container ID. Now we have to copy our MST file inside our container<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker cp c:\\WAC-NoFirewall-CredSSP.mst 9a4bb5975ee8:C:\\<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>When done we have both our WAC MSI file and our transformation file MST inside the root of our container so it's time to install. On your host issue a<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker attach 9a4bb5975ee8<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>to connect to container console. Ensure that you are inside the C:\\ path and issue<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock {\"language\":\"msdos\"} -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"msdos\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">msiexec \/i WindowsAdminCenter1910-RC4.msi \/qn \/L*v log.txt SME_PORT=8443 SSL_CERTIFICATE_OPTION=generate \/TRANSFORMS=WAC-NoFirewall-CredSSP.mst<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>Ensure that the MSI filename is set to the one that you are actually using. Pay attention to the <em>SME_PORT<\/em> parameter: this must be set to the same port you opened in your container or you won't be able to connect to Windows Admin Center. We are also generating a self-signed SSL certificated by this command and, most important, we ask <em>msiexec<\/em> to use our <em>WAC-NoFirewall-CredSSP.MST<\/em> file as a tranformation. A log of the installation will be stored inside <em>log.txt<\/em>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If everything goes well you will read inside <em>log.txt <\/em>that WAC has been installed successfully.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3> Connecting to Windows Admin Center<\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Now that Windows Admin Center has been installed, you can open your browser on your host OS and browse to <em>https:\/\/localhost:8443<\/em>, ignore that self-signed certificate we generated and... you won't be able to connect to WAC ! \ud83d\ude04<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>The reason for that is that you need to login using credentials for an administrator user but you don't actually know the password for <em>ContainerAdministrator<\/em> user that is part of the container and your Administrator password won't work inside your container. So go back to the console, attach container using \"docker attach\" if needed and issue the following commands<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:enlighter\/codeblock -->\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">net user MyAdmin Pa$$w0rd! \/add\nnet localgroup administrators MyAdmin \/add<\/pre>\n<!-- \/wp:enlighter\/codeblock -->\n\n<!-- wp:paragraph -->\n<p>What you're doing is adding a new <em>MyAdmin<\/em> user using <em>Pa$$w0rd!<\/em> as his password and add him to the <em>Administrators<\/em> group. That user won't be part of the hosting OS and it will only exist in that specific container. Now you can connect back to Windows Admin Center and type <em>MyAdmin<\/em> \/ <em>Pa$$w0rd!<\/em> as your credentials.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:image {\"id\":1484,\"align\":\"center\"} -->\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img src=\"https:\/\/www.theserverside.technology\/wp-content\/uploads\/2019\/11\/wac_containers_05-1024x808.jpg\" alt=\"\" class=\"wp-image-1484\"\/><figcaption>Windows Admin Center running inside a container<\/figcaption><\/figure><\/div>\n<!-- \/wp:image -->\n\n<!-- wp:paragraph -->\n<p>Note that your gateway will be displaied as the container ID (<em>899aa7b9d38f<\/em>, in that image) and your current user will be displaied as as <em>[containerid]\\MyAdmin<\/em> (<em>899aa7b9d38f\\testadmin<\/em> in that image).<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3>Errors and limitations <\/h3>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>There are a few quirks or limitations that you will face when working with Windows Admin Center installed inside a container. I wasn't able to make Powershell tool to work fine when connecting to remote servers. Not sure what the problem is and I'm working with Microsoft to understand if this can be fixed. Other tools seem to work fine though I didn't test them all.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p> This is by far the worst problem and I hope we can fix it. Then you have some tools not working when trying to connect back to container itself, that is the <em>gateway<\/em> in WAC terms. If you run a process-isolated container, you will be able administer it by using Windows Admin Center even if some tools won't work: Powershell, files, firewall and so on. That is somewhat expected and not a real limitation. If you run Hyper-V-isolated container, you won't be able to connect back to gateway, which as I said it is not a problem at all since you basically don't need to manage your gateway.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>If there's a way for Powershell tool to work, deploying into containers could be a very handy option in many scenarios.<\/p>\n<!-- \/wp:paragraph -->","_it_post_name":"","_it_post_excerpt":"","_it_post_title":"How to containerize Windows Admin Center","edit_language":"it"},"categories":[400],"tags":[377,329,108,381,115],"_links":{"self":[{"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/posts\/1426"}],"collection":[{"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/comments?post=1426"}],"version-history":[{"count":43,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/posts\/1426\/revisions"}],"predecessor-version":[{"id":1490,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/posts\/1426\/revisions\/1490"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/media\/1427"}],"wp:attachment":[{"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/media?parent=1426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/categories?post=1426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.theserverside.technology\/it\/wp-json\/wp\/v2\/tags?post=1426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}