August 3rd, 2016 by Adam Najmanowicz | 33 Comments
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
}
}
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 »
Recently 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.
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.
Since 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 »
November 9th, 2014 by Adam Najmanowicz | 57 Comments
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.
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.
October 25th, 2014 by Adam Najmanowicz | 75 Comments
Creating reports is probably a task that every developer dread. I for once always felt like listening to Tennessee Ernie Ford?s ?16 Tons? every time when I was supposed to do it for yet another project audit ? especially this part resonated with me:
I was born one mornin’ when the sun didn’t shine
I picked up my shovel and I walked to the mine
I loaded sixteen tons of number nine coal
And the straw boss said “Well, a-bless my soul”
While the Advanced System Reporter gets you a long way, I’ve found that there were still many scenarios where I would have to write the reports by hand. Madness? Fast forward to Sitecore PowerShell Extensions (or SPE for short) it actually this doesn?t have to be like that and creating reports can be both quick and fun ? provided you?re going to use the module.
I?ve decided to 1-up the game from my previous post and zip something that isn?t really a real file but rather a blob in a Sitecore database. The script below is based heavily on the last post but instead of just zipping content of a flat folder traverses the Sitecore item tree and zips all files beneath the current folder.
There was a breaking change in the Console 2.1, if you’re using version 2.1 or newer use Download-File commandlet instad of the “Get-File” as shown in the code below.
You might have have found yourself hunting around in the Sitecore interface for something that would allow you to download all the the log files in a fast and convenient way once time or another. Have you found one? Me neither? but luckily I had the PowerShell console installed on my server so I started looking for a script to zip all files in a folder and luckily because we have a full PowerShell power in the box I could stand on the shoulders of giants and get the zipping part from Stack Overflow ? again (which is the majority of my script. The rest was super easy ? just call the function and download the file?
The only meaningful lines other than the copied function that I needed to use was calling it (?ZipFiles? – naturally) and then calling the new commandlet Get-File (that was added in the version 2.0 of the console). Obviously it?s good to let the user know what?s going on and cleaning up after yourself ? hence the furniture code around those.
###########################################################################
# #
# The script zips all log4Net files and allows users to download the zip. #
# It will show errors for logs currently opened by Sitecore for writing. #
# #
###########################################################################
#
# The ZipFiles function is based on noam's answer
# on the following Stack Overflow's page: http://bit.ly/PsZip
#
function ZipFiles( $zipArchive, $sourcedir )
{
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, `
Culture=neutral, PublicKeyToken=31bf3856ad364e35") | Out-Null
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, `
[System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite)
$in = gci $sourceDir | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files) {
$fileName = [System.IO.Path]::GetFileName($file);
$partName=New-Object System.Uri($file, [System.UriKind]::Relative)
$part=$ZipPackage.CreatePart("/$fileName", "application/zip", `
[System.IO.Packaging.CompressionOption]::Maximum)
Try{
$bytes=[System.IO.File]::ReadAllBytes($file)
}Catch{
$_.Exception.ErrorRecord.Exception
}
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$ZipPackage.Close()
}
# Get Sitecore folders and format the zip file name
$dateTime = Get-Date -format "yyyy-MM-d_hhmmss"
$dataFolder = [Sitecore.Configuration.Settings]::DataFolder
$logsFolder = [Sitecore.Configuration.Settings]::LogFolder
$myZipFile = "$dataFolder\logs-$datetime.zip"
# Warn that the used log files will fail zipping
Write-Host -f Yellow "Zipping files locked by Sitecore will fail." -n
Write-Host -f Yellow "Files listed below were used."
# Zip the log files
ZipFiles $myZipFile $LogsFolder
#Download the zipped logs
Get-File -FullName $myZipFile | Out-Null
#Delete the zipped logs from the server
Remove-Item $myZipFile
PS. The hardest part of the blog was to find and theme a nice image for it
There are 2 more ways I?ve managed to find and implement that you can control data sources with PowerShell:
rendering data source roots
rendering data source itself
The motivation would be similar to what I?ve described in the ?Part 1? blog post. So without further ado let?s cut to the meat?
Rendering Data Source Roots
You might want your roots to be dynamic and you can deliver those using a PowerShell script!
Sitecore allows you to specify a place in the content tree where content for your rendering or sublayout can be selected from. More over it allows you to specify more than one of those roots. What?s even greater ? this is done through a pipeline defined in web.config, which means we can hook into it with? PowerShell!
A cool part of the experience is that you can have multiple roots, which means that your scripts can be more liberal in what roots they expose.
January 29th, 2013 by Adam Najmanowicz | 42 Comments
A while ago Jakob suggested that putting the Sitecore PowerShell Console in Visual Studio might not be a bad idea. He even provided me with the boilerplate code that served as a stub for the module (Thanks a million Jakob!).
So after some struggling on my part the new module is now on the Sitecore Marketplace. There is really not much to write about. If you like PowerShell and Sitecore Rocks you will find it pretty neat. Otherwise I?m afraid those are not the droids you are looking for
Basically what it does is: it allows you to enjoy PowerShell automation while still skipping the web interface (that effectively is why you?re using rocks, right?).
Installation is fairly straightforward. Once you download the zip file ? unpack it somewhere on your drive and run the install.bat within it. Once you restart your Visual Studio you?ll be able to do the following:
Which should result in the following outcome:
Feel free to contact me or post your questions as a comment below.