App settings in environment variables in Sitecore.

Creating back-end integrations is inevitably linked with having to authenticate against a remote endpoint. Be that a Rest API, FTP or an APM – secrets (credentials, api tokent, shared secrets) of some sort will be involved in the process.

Those credentials must be stored somewhere. At this point I hope no one even considers hardcoding those but even if you extract them to configuration – having them exposed in your repository may be a bad idea and is frowned upon by tools like SonarQube.

You would be encouraged to access those secrets by having them anchored against web.config appSettings section such as:

<appSettings>
  <add key="EmailReminder.FromAddress" value="[email protected]" />
  <add key="Foundation.RemoteApi.AccessKey" value="" />
  ...
</appSettings>

This is because you can easily and conveniently edit such settings in Azure portal. Arguably you could also do this using connection strings, but those are not full connection strings we’re dealing with…

You cannot keep them in a dev only patch file as this section is not patchable with standard Sitecore practices… So for a long time, we just kept empty placeholders this list in web.config and when you needed to work with a specific integration point you scrambled to find the credentials and struggled with them being wiped when the project was published.

This is handled elegantly in .Net Core OOTB as they can cascade from environment variables, but somehow despite decades of aggregated Sitecore experience in the team we just kept doing it.

Yesterday morning something in me broke… I’ve had enough! Decided that we need a proper reusable solution that would not be harder than sharing a file with the necessary secrets between developers.

I sat down with the intention of writing something that would just let me use environment variables. This way we still don’t have to store them in the repository, and they don’t get wiped when an app is republished (akin to how it works in Azure.

Let’s see what we’re dealing with…

So the xml had some AppSettings builder OOTB that maybe I could reuse/inherit in some capacity…

<appSettings configBuilders="SitecoreAppSettingsBuilder">
  <add key="EmailReminder.FromAddress" value="[email protected]" />
...
</appSettings>

SitecoreAppSettingsBuilder looked curiously like what I wanted to do…

  <configSections>
    <section name="sitecore" type="Sitecore.Configuration.RuleBasedConfigReader, Sitecore.Kernel" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, Sitecore.Logging" />
    <section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false" />
  </configSections>
  <configBuilders>
    <builders>
      <add name="SitecoreAppSettingsBuilder" mode="Strict" prefix="SITECORE_APPSETTINGS_" stripPrefix="true" type="Sitecore.Configuration.FlexibleEnvironmentConfigBuilder, Sitecore.Kernel" />
      <add name="SitecoreConnectionStringsBuilder" mode="Strict" prefix="SITECORE_CONNECTIONSTRINGS_" stripPrefix="true" type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Environment, Version=1.0.0.0, Culture=neutral" />
    </builders>
  </configBuilders>

I started investigating the classes, which looked intriguing, something didn?t feel right. Then it struck me?Sitecore already provided all the configuration builders for the job… undocumented…

The least buggy, most hassle-free code is the one you never write

There is no code to write here, when dealing with app settings defined in the main web.config <appSettings> section (not patchable by the usual sitecore Sitecore-specific configs), such as:

<add key="Foundation.RemoteApi.AccessKey" value="" />

We can use environment variables with a prefix SITECORE_APPSETTINGS_. For instance, the setting above could be stored in the following environment variable:

SITECORE_APPSETTINGS_Foundation.RemoteApi.AccessKey

Handling Environment Variables in IIS

Since environment variables are fixed at application startup, you can?t use a newly modified variable immediately. Unfortunately, even recycling the application wasn?t enough in my case. I had restart IIS for them to take:

iisreset /stop
iisreset /start

Automating the Process

To streamline this, I created short PowerShell script that globally sets all required variables. Here are some key points about the script:

  • No repo storage: This script isn?t stored in the repository, but we can share it securely via direct messaging or other private channels.
  • Elevated privileges: If you run it without admin rights, it will prompt you for confirmation and relaunch itself with elevated privileges.
  • Environment-specific values: The script can easily be populated by keys we store in Azure app settings.
  • IIS restart: It handles the IIS restart automatically.

Checking App Settings in Sitecore

To verify the value of an appSetting in Sitecore, open Sitecore Desktop, launch PowerShell ISE, and run the following one-liner, replacing the variable name with the one you want to check:

[System.Web.Configuration.WebConfigurationManager]::AppSettings["Foundation.RemoteApi.AccessKey"]

PowerShell Script: Simplified and Ready

Below is the script I mentioned earlier:

# Check if the script is running as Administrator
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "The script is not running with administrative privileges. Relaunching as Administrator..."
    
    # Get the current script's full path
    $scriptPath = $MyInvocation.MyCommand.Path

    # Create a new PowerShell process as Administrator
    Start-Process -FilePath "powershell.exe" -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -Verb RunAs

    # Exit the current non-admin script
    exit
}

# Code below runs with administrative privileges
Write-Host "Script is running with administrative privileges."

function Set-SitecoreAppSetting {
    [CmdletBinding()]
    param (
        [Parameter(Position=0, Mandatory=$true)]
        [string]$VariableName,
        
        [Parameter(Position=1, Mandatory=$true)]
        [string]$VariableValue
    )
    process {
        Write-Host "Setting variable `"SITECORE_APPSETTINGS_$VariableName`" to value `"$VariableValue`""
       [System.Environment]::SetEnvironmentVariable("SITECORE_APPSETTINGS_$VariableName", $VariableValue, [System.EnvironmentVariableTarget]::Machine)
    }
}

# store your variables below - to speed up onboarding your colleagues...

Set-SitecoreAppSetting "VariableName1" 'VariableValue1'
Set-SitecoreAppSetting "VariableName2" 'VariableValue2'

Conclusion

This approach eliminates the need for any custom code while leveraging Sitecore?s built-in capabilities. The PowerShell script provides a clean way to manage environment variables without hardcoding sensitive details, and it ensures a consistent setup across the team. I hope this solution simplifies your workflow as much as it has mine!

Posted in Uncategorized
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...
| Leave a Comment »

I’ve received this nice comment on one of my earlier posts and I thought it might warrant a blog post since it is a nice little challenge and might be useful for more scripters in our community.

Hi Adam,

thanks for the pointers on PowerShell! There’s one in particular I’m hoping to get some help with, if that’s ok? I have created a Branch Template in Sitecore, and I want to deploy it under every item in the Content Tree that uses one particular page template (about 200 instances of deployment, in this case). For an added bit of fun, there will be several different language versions being deployed along the way, so I guess that prevents me doing a blanket rollout. Could you please recommend a script that is along the lines of “Add this Branch Template under this Item ID in the following named language codes”? I realise I would then be repeating that line 200 times with varying parent item ID and languages, but I can live with that if that’s the easiest way to do it.

Many thanks for your help!
Phil Neale

First let’s set up a bit of a folder structure for our PoC.

#Clean-up after previous run
Remove-Item master:\content\branch-test -ErrorAction SilentlyContinue -Recurse -Force

#Create a folder strcture for our tests
New-Item master:\content\ -Name "branch-test" -ItemType "Common/Folder"

foreach($i in 1..3){

    #Create folders for items that we will serve as branch hosts
    New-Item master:\content\branch-test -Name "folder $i" -ItemType "Common/Folder" | Out-Null

    foreach($j in 1..3){

        #Create items underneath which we will be creating our branches
        New-Item "master:\content\branch-test\folder $i" -Name "branch-host $j" -ItemType "Sample/Sample Item" | Out-Null
    }
}

After this the content tree structure should look like on the following picture Read the rest of this article »

SitecorePatched The post is related to the image resize vulnerability fix introduced in Sitecore 7.5. To read more about the Sitecore fix go to the Release notes page and search for ?Media request protection?. While I was holding off for a number of months on the publication of the post as it puts the attack vector in plainer sight that I would like it to be (while the community figured out how to work with Media Resizing in a neat way) – but recently I’ve seen voices raised considering turning the Media Request protection off which I hope you will not be doing after reading this post. The post will also tell you how to enable such security on your older versions of Sitecore.

So here’s the story…. At some point in Cognifide we have performed a research around Sitecore security and one of my colleagues (Marek)  found out that you could easily kill any Sitecore instance by performing an image resize attack on it. While the CMS did some rudimentary checks and limited the values of height and width you could still perform an attack by harvesting the images from the site and perform multiple parallel & iterative size increase or just plain use the scale parameter to achieve any image size. A result of such attack would be a a denial of service due to 100% CPU & memory usage and would potentially allow for filling the server drive by creating the endless number of scaling calls.

Marek was even kind enough to provide a proof of concept code that confirmed the hypothesis by performing attack on a few of our internal servers. The program would load the home page; parse to find images linked from it and perform resizing of the images in a number threads.

Psst? Mike made me add the image ? supposedly without it I?m not as cool as Stephen!

Following the discovery I’ve attempted to remedy the problem and as a consequence came up with the solution which I have recently put on GitHub – ImageGuard which signs the rendered media links that use any of the resizing/scaling capabilities and filters all request that try to resize/scale, allowing the sizing only when the hash matches and provided it to Sitecore.

This solution is nowhere as complete as the one that was later provided by Sitecore – starting from version 7.5 ? still I think it?s still worth making it public to allows for older versions of Sitecore to be guarded against this type of attacks. Read the rest of this article »

shoot_out_of_cannon_400_clr_13993In one of my previous posts I described how to create reports in Sitecore PowerShell Extensions (SPE for short) that allow you to leverage the joint power of Sitecore and PowerShell to deliver complete and elegant reports in little to no time. In this post I?ll tell you how to take this a step further and operationalize them into full blown Sitecore Desktop applications.

The secret sauce is in the actions you can place on the report, the additional parameters that I haven?t mentioned in the previous post, and the use of Sitecore rules engine with some rules that come with SPE.

For the purpose of this post I will limit the scripts to samples that are (mostly) in the vanilla SPE deployment.

Let?s begin with describing the actions and how you can configure them to appear in your reports.

What are report actions?

Actions are simply commands powered by scripts and with visibility dependent on certain conditions like the .Net class of the object that is displayed or perhaps other session settings.

Action Scripts

You define an action as a script located in an SPE script library and appears in the Actions panel. In the simplest scenario the action would appear when the script library name matches the .Net class name of the items displayed. In the above scenario the actions are placed under /Platform/Internal/List View/Ribbon/Item/ where Platform is the module and Item is a script library. Let?s take a look at the script here /Platform/Internal/List View/Ribbon/Item/Open Read the rest of this article »

short_cut_400_clr_7608This post describes how you can deliver JSON/XML/HTML APIs quickly with Sitecore PowerShell Extensions.

Technically this was also available earlier but the API was not refined to the state it is now.

As Sitecore is constantly progressing from predominantly serving as a  CMS towards becoming a mobile and web application delivery platform (which is very apparent by the recent increase of SPEAK popularity, the introduction of Item Web API and the app centric nature of the new Sitecore 8 interface there is an increased need to rapidly deliver APIs for those those front end applications to work seamlessly with the CMS back-end.

PowerShell Extensions can help you with that move by enabling rapid prototyping of APIs that are either JSON or XML in nature.

How to make scripts available for the Web API?

This functionality is available in Sitecore PowerShell Extensions starting from version 2.5, however I was never happy with how it worked and how the URLs were structured. With the Modules functionality introduced in 2.8 it was a good time to model it properly for SPE 3.0.

To make a script callable through the v2 of the API you need to place it in an Enabled module in the Web API integration point library.

Read the rest of this article »

Posted in PowerShell, Sitecore, Software, Software Development, Solution, Web applications
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
Loading...
| 54 Comments »

This is just a short post to supplement the “Working with Sitecore items in PowerShell Extensions” as we now have a new cmdlet of retrieving items in SPE 3.0.

Find-Item cmdlet allows you to leverage the glorious new search API Sitecore introduced in the 7.0 version of its CMS to retrieve items using the Sitecore Content Search indexes.

You will find the available parameters on it as follows:

  • -Index – index name – ISE supports index name auto completion
  • -Where – Dynamic Linq syntax as specified in this blog
  • -WhereValues – array of objects for Dynamic Linq
  • -Where parameter. -OrderBy – Dynamic Linq syntax ordering parameter
  • -First – number of results to return -Skip – number of results to skip before returning the rest of results.
  • -Criteria – simple search criteria in the following example form:

Read the rest of this article »

Sitecore PowerShell Extensions in numbers

graph_on_grid_400_clr_9636Recently the Sitecore PowerShell Team has been reflecting on the progress of the Sitecore PowerShell Extensions (SPE) module. We appreciate all the feedback and contributions from the community. Without the many great people in the community, the module just wouldn’t be where it is today. The team is proud of the accomplishments for a module developed purely by the community with no formal Sitecore support.

The new year has revealed some exciting news out on the Marketplace for SPE.

  • 30 recommendations as of March 1st, 2015.
  • Appears on the Most Recommended list on the Marketplace home page.
  • Just last night it has also appeared on the Most Downloaded list on the Marketplace!
  • 16 ratings – average 5 stars!

The community is vocal!

If there is anything worth mentioning about the module it IS the amazing community!

From what we could find between all of us we have created over 90 articles and videos about the Sitecore PowerShell Extensions.

Together we?ve talked about he module at least at 3 conferences (both times times Sitecore Virtual User Summit was organized and again on Sitecore SUGCON)  and a number of  times on various Sitecore User Groups. There is plenty of material on YouTube when you search for Sitecore PowerShell. Especially interesting is the 9 episodes mini series on the module usage by Michael West and a comprehensive summary of the module capability by Michael Reynolds. The number of YouTube entries about SPE is now round 15 videos.

And you?re hungry for content!

Our community content reference page have been visited 9722 times over the past year with the number gradually growing to 1343 page views last month alone.

image

You?re visiting us mostly from United States, United Kingdom and India. Read the rest of this article »

join_the_puzzle_crowd_400_clr_10889Since we’ve seen some interest from developers wanting to join the Sitecore PowerShell Extensions team, I thought it might be worth documenting how my development environment is put together to allow for easier on-boarding of new members (Yes, we’re hiring! No, we can’t pay you ;) ). Maybe you just want to compile it yourself to make sure we’re not up to no good, or just plain see inside and play with it…

First of all you need to have Sitecore installed somewhere (obviously). For the purpose of examples I’ll assume your instance is located at C:\inetpub\wwwroot\Sitecore8\ and has the 3 standard folders Data, Databases and Website in them as it normally has. For that very same reason I’ll also assume that your Sitecore PowerShell Extensions project folder is located at C:\Projects\SitecorePowerShell\

1) Seed your Sitecore instance

First step that I always perform when I setup a new environment is to seed the Sitecore instance with the items required which is best done by installing the latest release of PowerShell Extensions.

2) Set up Sitecore SPE folders to use the latest files you’re working on

Since we’re likely to modify the assets like JavaScript, styles or XML Controls I want those to be automatically synchronized with changes I do in C:\Projects\SitecorePowerShell\ for this purpose I set up junction points in my Sitecore instance folder to point at my repository folder. To do this I delete the folders that were created by the install package and perform the Junction creation. Assuming the folders as they were specified before you can write a short batch file that would look like this: Read the rest of this article »

I’m really excited to see the 3.0 version of Sitecore PowerShell Extensions released. There have been more effort, love and sweat poured into this version by the whole team than I would ever expect. This blog has been written to assert the smoothest upgrade experience possible. While we’re always striving for the smoothest upgrade possible – this version introduces some changes that require you to perform a manual step or two. While those could be automated to a degree, making those manual was a conscious choice as I didn’t want to break e.g. your Insite instance that stores some of its files in the “Console” sub-folder of the Website folder.

Before upgrading your instance from Sitecore PowerShell Extensions 2.x to 3.0 please make sure you have your scripts backed up as the upgrade process might cause some of your scripts to be removed. This is especially true if you used the integration script libraries and you are upgrading from SPE 2.7 or earlier. If you’re upgrading from version 2.8 and your script live in your own modules You should be safe although it’s always smart to back up.

The steps you need to take prior or after installing the new version of the PowerShell Extensions:

You MUST delete the following folder from your sitecore Website folders:

  • \sitecore\shell\Applications\PowerShell\

IMPACT: If you will not delete that folder or the contents of that folder the PowerShell Extensions applications might no longer work or produce unexpected results

You SHOULD delete the content of the following folder:

  • \Console\Services\

IMPACT: Should you not remove the folder – the PowerShell services  might be available from both the old URL and the new URL available at: “\sitecore modules\PowerShell\Services\”

You CAN delete the following folders:

  • \Console\Assets\
  • \Console\Scripts\
  • \Console\Styles\

IMPACT: Those folders now exist under “\sitecore modules\PowerShell\” but their existence in the previous location does not have any impact other than taking space on the server,

That is pretty much it. I hope to blog about the new features shortly as there is plenty of them and the whole PowerShell Extensions team is really excited to make those available for you.

Posted in .Net Framework, PowerShell, Sitecore, Software Development, Solution, Web applications
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading...
| 33 Comments »

Introducing PowerShell Actions for Sitecore Workflows

This has been on my plate for a while and to be honest I?m not sure what took me so long as it literally took around 4 hours from start to completion which I consider a testament to how easy it is to create additional integrations with PowerShell akin to the Gutter integration or the login/logout integration Michael West has recently introduced in the platform.

creating_a_better_process_800_clr_7366

What this integration allows you to do is to eliminate the need for code deployment when you?re in need for a quick action here and there for when a user executes a workflow command.

You might find this article helpful by a Cognifide colleague of mine. I especially like this image which illustrates nicely where actions fit in a Sitecore workflow.

They are effectively little bits of code that get executed automatically when a user triggers a command.

Read the rest of this article »

Posted in Open Source, PowerShell, Sitecore, Software Development, Solution, Web applications
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading...
| 57 Comments »