Sitecore 10 for developers

Sitecore 10 bring in loads of exciting new things for developers the more important in my opinion are:

  • asp.net core
  • Serialization CLI + VS Addon
  • Horizon UI
  • Containers

Due to my MS developer background, asp.net core is the more exciting news for me and confirm the maturity of Sitecore as an headless CMS

these two drawings explain high level asp.net core architecture

As you can see there is a clear decoupling in term of hosting from the custom code and the Sitecore instance that provide a set of services to a variety of web sites / apps etc..

When should you use asp.net core? I am leaving Sitecore to respond with one of their slides….

further info…

and

Sitecore CLI is the new serialization engine that is going to replace Unicorn and TDS, it comes with a CLI and a VS add-on I have tested it and I am looking forward to get it within my deployment pipeline…

further info:

Get To Know an MVP – Stelio Di Bello

Recently has been recorded a podcast where I talk with Tamas Varga about my Siteore journey, here you can find the link on CoreSampler website to listen the PodCast:

https://coresampler.fm/91

and here you can find a transcript of the conversation with Tamas:

Tamas:  Hi Stelio, please introduce yourself 

Stelio: My name is Stelio Di Bello, I am originally from south Italy and I moved to the UK thirteen years ago.

At the beginning of my career I have worked for Microsoft consulting services and I became a regional expert on Microsoft Commerce Server, the father of Sitecore Commerce…
Nowadays I work for my own company that’s an independent Sitecore consultancy, I work as technical architect and, I truly enjoy technology.
In my free time I am also an international Bridge player and I like to experiment with technology exploring conversational interfaces such as Amazon Alexa and face rekognition.
I work for big / enterprise clients within different industries and multimillion ecommerce websites. In my engagements, I do not work only with Sitecore but with with a variety of web technologies such as Akamai, Azure, AWS, FrontEnd development, Google Analytics, Tag Managers, Tracking & Optimisation products and everything else MarTech related…

Thanks to Sitecore, my work gravitates between IT & Marketing trying to deliver world class performing website in a very agile & flexible way of working to keep marketing department happy…
I have been awarded Sitecore MVP in the technology category for 6 years in a row.

Tamas: When did you join the Sitecore Community? 

Stelio: I have always been a big fan of Microsoft Content Management Server 2002 and I have actually, never felt in love with Sharepoint…
First time that I have heard about Sitecore was in 2009, when I was considering on a project to replace Sharepoint with Sitecore 6.2, in the end sadly we decided to keep Sharepoint… few years later following to that parenthesis I have done my first Sitecore 6.5 project and, after that  I have not been able to leave Sitecore world anymore… Within these years, I have been involved in several crazy and exciting projects… once a  Formula 1 client asked me to build a website from scratch in just three weeks from Wireframes to deployemnt, and I did it..  in the end, the website won a Sitecore experience award for marketing agility…
Within these years, I am always been a keen blogger and in my engagements, I do a lot of evangelism to other developers about Sitecore new versions / new functionalities and the best way to leverage the full Sitecore potential, such as personalization and testing capabilities.

Tamas: What do you find the most appealing in the Sitecore Community?

Stelio: When you are a developer and you are facing a problem and go on line searching for a solution and you find the exact answers to your problem on Stack exchange or on a blog post that is the moment that you realize that you have to give back…  share your experience so that other people can benefit from your learning and experience as you are learning from other people… I also quite enjoy attending Sitecore events in person, such as Sitecore user groups in London or SugCon Europe, meeting with other community members to share experiences and make friends keeps it fun and real

Tamas: What is your suggestion for someone would like to be an MVP? 

Stelio: I would recommend to everybody to follow their passion and share their experiences in any format that they find appropriate, it could be a blog, or a youtube video, a project on github or a module on marketplace…. every contribution is valuable to the community and everybody has to be able to express in the way that they feel more comfortable doing it…  the more important suggestion is to be passionate about technology and enjoy Sitecore…

Tamas: What is your favorite motivational quote?

Stelio: My favorite quote is:

simplicity is the ultimate sophistication” from Leonardo da vinci

I truly believe that often keeping it simple and effective is the key to success…

I often find situations where we are asked for perfect solutions that end up building unrequired complexity, often I see clients who wants to have way too many non production environments and end up spending loads of money on it…

don’t do it! keep it simple and effective and enjoy Sitecore!

Compilation optimization for Sitecore CD on Azure Paas

I have seen in few instances deployed on Azure PAAS an issue with recompilation leading to the app pool restart…

my recommendation for the <compilation> tag in the web.config is to add the following attribute numRecompilesBeforeAppRestart=”100″

this attribute will prevent restarting when it reaches 10 recompilations (note that 10 is the default value in case you do not specify it)

Note that hosting your instance in Azure PAAS I have seen this issue in several instances…

<compilation defaultLanguage="c#" debug="false" targetFramework="4.6.2" numRecompilesBeforeAppRestart="100"/>

view raw
web.config
hosted with ❤ by GitHub

 

Disable FileSystem watchers to improve Sitecore stability on Azure PAAS Best Practice

I have seen few Sitecore instances deployed on Azure having issues with the filesystem watcher forcing the instance to restart, however in my experience file system watchers are not very useful since code got change only within the deployments…

Best way to ensure if you are experiencing any issue is to check your Sitecore logs and find the reason for the restart of your webapp… if the reason for restart points you to the file system changes, I would suggest applying the following patch to stabilize your sitecore instance…

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&gt;
<sitecore>
<settings>
<setting name="Media.FileSystemWatcher.BufferSize" value="16384" >
</setting>
</settings>
<watchers>
<patch:delete />
</watchers>
<mediaLibrary>
<watcher>
<ignoreList>
<patch:delete />
</ignoreList>
</watcher>
</mediaLibrary>
</sitecore>
</configuration>

view raw
DisableWatchers
hosted with ❤ by GitHub

 

 

How to coexist Sitecore SSO AD owin with another public-facing provider

I am not sure if I have been particularly “unlucky” or if that’s going to become a common issue for Sitecore administrators but I found myself in a particular scenario where on the public website AD-B2C was used to authenticate external users and at the same time they wanted to use AD to access to the Sitecore content authoring….

the exact scenario is the following:

http://www.myclient.com –> using ADB2C to authenticate website customers

cms.myclient.com –> using AD to authenticate content authors

investigating the issue, came lear to me that there was an issue with the AD Cookies between the .AspNet.Cookies cookie issued for the CD and the cookie issued for the CM…

note that within the AD provider you cannot really change  the name of .aspnet.cookies (or at least it is not trivial to do it…)

the simplest solution that I come up with was to clear this cookie on the Sitecore login page so that I can ensure that Sitecore CMS AD provider won’t be confused with the cookie issued from the CD server…

<script runat="server">
//This snippet goes into sitecore/login/default.aspx
protected override void OnPreInit(EventArgs e)
{
if (Request.Cookies[".AspNet.Cookies"] != null)
{
//Force expiration of SSO cookie on .yourclient.com domain
HttpCookie myCookie = new HttpCookie(".AspNet.Cookies");
myCookie.Expires = DateTime.Now.AddDays(1d);
myCookie.Domain = "yourclient.com"; // !!!!
Response.Cookies.Add(myCookie);
}
}
</script>

view raw
default.aspx
hosted with ❤ by GitHub

UserName Overwrite with Azure AD – SSO for Identity server

As you probably know, Sitecore is shipping from version 9.1 with the Identity server….

If you want to integrate Sitecore with Azure Active Directory, this resource will walk you through the configuration step by step:

https://sitecore.derekc.net/setting-up-azure-active-directory-integration-with-sitecore-identity-server-sitecore-9-1/

However once you have followed all the steps, you will have an unpleasant surprise when you discover that the Sitecore UserName is mapped with some random unfriendly characters…

randomusername

userlist

As you can probably agree, this is not very user-friendly since the user-name is used in the item version history and within the workflows…

versionhistory

this code snippet will help you to use as user-name, either for the email address as username or the cleaned name of the active directory user…

usermapped

sitecoreauthor

using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Sitecore.Diagnostics;
using Sitecore.Owin.Authentication.Configuration;
using Sitecore.Owin.Authentication.Identity;
using Sitecore.Owin.Authentication.Services;
using Sitecore.SecurityModel.Cryptography;
namespace XXXXX.Foundation.SSO.UserBuilders
{
public class XXXExternalUserBuilder : DefaultExternalUserBuilder
{
public XXXExternalUserBuilder(ApplicationUserFactory applicationUserFactory, IHashEncryption hashEncryption) : base(applicationUserFactory, hashEncryption) { }
protected override string CreateUniqueUserName(UserManager<ApplicationUser> userManager, ExternalLoginInfo externalLoginInfo)
{
Sitecore.Diagnostics.Log.Debug("CreateUnique UserName",this);
if (externalLoginInfo != null)
{
if (!string.IsNullOrWhiteSpace(externalLoginInfo.Email))
{
return externalLoginInfo.Email;
}
else
{
Sitecore.Diagnostics.Log.Debug("empty Email", this);
Sitecore.Diagnostics.Log.Debug("default username " + externalLoginInfo.DefaultUserName, this);
var validUserName = externalLoginInfo.DefaultUserName.Replace(",", "");
return "sitecore\\" + validUserName.Replace(" ", "");
}
}
Sitecore.Diagnostics.Log.Error("null UserInfo when creating UserName", this);
return "nullUserInfo";
}
}
}

view raw
ADUserBuilder.cs
hosted with ❤ by GitHub

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:localenv="http://www.sitecore.net/xmlconfig/localenv">
<sitecore localenv:require="uat or prd" role:require="Standalone or ContentDelivery or ContentManagement">
<federatedAuthentication>
<identityProvidersPerSites hint="list:AddIdentityProvidersPerSites">
<!– Defines a list of providers assigned to all sites. –>
<mapEntry name="all sites" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
<!–
The list of site names for which the specified identity providers will work.
Note: the fedauth.siteNameExpander pipeline processes each site name, which gives the ability to use expressions like
"regexp:modules_.*" or "database:web" or "domain:extranet"
–>
<sites hint="list">
<site>regexp:.*</site>
</sites>
<externalUserBuilder type="XXXX.Foundation.SSO.UserBuilders.XXXXExternalUserBuilder, XXXX.Foundation.SSO" resolve="true">
<IsPersistentUser>true</IsPersistentUser>
</externalUserBuilder>
</mapEntry>
</identityProvidersPerSites>
<propertyInitializer>
<maps>
<map name="set IsAdministrator" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
<data hint="raw:AddData">
<source name="http://www.sitecore.net/identity/claims/isAdmin" value="true" />
<target name="IsAdministrator" value="true" />
</data>
</map>
<map name="set Email" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
<data hint="raw:AddData">
<source name="email"/>
<target name="Email"/>
</data>
</map>
<map name="set FullName" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
<data hint="raw:AddData">
<source name="name"/>
<target name="FullName"/>
</data>
</map>
</maps>
</propertyInitializer>
</federatedAuthentication>
</sitecore>
</configuration>

Celebrating my 200th post

I am happy to celebrate with you my 200th blog post and still counting…

This year has been a great year for the Sitecore community having fun with Sitecore 9 & DevOps… in case you have missed I would suggest you take a look at my posts talking about Azure, Powershell, Gulp, Helix and best way to build your deployment pipeline…

https://sitecorecommerce.wordpress.com/2019/12/03/removing-gulp-from-your-ci-pipeline-for-helix-style-solution-with-powershell/

https://sitecorecommerce.wordpress.com/2019/12/02/copying-unicorn-files-with-powershell-for-azure-pipeline-within-an-helix-style-solution-without-gulp/

https://sitecorecommerce.wordpress.com/2019/11/02/powershell-to-publish-helix-base-solution-with-visualstudio-2019-without-gulp/

https://sitecorecommerce.wordpress.com/2019/11/19/sitecore-9-2-powershell-using-arm-template-for-azure-paas/

https://sitecorecommerce.wordpress.com/2019/10/25/sitecore-9-2-dev-environment-setup/

 

 

Removing Gulp from your CI Pipeline for Helix style solution with PowerShell

As previously discussed, if you have an Helix style solution, and you want to replace Gulp with PowerShell this script can come quite useful…

The principle is not to use Gulp for Build and packaging neither on your local environment (see this other post to see how to do it: https://sitecorecommerce.wordpress.com/2019/11/02/powershell-to-publish-helix-base-solution-with-visualstudio-2019-without-gulp/

neither on your Build server / Azure Pipeline….

as you can imagine PowerShell is your friend 🙂

In my specific example, I have instrumented it with VS 2017 but this script would work with any version of MS Build assuming that all parameters are supported….

BuildAndPublish

The principle is a pretty simple loop through all the project in Feature / Foundation / Project and just calling a simple MSBuild command to publish the project within my Temp folder….  Msbuild will build each project, and publish each project copying the Bin / Views / and configs in the Temp folder keeping your solution structure…

Once you have the temp folder, you can then Zip the package and use to deploy on your Sitecore instance…

Write-Host $Env:BUILD_SOURCESDIRECTORY
$foundationPath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Foundation"
Write-Host "found path $foundationPath"
$featurePath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Feature"
Write-Host "found path $featurePath"
$projectPath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Project"
Write-Host "found path $projectPath"
$tempOutputfolder = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/temp"
Write-Host "Temp fold $tempOutputfolder"
$msBuildExe = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe"
Write-Host "Trying to get build file $msBuildExe"
Write-Host "Trying to build into $Env:BUILD_ARTIFACTSTAGINGDIRECTORY "
Write-Host "Trying to get build dir $Env:AGENT_BUILDDIRECTORY"
if ((Test-Path $foundationPath) -eq $True) {
$foundationProjects = Get-ChildItem $foundationPath Recurse Include *.csproj
foreach ($projectFile in $foundationProjects) {
if ($projectFile -notlike "*Tests*")
{
Write-Host "Foundation $projectFile "
#$testproj = $projectFile
& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=release /p:PublishUrl=$tempOutputfolder
#& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=debug /p:PublishUrl=$publishTarget -v:q -nologo -clp:NoSummary > null
#if ($LastExitCode -ne 0) {
# Write-Host "Build failed for" $projectFile -foregroundcolor Magenta
# exit
#}
}
}
}
if ((Test-Path $featurePath) -eq $True) {
$featureProjects = Get-ChildItem $featurePath Recurse Include *.csproj
foreach ($projectFile in $featureProjects) {
if ($projectFile -notlike "*Tests*")
{
Write-Host "Feature $projectFile "
& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=release /p:PublishUrl=$tempOutputfolder
#& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=debug /p:PublishUrl=$publishTarget -v:q -nologo -clp:NoSummary > null
#if ($LastExitCode -ne 0) {
# Write-Host "Build failed for" $projectFile -foregroundcolor Magenta
# exit
#}
}
}
}
if ((Test-Path $projectPath) -eq $True) {
$projectPathProjects = Get-ChildItem $projectPath Recurse Include *.csproj
foreach ($projectFile in $projectPathProjects) {
if ($projectFile -notlike "*Tests*")
{
Write-Host "Project $projectFile "
& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=release /p:PublishUrl=$tempOutputfolder
#& "$($msBuildExe)" "$($projectFile)" /m /nr:false /p:DeployOnBuild=true /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:Configuration=debug /p:PublishUrl=$publishTarget -v:q -nologo -clp:NoSummary > null
#if ($LastExitCode -ne 0) {
# Write-Host "Build failed for" $projectFile -foregroundcolor Magenta
# exit
#}
}
}
}

 

Copying Unicorn Files With PowerShell for Azure Pipeline within an Helix style solution without GULP

In the case, you have an Helix style solution, you are using Unicorn and you use Azure Dev ops as your build pipeline to publish your solution on Azure PAAS and you want to use Gulp only for styles and scripts manipulations…

you will definitively need this snippet since you probably have already encountered this problem within your Build Pipeline…

The principle is pretty simple, you need to copy your YML files and keep all the folder structure within serialization… within the App_Data/Unicorn folder within a website Temp folder that you will later zip with the rest of Bin and Views so that you can install your changes once the package is deployed across the environment…

This is done within the Gulp – Package task typically, but if you want to get rid of it, I would recommend doing a separate PowerShell Task just to copy Unicorn files…

copyunicorn

The content of the Powershell is pretty simple and copy the files keeping your serialization structure across Feature, Foundation, Project folders…

Write-Host "Copying files for Unicorn into App_Data/unicorn keeping your Unicorn folder structure !!!!!"
Write-Host $Env:BUILD_SOURCESDIRECTORY
$foundationPath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Foundation"
Write-Host "found path $foundationPath"
$featurePath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Feature"
Write-Host "found path $featurePath"
$projectPath = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/src/Project"
Write-Host "found path $projectPath"
$tempOutputfolder = Join-Path Path $Env:BUILD_SOURCESDIRECTORY ChildPath "Website/temp"
Write-Host "Temp fold $tempOutputfolder"
$unicornDatafolder = Join-Path Path $tempOutputfolder ChildPath "App_Data/unicorn"
New-Item ItemType directory Path $unicornDatafolder
$unicornfeaturefolder = Join-Path Path $unicornDatafolder ChildPath "Feature"
$unicornfoundationfolder = Join-Path Path $unicornDatafolder ChildPath "Foundation"
$unicornprojectfolder = Join-Path Path $unicornDatafolder ChildPath "Project"
New-Item ItemType directory Path $unicornfeaturefolder
New-Item ItemType directory Path $unicornfoundationfolder
New-Item ItemType directory Path $unicornprojectfolder
$testproj =""
if ((Test-Path $foundationPath) -eq $True) {
$foundationProjects = Get-ChildItem $foundationPath Recurse Directory Include *serialization*
foreach ($serFolder in $foundationProjects) {
if ($serFolder -notlike "*Tests*")
{
Write-Host "Foundation $serFolder "
$featurename = (get-item $serFolder ).parent.Name
$unicornfoundSubfolder = Join-Path Path $unicornfoundationfolder ChildPath $featurename
New-Item ItemType directory Path $unicornfoundSubfolder
Copy-Item $serFolder Destination $unicornfoundSubfolder Recurse
}
}
}
if ((Test-Path $featurePath) -eq $True) {
$featureProjects = Get-ChildItem $featurePath Recurse Directory Include *serialization*
foreach ($serFolder in $featureProjects) {
if ($serFolder -notlike "*Tests*")
{
Write-Host "Feature $serFolder "
$featurename = (get-item $serFolder ).parent.Name
$unicornfeatSubfolder = Join-Path Path $unicornfeaturefolder ChildPath $featurename
New-Item ItemType directory Path $unicornfeatSubfolder
Copy-Item $serFolder Destination $unicornfeatSubfolder Recurse
}
}
}
if ((Test-Path $projectPath) -eq $True) {
$projectPathProjects = Get-ChildItem $projectPath Recurse Directory Include *serialization*
foreach ($serFolder in $projectPathProjects) {
if ($serFolder -notlike "*Tests*")
{
Write-Host "Project $serFolder "
$featurename = (get-item $serFolder ).parent.Name
$unicornfeatSubfolder = Join-Path Path $unicornprojectfolder ChildPath $featurename
New-Item ItemType directory Path $unicornfeatSubfolder
Copy-Item $serFolder Destination $unicornfeatSubfolder Recurse
}
}
}

view raw
CopyUnicorn.ps1
hosted with ❤ by GitHub

Disaster Recovery region in Azure for Sitecore 9.x

In case you are worried about an Azure region going down and want to make your Sitecore Azure infrastructure not dependent on a single region, deploying a region for disaster recovery could be an option…

Obviously, depending on the complexity of your website, Sitecore resilience may be the minor problem in case of a region failure and further conversation should be taken to ensure that your infrastructure and data can be available across multiple regions….

As you can imagine, if your site is relying on Sitecore Analytics for personalization features your task won’t be trivial due to the Sitecore architecture, however, is a fair assumption and common practice to have analytics turned off on the DR region…

A typical DR region for Sitecore, would need the following elements:

  • Content Delivery server
  • WebDatabase
  • Redis cache (you could consider switching off if budget is an issue)
  • Search (assuming that is mandatory to have search available in case of DR)

My recommendation to provision a DR region on Azure PAAS would be to use the XM scaled scripts to provision a new environment in your favourite “backup” region and then delete the unrequired resources:

  • Identity server
  • Content Management Server
  • Master Database

The following Powershell script shows how to run the clean up of these resources…

$Name = "ResourceGroupNamePrefix"
$location = "West Europe"
$AzureSubscriptionId = "XXXXXXXXXXXXXXXXXXXXXX"
#region Service Principle Details
$UseServicePrincipal = $false
$TenantId = "XXXXXXXXXXXXXX"
$ApplicationId = "SERVICE_PRINCIPAL_APPLICATION_ID"
$ApplicationPassword = "SERVICE_PRINCIPAL_APPLICATION_PASSWORD"
#endregion
Write-Host "Setting Azure RM Context…"
Write-Host "Subscriptionid $AzureSubscriptionId "
if($UseServicePrincipal -eq $true)
{
#region Use Service Principle
$secpasswd = ConvertTo-SecureString $ApplicationPassword -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($ApplicationId, $secpasswd)
#Login-AzureRmAccount -ServicePrincipal -Tenant $TenantId -Credential $mycreds
Set-AzureRmContext -SubscriptionID $AzureSubscriptionId -TenantId $TenantId
#endregion
}
else
{
#region Use Manual Login
try
{
Write-Host "inside try"
Set-AzureRmContext -SubscriptionID $AzureSubscriptionId
}
catch
{
Write-Host "inside catch"
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionID $AzureSubscriptionId
}
#endregion
}
Write-Host "Check if resource group already exists…"
$notPresent = Get-AzureRmResourceGroup -Name $Name -ev notPresent -ea 0
if (!$notPresent)
{
Write-Host "Resource group $Name not present in $location "
}
#Start the proper clean up JOB!!!!
$CMName = $Name+ "-cm"
$SiName = $Name+ "-si"
$MasterDbName = $Name+ "-master-db"
$SqlDbName = $Name+ "-sql"
Write-Host "CM name $CMName"
Write-Host "SI name $SiName"
try
{
$SiRes = Get-AzureRmResource -ResourceName $SiName -ResourceGroupName $Name -ResourceType Microsoft.Web/sites
if ($SiRes)
{
Write-Host "SI ID $SiRes.ResourceId"
Remove-AzureRmResource -ResourceName $SiName -ResourceGroupName $Name -ResourceType Microsoft.Web/sites
}
}
catch { Write-Error $_.Exception.Message
}
try
{
$cmRes = Get-AzureRmResource -ResourceName $CMName -ResourceGroupName $Name -ResourceType Microsoft.Web/sites
if ($cmRes)
{
Remove-AzureRmResource -ResourceName $CMName -ResourceGroupName $Name -ResourceType Microsoft.Web/sites
}
}
catch { Write-Error $_.Exception.Message
}
Remove-AzureRmSqlDatabase -ResourceGroupName $Name -DatabaseName $MasterDbName -ServerName $SqlDbName
Write-Host "Deployment Complete."
}
catch
{
Write-Error $_.Exception.Message
Break
}

view raw
DRRegionCleanUp
hosted with ❤ by GitHub