Adding a Custom Http Header Using CasperJS

I was working with some web tests using CasperJS, and got the following error from the server (IIS):

HTTP Error 500.52 – URL Rewrite Module Error.
Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded (“deflate”).

I couldn’t change the server configurations, so I had to force the server to return unencoded (uncompressed) content. It turned out to be quite hard to find a solution, but the solution was just three lines of code.

In theory, setting this in the options argument to Casper should work:

var casper = require(‘casper’).create(
{
    pageSettings: {
        customHeaders: {
            ‘Accept-Encoding’: ‘identity’
        }
    }
});

But it didn’t.

Nor did passing the headers option to open(http://docs.casperjs.org/en/latest/modules/casper.html?highlight=header#open). The problem with that approach was that the header was only set to the first request, not for subsequent requests as a result of redirects.

This conversation inspired me to come up with my solution: https://github.com/n1k0/casperjs/issues/667. I simply hooked up the start event and set the header:

casper.on(‘started’, function () {
    this.page.customHeaders = { ‘Accept-Encoding’: ‘identity’ }
});

Automatically Shut Down an Azure VM

Here is a self-documenting (I hope) PowerShell script. Windows Azure PowerShell is required.

Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"
# Importing publish settings only has to be done once.
# Download from <a href="https://windows.azure.com/download/publishprofile.aspx">https://windows.azure.com/download/publishprofile.aspx</a>
# Then, run the following line:
# Import-AzurePublishSettingsFile "Path\File.publishsettings"
# Test:
Get-AzureVM -ServiceName "MyService" > C:\Users\user\Documents\StopLog.txt 2>&1
# Stop the VM:
Stop-AzureVM -Name "MyName" -ServiceName "MyService" -Force >> C:\Users\user\Documents\StopLog.txt 2>&1
# Schedule a task (using Task Scheduler) with
# Action: Start a program
# Program/script: powershell.exe
# Parameters: C:\Users\user\Documents\StopVM.ps1

Accessing SQL Server Analysis Services via HTTP

I have set up HTTP access to SQL Server Analysis Server a couple of times. It is well documented here: http://technet.microsoft.com/en-us/library/gg492140.aspx

But each time, I seem to encounter the following error when I try to add the script map: “The specified module required by this handler is not in the modules list. If you are adding a script map handler mapping, the IsapiModule or the CgiModule must be in the modules list.”

image

Here is how to solve this: In Windows Server 2012, add the ISAPI Extension feature using the Add Roles and Features Wizard (which is accessible from Server Manager):

image

Here is a PowerShell script that automates the steps 1-2 outlined in the Technet article above. (I ran into problems adding the script map using PowerShell.)

# Prerequisites: Windows PowerShell Snap-In for IIS 7.0

$filepath="C:\inetpub\wwwroot\OLAP"
$olapisapipath="C:\Program Files\Microsoft SQL Server\MSAS11.MSSQLSERVER\OLAP\bin\isapi"

New-Item -Path $filepath -ItemType directory
Copy-Item -Path "$olapisapipath\*" -Destination $filepath -Recurse
Import-Module WebAdministration
New-Item IIS:\AppPools\OLAP
Set-ItemProperty IIS:\AppPools\OLAP -Name managedPipelineMode -value Classic
Set-ItemProperty IIS:\AppPools\OLAP -Name managedRuntimeVersion -value v2.0
New-Item "IIS:\Sites\Default Web Site\OLAP" -type Application -physicalPath $filepath
Set-ItemProperty "IIS:\Sites\Default Web Site\OLAP" -Name applicationPool -Value OLAP

Access Permissions to SSAS

IIS must be granted access to query the SSAS database. If you’re using authentication, it is the IIS AppPool account that should be granted access. If you’re using anonymous, you can check the account by selecting Anonymous Authentication in IIS Manager and clicking Edit. If your IIS server is separate from your SSAS server, you must change this to a domain account.

I have put an XMLA script to create an appropriate role in SSAS on OneDrive: https://onedrive.live.com/redir?resid=DD9BE5E7B16098D7%2114485

Syncing Internet Explorer favorites using SkyDrive

I think I finally found a way to sync Internet Explorer favorites using SkyDrive. As you probably know, you can only sync one local folder (normally C:\Users\<user name>\SkyDrive). But using symbolic links, you can in fact “cheat” to make Internet Explorer use the SkyDrive folder.

First, I created a folder named Favorites in SkyDrive. Then, I started an elevated command prompt (“run as administrator”) and ran this command on each computer:

cd C:\Users\<user name>
ren Favorites Favorites.bak
mklink /d Favorites C:\Users\<user name>\SkyDrive\Favorites

That’s it!

Edit: There is a much simpler method. Select the Favorites folder in file Explorer, then select properties, then go to the location tab, then type C:\Users\<user name>\SkyDrive\Favorites as the new location and click the Move button.

Modifying Installation Directory Security with Windows Installer

I had a ill-behaved application for which I needed to construct an MSI installation package. The problem with this application is that it requires users to have modify permissions on the installation folder (and subfolders), since it writes application data there.

So the first step was to create a custom action. Create a C# project, then Add New Item and choose the Installer Class template.

Here is the beginning of this class:

    [RunInstaller(true)]
    public partial class ClientInstaller : System.Configuration.Install.Installer
    {
        public ClientInstaller()
        {
            InitializeComponent();
        }

        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
            SetDirectorySecurity();
        }

Then, right-click on the setup project, choose View –> Custom actions to display the custom actions window. In the Install folder, add Primary output from the C# project.

The first problem was how to get hold of the installation folder. I used a context parameter, targetdir, for this.
string targetdir = Path.GetDirectoryName(Context.Parameters["targetdir"]);
This parameter needs to be set using the CustomActionData property. In the custom actions window, select primary output from the C# project, and set the CustomActionData property to
/targetdir="[TARGETDIR]\"
Yes, the double quotation marks and the backslash are needed.

The second problem was how to actually add the permissions. I found (part of) the answer in a forum post by “Jaso”: http://www.aspnet-answers.com/microsoft/NET-Security/30001760/how-to-change-group-permissions-on-existing-folder.aspx. The  problem with this code is that the statement “So just use ‘objectinherit and the child objects (even created at a later time in sub directories) inherit the permission correctly.” is false. You need to use both ObjectInherit and ContainerInherit to make sub folders inherit the same permission. Here is my complete SetDirectorySecurity:

        private void SetDirectorySecurity()
        {
            string targetdir = Path.GetDirectoryName(Context.Parameters["targetdir"]);
            Log("Adding modify rights for " + targetdir);
            // The following code was copied (and modified) from "Jaso" (http://www.aspnet-answers.com/microsoft/NET-Security/30001760/how-to-change-group-permissions-on-existing-folder.aspx).
            // Retrieve the Directory Security descriptor for the directory
            var dSecurity = Directory.GetAccessControl(targetdir, AccessControlSections.Access);
            // Build a temp domainSID using the Null SID passed in as a SDDL string.
            // The constructor will accept the traditional notation or the SDDL notation interchangeably.
            var domainSid = new SecurityIdentifier("S-1-0-0");
            // Create a security Identifier for the BuiltinUsers Group to be passed to the new accessrule
            var ident = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, domainSid);
            // Create a new Access Rule.
            // ContainerInherit AND ObjectInherit covers both target folder, child folder and child object.
            // However, when using both (combined with AND), the permissions aren't applied.
            // So use two rules.
            // Propagate.none means child and grandchild objects inherit.
            var accessRule1 = new FileSystemAccessRule(ident, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow);
            var accessRule2 = new FileSystemAccessRule(ident, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow);
            // Add the access rules to the Directory Security Descriptor
            dSecurity.AddAccessRule(accessRule1);
            dSecurity.AddAccessRule(accessRule2);
            // Persist the Directory Security Descriptor to the directory
            Directory.SetAccessControl(targetdir, dSecurity);
            Log("Rights added.");
        }

        private void Log(string message)
        {
            Context.LogMessage(message);
            System.Diagnostics.Trace.WriteLine(message, "1177 client installer");
        }