Posts tagged Windows Azure
Enable PowerShell Remoting on Windows Azure
If it takes you more than 1 line of code, you aren’t doing it right!
I started writing this post a week ago in response to a customer request, so excited I was I even tweeted about writing a post on PowerShell. My Bad – because right after I tweeted I hit a snag – which is worthy of a whole post on its own. Ignoring the snag right now – let me tell you how to do the above.
First – a BIG shout out to the PowerShell team at Microsoft who answered my endless questions. Also a big shout out to Lee Holmes – who once again saved my bacon.
Anyway…
At long last I’ve had a chance to “play” around with the new Windows Azure features we announced at PDC 2010. I thought it would be fun to enable PowerShell Remoting in Windows Azure Roles. (Note I’m talking about Web and Worker roles here – not VM Role).
With new features such as remote desktop, startup tasks and Azure Connect – setting up PowerShell should be easy.
First, I’m going to assume you have worked through the notes/tutorials/stuff to enable Azure Connect & Remote Desktop – that way this post stays within the realms of being relatively small.
Here is our checklist:
- Make sure the OS Family in the ServiceConfiguration.cscfg is set to “2” to enable R2.
- Create a user account so you can connect to the server.
- Add a startup task to open the firewall port.
- Add the Role to Azure Connect.
- Execute Lee’s magic script to enable PowerShell Remoting
PowerShell v2 is the version you need to do remoting. Server 2008 R2 contains PowerShell v2 in the box. We can tell Windows Azure to use an R2 server by changing the OSFamily in the ServiceCOnfiguration.cscfg to 2 as shown below:
<ServiceConfiguration serviceName="AzureMemcachedTest" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*">
Next step is to create a user account so that you can actually connect to the server. The easiest way to do this is to enable remote desktop, which creates a user on the host.
Now to make sure the firewall port is open we will need. I created a .cmd file containing the following 2 commands. The first opens the firewall for WINRM, the second for ping. This was added in the root folder of my role project.
netsh advfirewall firewall add rule name="Windows Remote Management (HTTP-In)" dir=in action=allow service=any enable=yes profile=any localport=5985 protocol=tcp
netsh advfirewall firewall add rule name="ICMPv6 echo" dir=in action=allow enable=yes protocol=icmpv6:128,any
Then I added a startup task to ServiceDefinition.csdef:
<Startup>
<Task commandLine="EnablePowershellRemoting.cmd" executionContext="elevated" taskType="foreground"/>
</Startup>
Next add the Role to Azure Connect. I’ll assume you know how to do this.
Now deploy your service. Once deployed, do the final step to connect the Azure connect network, and make sure the agent is installed on your computer.
The final step is to “turn on” PowerShell Remoting. For numerous reasons, you cannot just run a startup task with “Enable-PSRemoting” as the command. The biggest reason is that startup tasks run as local system and thus cannot actually complete the Enable-PSRemoting command.
This is where I got stuck for 3 days until Lee shared his script. The script is below and is fairly easy to follow. Basically it will connect to the VM and create a scheduled task to enable-psremoting.
##############################################################################
##
## Enable-RemotePsRemoting
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Enables PowerShell Remoting on a remote computer. Requires that the machine
responds to WMI requests, and that its operating system is Windows Vista or
later.
.EXAMPLE
Enable-RemotePsRemoting <Computer>
#>
param(
## The computer on which to enable remoting
$Computername,
## The credential to use when connecting
$Credential = (Get-Credential)
)
Set-StrictMode -Version Latest
$VerbosePreference = "Continue"
$credential = Get-Credential $credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
$script = @"
`$log = Join-Path `$env:TEMP Enable-RemotePsRemoting.output.txt
Remove-Item -Force `$log -ErrorAction SilentlyContinue
Start-Transcript -Path `$log
## Create a task that will run with full network privileges.
## In this task, we call Enable-PsRemoting
schtasks /CREATE /TN 'Enable Remoting' /SC WEEKLY /RL HIGHEST ``
/RU $username /RP $password ``
/TR "powershell -noprofile -command Enable-PsRemoting -Force" /F |
Out-String
schtasks /RUN /TN 'Enable Remoting' | Out-String
`$securePass = ConvertTo-SecureString $password -AsPlainText -Force
`$credential =
New-Object Management.Automation.PsCredential $username,`$securepass
## Wait for the remoting changes to come into effect
for(`$count = 1; `$count -le 10; `$count++)
{
`$output = Invoke-Command localhost { 1 } -Cred `$credential ``
-ErrorAction SilentlyContinue
if(`$output -eq 1) { break; }
"Attempt `$count : Not ready yet."
Sleep 5
}
## Delete the temporary task
schtasks /DELETE /TN 'Enable Remoting' /F | Out-String
Stop-Transcript
"@
$commandBytes = [System.Text.Encoding]::Unicode.GetBytes($script)
$encoded = [Convert]::ToBase64String($commandBytes)
Write-Verbose "Configuring $computername"
$command = "powershell -NoProfile -EncodedCommand $encoded"
$null = Invoke-WmiMethod -Computer $computername -Credential $credential `
Win32_Process Create -Args $command
Write-Verbose "Testing connection"
Invoke-Command $computername {
Get-WmiObject Win32_ComputerSystem } -Credential $credential
Piece of cake really.
Once you have the script saved, you can execute it like
PS> $computername = "WhateverTheComputerNameOfTheInstanceIs"PS> .\Enable-RemotePSRemoting.ps1 $computername
Once it finishes executing, you should be able to connect using:
PS> Enter-PSSession –ComputerName $computername –Credential RemoteDesktopUsername
Then you can work interactively – try get-process as an example.
Pretty neat, and great for debugging!
THIS POSTING IS PROVIDED “AS IS” WITH NO WARRANTIES, AND CONFERS NO RIGHTS
Windows Azure Memcached plugin
Update: Fixed broken link.
Cutting a really long story short. I wanted an easy way of adding caching to a Windows Azure project. Several people I know are already using Memcached, while waiting for our own caching service to go into production. I thought, this should be a plugin.
A plugin is exactly what it sounds, it is something that gets “plugged” into your role at build time. You can see the existing plugins on you have installed by looking at C:\Program Files\Windows Azure SDK\v1.3\bin\plugins. You should see plugins for diagnostics, RemoteAccess and more.
To make your own plugin is fairly easy – if you look in any of the plugin folders you will see a .CSPLUGIN file. You should be able to work out how this works. If you cannot, you probably don’t want to be building your own.
For the Memcached plugin, all I really need is the memcached.exe file (and any dependencies( I used the version from http://www.urielkatz.com/archive/detail/memcached-64-bit-windows/)), plus a little wrapper to read the config and launch memcached with the correct parameters – and of course the CSPLUGIN file:
<?xml version="1.0" ?> <RoleModule xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" namespace="Memcached64Plugin"> <Startup> <Task commandLine="Memcached64Plugin.exe" taskType="background" executionContext="limited"/> </Startup> <Endpoints> <InternalEndpoint name="Endpoint" protocol="tcp" port="11212" /> </Endpoints> <ConfigurationSettings> <Setting name="CacheSizeInMB"/> </ConfigurationSettings> </RoleModule>
What the above essentially does is:
- Adds a startup task
- Adds an InternalEndpoint for port 11212
- Adds a CacheSizeInMb setting
The little wrapper was written as a console app:
static void Main() { var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Memcached64Plugin.Endpoint"].IPEndpoint; var cacheSize = RoleEnvironment.GetConfigurationSettingValue("Memcached64Plugin.CacheSizeInMB"); var startupInfo = new ProcessStartInfo("memcached.exe", string.Format("-m {0} -p {1}", cacheSize, endpoint.Port)); Process.Start(startupInfo); }
Note when we read the values we use the format <name of the plugin>.<key>, rather than just <key>, in this case Memcached64Plugin.Endpoint, rather than just Endpoint.
Once you build the solution and copy the files into the plugin folder, you can then use the Imports tag in your ServiceConfiguration.csdef file:
<Import moduleName="Memcached64Plugin" />
This will magically add the correct settings to your ServiceConfiguration.cscfg file as shown:
<ConfigurationSettings> <Setting name="Memcached64Plugin.CacheSizeInMB" value="512" />
Note, you won’t see the internal port or the startup task.
When you build and deploy (or even run in the Compute Emulator) the plugin will be packaged up with your code and executed on boot.
For the client side, I used the enyim client, which you can grab from http://memcached.enyim.com/.
You can grab a list of memcached servers using the RoleEnvironment, something like:
RoleEnvironment.Roles["WebRole1"].Instances.Select(instance => instance.InstanceEndpoints["Memcached64Plugin.Endpoint"].IPEndpoint)
Note the role is WebRole1 and the port we are looking for is the one we defined in the CSPLUGIN!
You should also write some code to handle a topology change, including adding more instances (or removing instances). You can do this by adding code to handle the RoleEnvironment.Changed event, and rebuilding your server list.
You can grab my plugin below, minus the memcached.exe and required dll. You can download those from the http://www.urielkatz.com/archive/detail/memcached-64-bit-windows/.
THIS POSTING IS PROVIDED “AS IS” WITH NO WARRANTIES, AND CONFERS NO RIGHTS
PS: No, this was nothing to do with PowerShell, I hit an issue with that which I’m still working on – cross your fingers – it will be splendid.
Windows Azure Diagnostics Viewer
I’ve just finished publishing a prototype of the Windows Azure Diagnostics Viewer onto code gallery at http://code.msdn.microsoft.com/wazdmon.
The Windows Azure Diagnostics Viewer is a prototype web application that can be used to view and analyze Windows Azure Diagnostics information.
The Windows Azure Diagnostics Viewer has 2 components, a website and a scheduler. The website provides a UI to allow you to view diagnostics information collected by Windows Azure, including performance counter graphs, logs as well as some customer data including Windows Azure Queue statistics and service status data.
The website is designed to be “injected” into an existing worker role by adding references to a few dll’s as well as the website “exe”. The goal here is to make adding the viewer to a project painless – although in the prototype there are still several steps to complete.
Once started, the viewer website uses the HWC to host the website.
As well as simply viewing data collected by the existing Windows Azure Diagnostics system, the viewer can also display pre-aggregated data as well as information about Queue lengths and even service status. It does this with the help of the scheduler.
The scheduler is also designed to be “injected” into a role, and simply executes specified tasks. These tasks are contained in dll’s which are loaded from blob storage. The viewer provides shortcuts to common tasks, such as queue length collection and data aggregation.
Whilst this is a prototype, it has inspired some other thinking and ideas. You can expect a rev for the new SDK shortly after the new SDK hits as we’d like to take advantage of some of the new SDK features.
Anyway, check it out and let us know what you think.
THIS POSTING IS PROVIDED “AS IS” WITH NO WARRANTIES, AND CONFERS NO RIGHTS