Connect to Remote Machine via WinRM (PowerShell PSSession)

Unlike SSH, connecting to a remote host with WinRM requires a little bit of a setup.
Since this is required for chef test kitchen set up, and I end up re-Googling for this every time I set up a new machine, I decided it is worth a blog post.

So there are potentially two parts to this, dependent on whether WinRM is already set up on your machine:

Connect to remote machine

First set up your credentials. Open up PowerShell and run

 $cred = Get-Credential

This will prompt you for your credentials and save them in the $cred variable. Enter the credentials you intend to use to connect to the remote machine.
Now enter PSSession using your remote host IP and the credentials you have just set up:

 Enter-PSSession 192.168.XXX.XXX -Authentication "basic" -Credential=$cred

If you get the error:

The WinRM client cannot process the request…

Continue reading on how to set up WinRM on your machine:

Set up WinRm on your machine

Open CMD as administrator
Enable WinRM

winrm quickconfig /q

To check your current WinRM configuration

winrm get winrm/config

If you get the error:

The WinRM client cannot process the request. Unencrypted traffic is currently disabled in the client configuration.

Enable unencrypted traffic in WinRM:

winrm set winrm/config/client @{AllowUnencrypted="true"}

If you get the error:

The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting.

Add the remote computer you are connecting to to Trusted hosts:

winrm set winrm/config/client @{TrustedHosts="192.168.XXX.XXX"}

If you do this fairly often and are behind a secure firewall you can save some time by adding everyone to your trusted hosts:

winrm set winrm/config/client @{TrustedHosts="*"}

Happy Remoting!

No, wait, the mandatory meme:

remote session

Azure Web App Deployment Parameters for MSBuild (TeamCity Example)

Setting up automated publish steps on CI servers often requires setting up an MSBuild step to auto-deploy your application into an Azure Website. While you usually provide a .pubxml publishing profile for that, you also need to add MSBuild parameters for the publishing to work correctly.

My example here is with TeamCity, but it would work similarly with Jenkins or TFS.

TeamCity

MSBuild parameters
 /p:Configuration=Release /p:DeployOnBuild=true 
/p:PublishProfile=MyProjectPublishProfileName /p:UserName=$MyProjectUsername 
/p:Password=XXXXX /p:AllowUntrustedCertificate=true 
/p:VisualStudioVersion=12.0 /p:_DestinationType=AzureWebSite

Don’t omit the $ in the username!

Happy Deploying!

Jenkins Post Build Step – Execute Script

To execute a post-build script in Jenkins

Install Post Build Task Plugin
By going to Dashboard -> Manage Jenkins -> Manage Plugins -> Available -> Filter -> “Post build task”

Yes, the UI kind of sucks, anyone wants to contribute to Jenkins by improving the UX/UI design? =)

To configure the step

Go to your Jenkins job
Click Configure
Look for “Add post-build action”
Select “Post build task”
post build task

Now, the plugin looks for STRING MATCHES in the console output of the build. (I am only highlighting this because I had a typical RTFM case this morning)
So, if you want to execute the task when a specific event happens, you need it to look for that event’s output in the console log. Let’s say the output that signifies failure is this: “Build step ‘Execute Windows batch command’ marked build as failure”. You can add the substring “marked build as failure” as my Log Text, like so:
build step

You can use the AND and OR operation to perform the same script in multiple cases (such as different exceptions).

Custom Domain in WordPress on Azure Web App

Since I had to go through this process a few times lately, and it is not as straightforward as one could hope, I think the world needs this post 🙂

Create the DNS records

I have tried a number of options until I was able to get both the root domain and the www subdomain verified in Azure portal.
I am using CloudFlare, and my DNS records look like this:
dns cloudflare

Add custom domain to Azure Web App

At this point if you try to access your domain you will get the following error: “Error 404 – Web app not found … The web app owner has registered a custom domain to point to the Microsoft Azure App Service, but has not yet configured Azure to recognize it”
web app not found
 
To fix this error, you will need to add your custom domain as a hostname in Azure portal.
Browse to your Web App => All settings => Custom domains and SSL => HOSTNAMES ASSIGNED TO SITE, and add both the root and the www subdomain.
portal domains
You may need to allow for some time after you have configured your DNS records. The official time frame for propagating domains is up to 24 hours, but in my experience if the DNS is set correctly it won’t take longer than 20 minutes.

Now if you browse to your domain you will see your WordPress site, yay!
However, you aren’t done yet.
If you click on one of the links on the site you will notice that WordPress still redirects you to the initial domain on someone.azurewebsites.net. To fix that you need to update the domain set in WordPress itself.
 
DO NOT update it through WordPress Dashboard => Settings => General. This does not work (at least currently) and might lock you out of the application! 😯
Instead you will need to FTP into your site and change the functions.php of your currently active theme.

FTP into the site using FileZilla

Get FTP credentials:
In the portal, browse to your Web App and click on get publish profile.
get profile

Open the publish settings file you have downloaded, and look for FTP.
Copy the publishUrl, userName and userPWD into FileZilla and click Quickconnect. (The publishUrl is the Host).
 
filezilla
* I chose FileZilla for the demonstration since it is free and easy to use. You can certainly use other applications to FTP into the site.

Update siteurl in functions.php

Browse to your /site/wwwroot/wp-content/themes/THEME_NAME, where THEME_NAME is the name of your active theme.
Find the file functions.php and copy it over to your local machine (or simply right-click and choose View/Edit to edit the file on the fly).
Add the following two lines right after the opening

<?php

tag

update_option('siteurl','http://divineops.net');
update_option('home','http://divineops.net');

 
So, in my case the file now looks like this:
functions_php

 
Upload the file back into the site using FileZilla.
* Note that your active theme might not have a functions.php file. In this case you can add one yourself. Please read this post for further details https://codex.wordpress.org/Changing_The_Site_URL
 
Your site will be down for a couple of minutes, so wait for it to come back up and sign in. Now you can browse to WordPress Dashboard => Settings => General and see if the URL settings got updated:
wordpress url
Now that your site is back up and running, you should remove the lines you added from functions.php. The WordPress manual claims it is important to clean them up 😉

OK, we are good to go! Anyone who browses to your site will now be redirected to the siteurl you just set up as a root URL, regardless of how they got to the site in the first place. Happy browsing!

Clone Git Tag via PowerShell

Install Git

If you don’t already have Git for Windows:
Download Git for Windows from https://msysgit.github.io/
Choose “Use Git from the Windows Command Prompt” during the installation – this will add Git to your PATH
git install

Alternatively you can manually add Git to your PATH:
Go to System Environment Variables => Advanced => Environmental Variables.
Find path in the variables list and hit edit.
Add the path to Git executable on your machine. In my case it is C:Program Files (x86)Gitcmd

Now Git commands will be recognized in PowerShell on your machine.

Clone the tag

Open PowerShell
Clone repo via https:

git clone https://path/repo.git

 
List available tags:

git tag -l

 
Checkout the tag:

git checkout tag_name

Enjoy!

Generic Type-Safe Method to Retrieve Values from App Settings

Following my post from yesterday, I had to publish this little method that helps you retrieve values from your appSettings in a type-safe manner.

I simply love things like that – just a few lines of code make sure you won’t have to worry about type casting in the rest of your application!

using System;
using System.Configuration;

namespace MyApp.Domain.Helpers
{
	public static class ConfigHelper
	{
		public static T GetAppSetting<T>(string key)
		{
			var setting = ConfigurationManager.AppSettings[key];
			if (null == setting) return default(T);
			return (T)Convert.ChangeType(setting, typeof(T));
		}
	}
}

 
* Please note that this method will return the default value of type T if the setting key isn’t present, and throw an exception if the value is of an incorrect type. Other approaches to error handling might need to be implemented depending on your application.

And the usage:

var intValue = ConfigHelper.GetAppSetting<int>("IntValue");
var stringValue = ConfigHelper.GetAppSetting<string>("StringValue");

Custom MVC Role Authorize Attribute using App Settings

Here is a simple implementation of a custom [Authorize] attribute that uses appSettings get Role names:

The only important thing to note here is using Sytem.Web.Mvc, since the [Authorize] attribute also exists in System.Web.Http and has a slightly different implementation there.
I believe the two implementations have been unified in Asp.Net 5 / MVC 6, but that is still in preview.

using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyApp.Web.Attributes
{
    public class RoleAuthorizeAttribute : AuthorizeAttribute
    {

        public RoleAuthorizeAttribute(params string[] roleNames)
        {
            var roles = roleNames.Select(roleName => 
			ConfigHelper.GetAppSetting<string>(roleName)).ToList();

            this.Roles = string.Join(",", roles);
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return base.AuthorizeCore(httpContext);
        }
    }
}

Now you decorate your controllers / methods with [RoleAuthorize(“MyRoleName”)]

[RoleAuthorize("MyRoleName")]
public class MyController : Controller
{
	public ActionResult Index()
	{
		return View();
	}
}

And this is all for this post =)