Saturday 26 December 2015

Customising the Service Manager HTML5 Portal

Microsoft have released a new HTML5 Portal, released as Update Rollup 8 for Service Manager, and we again have a few different areas in which to do customisations.

In this post I will outline both the most common basic customisation you will want to do after installation (branding the portal for your organisation) and a slightly more deeper customisation (adding a new item to the side bar).

Basic Customisation:

After a default installation, one of the first things you're likely going to want to change is the basic info.

This consists of:
  • Site Tile (Default Contoso Service Desk)
  • Support Contact Information (Defaults to Contoso Support with a 12345 number).
This is done via the web.config file found in the root of the installation folder (by default C:\inetpub\wwwroot\SelfServicePortal).

Lines 18 - 37 are the ones to focus on (for now) and allow you to change the defaults to something more suitable for your environment.


  • Lines 20 - 23 alter the site title and basic contact information.
  • Line 25 usually gets set to French, so amend to reflect your preferred default language.
  • Line 27 should be changed if you have a custom template that needs using for logging a basic incident request.
  • Line 29 should have been set correctly during installation and will reflect the SCSM Management server to use for all SDK calls.
  • Line 30 controls how much data is pulled back from a query in a request offering
  • Lines 32 & 33 control the timeouts on the caching of information used by the portal (only play with when testing or have a specific need, these defaults should suffice for most)
  • Line 35 will control the upload of telemetry data to Microsoft.
    N.B. Please don't immediately go and turn this off as a knee jerk reaction to "Microsoft are invading my privacy!!". The more telemetry Microsoft can get around usage of the portal, the better they can make it!

Deeper Customisation:
One example of a more deeper customisation is modification of the side bar. For example there may be a requirement to add your own link to perhaps an external site.

In the following example, I'll add a link to the Configuration Manager Software Catalog.



Open the Sidebar.cshtml file in either notepad, or some other editor (Default location is C:\inetpub\wwwroot\SelfServicePortal\Views\Shared\Sidebar.cshtml)

The first DIV section controls the collapsed state of the sidebar (Usually line 13)
   <div class="side_nav_bar col side_menu">

Within this section adding the following code will add a new item:

       <div class="row side_nav_sccm" accesskey="S" tabindex="9" data-toggle="tooltip" title="Software Catalog">
           <span class="icon-Dictionary icon icon-pos icon-medium"></span>
       </div>


  • Class="row side_nav_sccm" is used to name this section artefact
  • accesskey="" part to bind the icon to the S Key
  • tabindex="" assigns the order of which pressing the tab key cycles through the items.
  • title="" is the text shown as a tooltip when hovering over icon
The span class code is used to choose the icon displayed, in this example I've specified the Dictionary icon using icon-Dictionary which is the same icon used for accessing the Service Catalog at the top of the sidebar.

The list of icons already defined for use in the portal can be found in the main.css file in the .\Content\CSS folder from usually about line 2024. These are basically friendly name mappings for the character codes used within the fonts found in the .\Content\CSS\fonts folder.


You can either reference one of these friendly names, like I have in this example using icon-Dictionary, or dig deeper into the font file, find the icon you like and then create your own friendly name for reference.

TIP: If you can't convert the woff file to a ttf to be able to view it in Character Map, then you might want to check the OneDrive API GitHub site which hosts a copy.
https://github.com/OneDrive/onedrive-api-docs/tree/master/html-template/css


** Updated 12/04/2016**
The link I had previously to the font for use in CharMap is now dead :(

However, thanks to Donato Pasqualicchio @ MSFT, here is a link to this useful cheat sheet for the font: http://modernicons.io/segoe-mdl2/cheatsheet/

Back in the Sidebar.cshtml file that we're customising... 

The second DIV section controls the expanded state of the sidebar
   <div class="side_nav_bar_expand col side_menu">

Within this section add the following code to control how the button looks like in the expanded state, along with the URL to use when clicked.

<div class="row side_nav_sccm">
    <span class="icon-Dictionary icon-medium icon icon-pos"></span>
    <span class="icon-text icon-text-pos"><a href="http://ponconfigmgr01/cmapplicationcatalog/#/SoftwareCatalog" target="_blank">Software Catalog</a></span>
</div>



Class="row side_nav_sccm" is used to name this section artefact

The first bit of span class code is used to choose the icon displayed, so I've kept it the same as the icon in the minimised state (icon-Dictonary).

The second bit of span class code is used to define the text to show alongside the icon.
It's also here that I insert a URL that becomes the icon text and will open a new tab to the URL when clicked.

Save the sidebar.cshtml file, refresh the page and the new icon should be there and working!

I'm working on some further customisation posts, but feel free to post a comment if there is any specific customisation scenario you would like me to cover.

Wednesday 23 December 2015

Using Azure Automation DSC to configure and deploy the new SCSM Portal (Part 2)

So in the previous post I outlined creating a basic configuration file for DSC to deploy the new HTML5 Self-Service Portal for System Center 2012 R2 Service Manager.

Previous Post: http://www.systemcenter.ninja/2015/12/using-azure-automation-dsc-to-configure.html

In this post I thought I'd produce a quick video showing adding a server as a DSC node, applying the Configuration to it and checking the configuration applied.

Also, after the video break, I thought I'd detail a couple of additions I made to the configuration that weren't in the first post.



So if you just watched the video you'll have noticed I added a bit more configuration using something called DSC Resources.

Specifically I used xWebAdministration and xNetworking, both of which can be found on the PowerShell Gallery.

http://www.powershellgallery.com/

The PowerShell Gallery is the central repository for PowerShell content. You can find new PowerShell commands or Desired State Configuration (DSC) resources in the Gallery.

xWebAdministration Module - http://www.powershellgallery.com/packages/xWebAdministration/
xNetworking Module - http://www.powershellgallery.com/packages/xNetworking/

Both these modules contain multiple resources that can be used to aid in configuration.

The cool thing here is modules can be either deployed directly from the PowerShell Gallery into your Azure Automation subscription, or along with custom resources, uploaded as a zip file via the Azure Portal.

You can find them within your Assets > Modules section of the portal.



I'm using from the xWebAdministration module the xWebsite resource to change the port of the default web site in IIS from port 80 to 81 so that I can reutilise port 80 for the new SCSM SSP.

I do this by creating a new xWebsite section named DefaultWebsite and then use the BindingInfo section to declare which port the web site (Identified in the Name = "Default Web Site" part) should be using.

xWebsite DefaultWebsite
  {
    Ensure = "Present"
    Name = "Default Web Site"
    State = "Started"
    PhysicalPath = "C:\inetpub\wwwroot"
    BindingInfo = MSFT_xWebBindingInformation
      {
        Protocol = "HTTP"
        Port = 81
      }
    DependsOn = "[WindowsFeature]WebServer"
   }


Deeper details and resources can be found on the projects GitHub site:
https://github.com/PowerShell/xWebAdministration


I'm then doing a similar thing with the xFirewall resource from the xNetworking module to create a new firewall rule

xFirewall SCSMSSPFirewallRule
  {
    Direction = "Inbound"
    Name = "SCSM-SSP-Web-TCP-In"
    DisplayName = "SCSM SSP Web Server (TCP-In)"
    Description = "Allow incoming web site traffic to SCSM SSP."
    DisplayGroup = "PowerONPlatforms"
    Enabled = "True"
    Action = "Allow"
    Protocol = "TCP"
    LocalPort = "80"
    Ensure = "Present"
  }


Deeper details and resources can be found on the projects GitHub site:
https://github.com/PowerShell/xNetworking


This is by no means a production ready example, but does give some basics around using some of the built in resources (WindowsFeature & Package) along with some custom resources (xWebAdministration and xWebsite) and where to go find them (PowerShell Gallery).

Also, please note the SCSM Portal still requires both modifications to the web.config file and the Update 1 hotfix installing afterwards.

https://www.microsoft.com/en-us/download/details.aspx?id=50362



Tuesday 22 December 2015

Using Azure Automation DSC to configure and deploy the new SCSM Portal (Part 1)

On Nov 10th Microsoft released a new HTML portal for System Center Service Manager 2012 R2.

The installation is fairly straight forward, however there are still some pre-requisites that need to be in place and I also thought it would be good to introduce delivering this via Azure Automation Desired State Configuration (DSC).

The main reason for looking to do this via DSC is also the ongoing maintenance.
Things happen. People can make mistakes, features and roles can be accidently removed.

DSC provides a set of configuration that;
  • should be applied to a server
  • will be applied to a server to bring it into compliance
  • will then continue to check the server for compliance
  • will attempt to remediate and bring it back into compliance should it drift.


So what do we need?

Well the new portal is an IIS site and therefore requires some windows features to be installed. These are:

  • Web-Server
  • Web-Filtering
  • Web-Basic-Auth
  • Web-Windows-Auth
  • Web-Mgmt-Console
  • Web-Mgmt-Compat
  • Web-Net-Ext45
  • Web-ASP
  • Web-Asp-Net45
  • NET-Framework-45-ASPNET
  • NET-WCF-HTTP-Activation45

These can be easily added using a single PowerShell line:
Add-WindowsFeature Web-Server,Web-Filtering,Web-Basic-Auth,Web-Windows-Auth,Web-Mgmt-Console,Web-Mgmt-Compat,Web-Net-Ext45,Web-ASP,Web-Asp-Net45,NET-Framework-45-ASPNET,NET-WCF-HTTP-Activation45


But installation, as I mentioned, is only part of the story. Making sure these features remain in place is where DSC come in.

In DSC we create a "Configuration" file which lays out how the assigned server should be configured.
For Windows features there is a specific DSC Resource we use, aptly named, WindowsFeature.

For each windows feature that we require we use a block like this:

WindowsFeature WebServer
{
Ensure = "Present"
Name = "Web-Server"
}

So basically we name the code block with something meaningful (as we may reference later) with the WindowsFeature resource, use the Name property to specify the Windows Feature to check (Use Get-WindowsFeature in PowerShell to check for the name you require) and then use the Ensure property to state whether the named feature should either be present on the server or not (our intention).

Further properties and information can be found here:
https://technet.microsoft.com/en-us/library/dn282127.aspx

So for all our Windows Feature requirements for the SCSM Portal we get:
#Install the required IIS features
WindowsFeature WebServer
{
Ensure = "Present"
Name = "Web-Server"
}
WindowsFeature WebFiltering
{
Ensure = "Present"
Name = "Web-Filtering"
}
WindowsFeature WebBasicAuth
{
Ensure = "Present"
Name = "Web-Basic-Auth"
}
WindowsFeature WebWindowsAuth
{
Ensure = "Present"
Name = "Web-Windows-Auth"
}
WindowsFeature WebMgmtConsole
{
Ensure = "Present"
Name = "Web-Mgmt-Console"
}
WindowsFeature WebMgmtCompat
{
Ensure = "Present"
Name = "Web-Mgmt-Compat"
}
WindowsFeature WebNetExt45
{
Ensure = "Present"
Name = "Web-Net-Ext45"
}
WindowsFeature WebASP
{
Ensure = "Present"
Name = "Web-Asp"
}
WindowsFeature WebASPNet45
{
Ensure = "Present"
Name = "Web-Asp-Net45"
}
WindowsFeature NETFramework45ASPNET
{
Ensure = "Present"
Name = "NET-Framework-45-ASPNET"
}
WindowsFeature NETWCFHTTPActivation45
{
Ensure = "Present"
Name = "NET-WCF-HTTP-Activation45"
}


Well, that's the Windows Features sorted.
Now please, bear with me here as so far it looks like a lot more work as opposed to that single PowerShell one liner...

Next is the installation of the SCSM Portal.

For this we utilise the DSC Package Resource and it looks something like this:

Package SCSMSSP
{
Name = "SCSM SSP"
Path = "C:\DSC\SSP\SetupWizard.exe"
ProductId = "17F5D20F-47FB-485E-8CFC-4768C3C3F460"
Arguments = "/Install:SelfServicePortal /silent /accepteula /CustomerExperienceImprovementProgram:No /EnableErrorReporting:No /SMServerName:$SCSMSDKServer /PortalWebSiteName:SCSMPortal /PortalWebSitePort:81 /PortalAccount:$Domain\$SCSMUser\$SCSMPassword"
Ensure = "Present"
DependsOn = @("[WindowsFeature]WebServer","[WindowsFeature]WebFiltering","[WindowsFeature]WebBasicAuth","[WindowsFeature]WebWindowsAuth","[WindowsFeature]WebMgmtConsole","[WindowsFeature]WebMgmtCompat","[WindowsFeature]WebNetExt45","[WindowsFeature]WebASP","[WindowsFeature]WebASPNet45","[WindowsFeature]NETFramework45ASPNET","[WindowsFeature]NETWCFHTTPActivation45")
}


So again, we provide a name for the Package Resource code block (SCSMSSP) and a more friendly name for the Name property.
The Path property denotes where the installation file resides.
The ProductId property is the unique GUID for the application to allow DSC to check for it's presence.
The Arguments property is used for any command line to be passed to control the installation.
Again, the Ensure property denotes if the software should be installed (present) or not installed (absent).

The DependsOn property allows us to specify various resources that DSC should first ensure are compliant before attempting to run this resource.

It's easy to specify a dependant resource, just wrap the DSC Resource type name in square brackets and then specify the name of that feature.
So WindowsFeature WebASPNet45 becomes [WindowsFeature]WebASPNet45.

One thing to note is that if you need to specify multiple dependencies then you need to specify them as a string formatted as an array.
Do this by putting each feature formatted as just discussed in quotation marks " " and separating with a comma. Finally enclose it as an array - @( ).

So if we required two features, WebMgmtCompat and WebASP we would have the following:

DependsOn = @("[WindowsFeature]WebMgmtCompat","[WindowsFeature]WebASP")

So we're almost there...

For those that were paying attention, you may have noticed that the arguments property string contained some variables.
This allows us to prompt when compiling the DSC configuration for various settings to prevent hard coding data and allow for reuse.
Just like normal PowerShell we put these at the beginning in a Param block.

Param(
[Parameter(Mandatory=$true)]
[string] $SCSMSDKServer,
[Parameter(Mandatory=$true)]
[string] $Domain
)
$SCSMSDKCred = Get-AutomationPSCredential -Name "SCSMSDKCredentialAsset"
$SCSMUser=$SCSMSDKCred.UserName
$SCSMPassword = $SCSMSDKCred.GetNetworkCredential().Password

I'm also going to leverage the Credentials Asset feature of Azure Automation.
This allows you to securely store username and password combo's within Azure Automation as an asset to then be reused in Runbooks and DSC. Again, allowing us to avoid hardcoding sensitive data and not having to prompt for them at each compilation.

I'm using the Get-AutomationPSCredential command to retrieve it and then split the PSCredential object down to username and password.

However, because I'm utilising this for the command line arguments for the executable installation I can't use it as a PSCredential and have to supply a non encrypted password, hence the use of the .GetNetworkCredential().Password to pull the unencrypted password out of the object.

N.B. This has the side effect of storing the password in clear text within the MOF that gets compiled and pushed down to the DSC node.

Because of this, it also means that compilation of the configuration can not be done via the Azure Portal and only by PowerShell as you will need to add configuration to the compilation task to tell it to allow the use of plain text passwords. More on this later.


The final DSC Configuration script looks like this:


Configuration SCSMPortal
{
param(
[Parameter(Mandatory=$true)]
[string] $SCSMSDKServer,
[Parameter(Mandatory=$true)]
[string] $Domain
)
$SCSMSDKCred = Get-AutomationPSCredential -Name "SCSMSDKCredentialAsset"
$SCSMUser=$SCSMSDKCred.UserName
$SCSMPassword = $SCSMSDKCred.GetNetworkCredential().Password
Node "WebServer"
{
#Install the required IIS features
WindowsFeature WebServer
{
Ensure = "Present"
Name = "Web-Server"
}
WindowsFeature WebFiltering
{
Ensure = "Present"
Name = "Web-Filtering"
}
WindowsFeature WebBasicAuth
{
Ensure = "Present"
Name = "Web-Basic-Auth"
}
WindowsFeature WebWindowsAuth
{
Ensure = "Present"
Name = "Web-Windows-Auth"
}
WindowsFeature WebMgmtConsole
{
Ensure = "Present"
Name = "Web-Mgmt-Console"
}
WindowsFeature WebMgmtCompat
{
Ensure = "Present"
Name = "Web-Mgmt-Compat"
}
WindowsFeature WebNetExt45
{
Ensure = "Present"
Name = "Web-Net-Ext45"
}
WindowsFeature WebASP
{
Ensure = "Present"
Name = "Web-Asp"
}
WindowsFeature WebASPNet45
{
Ensure = "Present"
Name = "Web-Asp-Net45"
}
WindowsFeature NETFramework45ASPNET
{
Ensure = "Present"
Name = "NET-Framework-45-ASPNET"
}
WindowsFeature NETWCFHTTPActivation45
{
Ensure = "Present"
Name = "NET-WCF-HTTP-Activation45"
}
Package SCSMSSP
{
Name = "SCSM SSP"
Path = "C:\DSC\SSP\SetupWizard.exe"
ProductId = "17F5D20F-47FB-485E-8CFC-4768C3C3F460"
Arguments = "/Install:SelfServicePortal /silent /accepteula /CustomerExperienceImprovementProgram:No /EnableErrorReporting:No /SMServerName:$SCSMSDKServer /PortalWebSiteName:SCSMPortal /PortalWebSitePort:81 /PortalAccount:$Domain\$SCSMUser\$SCSMPassword"
Ensure = "Present"
LogPath = "C:\DSC\SSP\SSP_Setup.log"
DependsOn = @("[WindowsFeature]WebServer","[WindowsFeature]WebFiltering","[WindowsFeature]WebBasicAuth","[WindowsFeature]WebWindowsAuth","[WindowsFeature]WebMgmtConsole","[WindowsFeature]WebMgmtCompat","[WindowsFeature]WebNetExt45","[WindowsFeature]WebASP","[WindowsFeature]WebASPNet45","[WindowsFeature]NETFramework45ASPNET","[WindowsFeature]NETWCFHTTPActivation45")
}
}
}

Notice the Node reference?
The DSC Resources used are wrapped within a Node <Name> section.
This isn't mandatory, if you're only using this to configure a single server, but as a side effect of using Plain Text password and Azure Automation DSC this is required.

N.B. Thanks to @bgelens for pointing me at that requirement as I couldn't get it to work!!!


So I mentioned you can't just import and compile this within the Azure Portal.
You can still import it via the console, so go ahead and open your Azure Automation account | Click DSC Configurations | Add a Configuration | Browse to your Config File | Click OK.


PowerShell code to compile the DSC Configuration:

$ConfigData = @{
AllNodes = @(
@{
NodeName = "*"
PSDscAllowPlainTextPassword = $True
}
)
}
$Parameters = @{
"SCSMSDKSERVER" = "PONSCSM04"
"DOMAIN" = "PowerON"
}
$ResourceGroup="xxxxx"
$AccountName="xxxxx"
$ConfigurationName="xxxxx"
Login-AzureRmAccount
Start-AzureRmAutomationDscCompilationJob -ResourceGroupName $ResourceGroup -AutomationAccountName $AccountName -ConfigurationName $ConfigurationName -ConfigurationData $ConfigData -Parameters $Parameters

Main thing is the PSDscAllowPlainTextPassword. This flags the config to allow us to store the password in plain text within the MOF that gets downloaded to the DSC node, which we're doing by pushing the plain text password from the PSCredentialObject into a variable. 
(N.B. See update note below)

Make sure you replace the $ResourceGroup, $AccountName, $ConfigurationName with relevant variables as well as the Prameters (SCSMSDKServer & Domain).

All that is left is to assign this configuration to a node and sit back and watch the SCSM Portal install.
I've not covered that piece in this post, but will have a "part 2" soon, along with a quick video showing the process end to end.

Now read Part 2 - http://www.systemcenter.ninja/2015/12/using-azure-automation-dsc-to-configure_23.html


** Updated 23/12/2015 **
Minor revision to installation command as I realised it wasn't using the RTW command line.  Replaced SDKServerName with SMServerName and added PortalWebSiteName switches.

**Updated 23/12/2015 **
Joe from the Azure Automation team left a comment regarding the transfer of the MOF file is fully encrypted, and I must admit I didn't realise that WMF5 also encrypted the MOF locally so any worries of plain text passwords isn't really a worry at all!