Blog Post

System Center Blog
2 MIN READ

A brand new web console for Orchestrator 2019

Molish's avatar
Molish
Icon for Microsoft rankMicrosoft
Dec 16, 2021

System Center Orchestrator is the datacenter workflow management solution that's commonly used to automate datacenter operations including creation, monitoring, and deployment of data center resources. We consistently hear feedback from customers on enhancing the user experience and support for modern browsers. Thanks to the Orchestrator community for the continued support and feedback.    

 

We are excited to announce the release of brand new web console for System Center Orchestrator 2019. The new web console works well on modern browsers without Silverlight dependency. As you are all aware, the old Orchestrator console was built on Silverlight and Silverlight has been completely discontinued. Read more about the Silverlight announcement here.

The new web console brings in additional capabilities that includes the following.

  • The older version of SCO web console runs only on IE. The new version works on modern browsers like Microsoft Edge, Firefox, or Google Chrome.
  • The new Web console does not use Silverlight.
  • The new OData v4 JSON based Web API simplifies all the endpoints, most notably the ones for Job management.
  • The console also works well along-side the old Web service and old Web console.

The new console for System Center Orchestrator 2019 can be downloaded from here. We would like to inform that the new console will also be part of our upcoming System Center 2022 release. If you are interested to know more about System Center 2022, read our recent blog here.

 

Update [17 August 2023]: An updated version of System Center 2019 Web console v10.19.350.0 is now available here. The new release features .NET Core 6 and introduces significant enhancements as compared to the previous version. You can upgrade to the latest build by following the steps mentioned here.

Updated Aug 17, 2023
Version 2.0

55 Comments

  • Thanks for the new console.
    I have successfully installed the webservice and I can display the Runbooks, Folders and Servers.
    But I have an error to display the instances and jobs because there are too many objects, yet I only have 30 days of history (17607 jobs).
    Even if I force to recover only the first 5 jobs, it falls into error 500.

     

    Invoke-RestMethod -Uri 'http: // localhost: 881 / api / Jobs? Top = 5' -UseDefaultCredentials
    Invoke-RestMethod: The remote server returned an error: (500) Internal Server Error.

     

     

    Category: Microsoft.AspNetCore.Server.IIS.Core.IISHttpServer

    EventId: 2

    SpanId: 7efe98416550b544

    TraceId: 3bc584801971744ab99578033d428017

    ParentId: 0000000000000000

    RequestId: 80000019-0000-fe00-b63f-84710c7967bb

    RequestPath: /api/Jobs

     

    Connection ID "18302628887244308503", Request ID "80000019-0000-fe00-b63f-84710c7967bb": An unhandled exception was thrown by the application.

     

    Exception:

    System.InvalidOperationException: 'AsyncEnumerableReader' reached the configured maximum size of the buffer when enumerating a value of type 'Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[Orchestrator.Data.Models.Job]'. This limit is in place to prevent infinite streams of 'IAsyncEnumerable<>' from continuing indefinitely. If this is not a programming mistake, consider ways to reduce the collection size, or consider manually converting 'Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[Orchestrator.Data.Models.Job]' into a list rather than increasing the limit.

       at Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternal[T](Object value)

       at Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternal[T](Object value)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, Object asyncEnumerable, Func`2 reader)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)

       at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)

       at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)

       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)

       at Orchestrator.WebApi.Middlewares.TokenMiddleware.Invoke(HttpContext context, OrchestratorContext dbContext) in C:\__w\1\s\src\Orchestrator.WebApi\Middlewares\TokenMiddleware.cs:line 66

       at Orchestrator.WebApi.Middlewares.HttpOptionsMiddleware.Invoke(HttpContext context) in C:\__w\1\s\src\Orchestrator.WebApi\Middlewares\HttpOptionsMiddleware.cs:line 34

       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

       at Microsoft.AspNetCore.OData.Query.ODataQueryRequestMiddleware.Invoke(HttpContext context)

       at Microsoft.AspNetCore.OData.Routing.ODataRouteDebugMiddleware.Invoke(HttpContext context)

       at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()

     

  • Andy_Stewart's avatar
    Andy_Stewart
    Copper Contributor

    Missed one - Cog icon top right has a blank popup - doesn't seem to do anything?

  • Andy_Stewart's avatar
    Andy_Stewart
    Copper Contributor

    Molish got it up and running in our dev/test environment, with the tweaks from PChip1976 (thanks!)

     

    Is there a way to track development work on it, or raise queries/questions other than the bug report icon?

     

    e.g.

    - Folder structure not in alphabetic order like older version

    - No runbook servers or events tabs?

    - Summary stats not showing up ? (i.e. "Active Jobs shows 15" but nothing in the list underneath it on the page?

     

    Keen to see this progress, and to help out.

  • PChip1976's avatar
    PChip1976
    Copper Contributor

    TomRh Note the version is 0.1.0, definitely NOT production level code...  Spent 2 days reverse engineering the install docs till I got it mostly working, but yeah, looks nice, but definitely BETA.

     

    So try this:

    1. (Likely your issue) Download and install the ASP.NET core 5.0 (not the latest 6.0 the doc sends you to) web hosting, found https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-5.0.13-windows-hosting-bundle-installer
    2. (Needed for rewrite rules in web.config below) Download and install https://www.iis.net/downloads/microsoft/url-rewrite
    3. Copy the WebConsole folder to c:\inetpub
      • If you want to use port 80/443, you can simply replace the contents of c:\inetpub\wwwroot
      • You can also put the folder anywhere else for that matter
    4. Copy the WebApi folder to c:\inetpub (or other location)
      • There are 2 folders: the tree should look like C:\inetpub\WebApi & C:\inetpub\webconsole
    5. Create an account that has (at least) read access to the database (although I used the Orch Service Account, so it had all the required permissions already)
    6. Run the PowerShell script 2x (1 for the WebConsole, 1 for the WebAPI)
      • Make sure you're using the account from previous step
      • For the WebAPI, I would recommend you use the default port 5001 just in case something else is screwy.  For the webconsole, you can use port 80.
      • Actually, I would recommend that instead of the script you follow the manual process to create the web applications.  
    7. In the WebConsole\assets\configuration.json file, replace the webUri with "http://<ServerFQDN>:5001" (change the port if you didn't use the 5001 port for the WebAPI)
    8. Open your firewall rules to allow inbound TCP to your WebConsole AND WebAPI from your possible clients PCs
    9. Replace the WebApi\web.config with the following file

     

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <httpProtocol>
            <customHeaders>
              <add name="Access-Control-Allow-Credentials" value="true" />
              <add name="Access-Control-Allow-Methods" value="GET, POST, PATCH, OPTIONS" />
              <add name="Access-Control-Allow-Headers" value="Content-Type" />
            </customHeaders>
          </httpProtocol>
    	          <rewrite>            
                <outboundRules>
                    <clear />                
                    <rule name="AddCrossDomainHeader">
                        <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
                        <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                            <add input="{HTTP_ORIGIN}" pattern="(http(s)?:\/\/.*)" />
                        </conditions>
                        <action type="Rewrite" value="{C:0}" />
                    </rule>           
                </outboundRules>
            </rewrite>
          <handlers>
            <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
          </handlers>
          <aspNetCore processPath="dotnet" arguments=".\Orchestrator.WebApi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
            <environmentVariables>
              <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
                        <environmentVariable name="Database__Database" value="Orchestrator" />
                        <environmentVariable name="Database__Trusted_Connection" value="true" />
                        <environmentVariable name="Database__Address" value="***DBSERVERNAME***" />
            </environmentVariables>
          </aspNetCore>
        </system.webServer>
      </location>
    </configuration>
    <!--ProjectGuid: 2b28e03a-bff3-4fa9-98ee-fd2db7d151d6-->

     

    • For some added level of security, you may want to change the regex at line 18 with something to match all the possible clients (eg: PCs) that may access the webconsole (I have in mine but of course, that's confidential :smile:). 
      • If you do, then replace the ".*" with "(<regex>|localhost)" so you can keep on accessing it from the localhost using localhost AND from other computers in the network.  
      • Do NOT put the quotes
      • DO put the parenthesis
      • Reference: Stack Overflow:  https://stackoverflow.com/questions/17323350/access-control-allow-origin-with-multiple-domains 
    • Replace line 30 with your DB name
    • Replace line 32 with your actual DB Server name/alias.

     

     

    ...OK, I think that's sufficient for the time being.  For troubleshooting:

    • Use the Application Event Log for the WebAPI
    • Open the client's Browser Console (F12) to look at the WebConsole errors

    HTH

     

     

    Molish How can you release something when there can only be 1 hardcoded client (IP/Hostname) that can actually use the Web Console, as per the design provided because of the Allow-Origin.  See Stack Overflow above for more info

  • TomRh's avatar
    TomRh
    Copper Contributor

    Unfortunately, I can't get this to run. The Orchestrator.WebApi always runs into an HTTP 500 Internal Server Error. The permissions should all fit, but I'm not sure about the Database Connection String. Is the example from the manual enough or do I need more information?