Filtered by Tag (powershell)
Removing a Windows Azure Virtual Machine doesn't remove everything for you. This post is all about cleaning up with PowerShell after removing a Windows Azure VM
@ 04-28-2013
by Tugberk Ugurlu

When you remove a Windows Azure virtual machine, you are not actually removing everything. I hear you saying "What!!!"? Let's dive in then Smile

As each VM is kept under a cloud service, that cloud service is one of those things that remain after you remove your VM. Other thing is the disk (or disks, depends on your case) which is attached to your VM. If you didn't attach any data disks, at least your OS disk will remain inside your storage account even if you remove your VM. However, you cannot go and directly delete that VHD file just like a typical blob because there is a lease on that blob as it's still viewed as one of your registered disks.

Let's look at a case of mine on removing a Windows Azure VM. Yesterday, I created two VMs for demonstration purposes on a presentation and after the presentation, I removed those VMs by running "Remove-AzureVM" PowerShell command. So far, so good. When I go to the portal, I don't see those VMs as expected and I don't see any cloud services.

If you create a VM, the new portal is not showing that you have a cloud service but it implicitly creates one for you under the covers. As soon as you attach another VM to that cloud service, the cloud service shows up on the new portal as well. In either of these cases, the generated cloud service is completely visible to you through the REST management API. So, you can view them through PowerShell Cmdlets.

Let's run "Get-AzureService" PowerShell command to see my cloud services:


These are the generated cloud services which belong to my removed VMs. As far as I know, these cloud services won't cost me anything as they contain no deployments but it would be nice to remove them as I don't need them.


I got rid of the unnecessary cloud services. The next and final step of this cleaning is to remove the OS disks I have. This's actually more important because disk VHD files are stored inside the Windows Azure storage as blobs and each OS disk is approx. 127GB in size. So, I will pay for them as long as I keep them. Through new Windows Azure Storage PowerShell Cmdlets, I can view my VHD container to see which VHD files I have:


As you can see, I have two unnecessary VHD files which remained after my VM removal. At this stage, you might think directly deleting these blobs but as mentioned before, it will fail if we try to do that.


The error message I got is very descriptive actually: There is currently a lease on the blob and no lease ID was specified in the request. Let's run another PowerShell command to see which disks I have registered:


I have those two blobs registered as my disks and this prevents me from directly deleting them which is perfectly reasonable. To prove that this is actually the case, I will view the HTTP headers of one of those disks through CloudBerry Explorer for Azure Blob Storage:


You can see that "x-ms-lease-status" header is set to "locked" which states that there is a lease on the blob. Let's remove the "IstBootcampDemoTugberk-IstBootcampVM1-2013-4-27-132" disk from my registered disks:


Now, let's look at the HTTP headers of the blob again:


The lease is now taken out and it's now possible to delete the blob:


However, you can delete the disk from your registered disks list and the storage container in one go by running "Remove-AzureDisk" PowerShell Cmdlet with "DeleteVHD" switch:


The VHD file is completely gone. I hope the post was helpful Smile

Windows Azure PowerShell Cmdlets is a great tool to manage your Windows Azure services but if you are like me, you would wanna know where all the stuff is going. This post is all about it.
@ 04-26-2013
by Tugberk Ugurlu

Managing your Windows Azure services is super easy with the various management options and my favorite among these options is Windows Azure PowerShell Cmdlets. It's very well-documented and if you know PowerShell enough, Windows Azure PowerShell Cmdlets are really easy to grasp. In this post I would like to give a few details about this management option and hopefully, it'll give you a head start.

Install it and get going

Installation of the Windows Azure PowerShell Cmdlets is very easy. It's also well-documented. You can reach the download link from the "Downloads" section on Windows Azure web site. From there, all you need to do is follow the instructions to install the Cmdlets through Web Platform Installer.

After the installation, we can view that we have the Windows Azure PowerShell Cmdlets installed on our system by running "Get-Module -ListAvailable" command:


To get you started using Cmdlets, you can see the "Get Started with Windows Azure Cmdlets" article which explains how you will set up the trust between your machine and your Windows Azure account. However, I will cover some steps here as well.

First thing you need to do is download your publish settings file. There is a handy cmdlet to do this for you: Get-AzurePublishSettingsFile. By running this command, it will go to your account and create a management certificate for your account and download the necessary publish settings file.

Next step is to import this publish settings file through another handy cmdlet: Import-AzurePublishSettingsFile <publishsettings-file-path>. This command is actually setting up lots of stuff on your machine.

  • Under "%appdata%\Windows Azure Powershell", it creates necessary configuration files for the cmdlets to get the authentication information.


  • These configuration files don't actually contain certificate information on its own; they just hold the thumbprint of our management certificate and your subscription id.
  • Actual certificate is imported inside your certificate store. You can view the installed certificate by running "dir Cert:\CurrentUser\My" command.


Now you are ready to go. Run "Get-AzureSubscription" command to see your subscription details and you will see that it's set as your default subscription. So, from now on, you don't need to do anything with your subscription. You can just run the commands without worrying about your credentials (of course, this maybe a good or bad thing; depends on your situation). For example, I ran the Get-AzureVM command to view my VMs:


So, where is my stuff?

We installed the stuff and we just saw that it's working. So, where did all the stuff go and how does this thing even work? Well, if you know PowerShell, you also know that modules are stored under specific folders. You can view these folders by running the '$env:PSModulePath.split(';')' command:


Notice that there is a path for Windows Azure PowerShell Cmdlets, too. Without knowing this stuff, we could also view the module definition and get to its location from there:

Get-Module -ListAvailable -Name Azure


"C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure" directory is where you will find the real meat:


On the other hand, when we imported the publish settings, it puts a few stuff about my subscription under "%appdata%\Windows Azure Powershell". The certificate is also installed under my certificate store as mentioned before.

Clean Up

When you start managing your Windows Azure services through PowerShell Cmdlets, you have your Windows Azure account information and management certificate information at various places on your computer. Even if you uninstall your Windows Azure PowerShell Cmdlets from your machine, you are not basically cleaning up everything. Let's start by uninstalling the Cmdlets from your computer.

Simply go to Control Panel > Programs > Programs and Features and find the installed program named as Windows Azure PowerShell and uninstall it. You will be done.


Next step is to go to "%appdata%\Windows Azure Powershell" directory and delete the folder completely. One more step to go now: delete your certificate. Find out what the thumbprint of your certificate is:


Then, run the Remove-Item command to remove the certificate:

Remove-Item Cert:\CurrentUser\My\507DAAF6F285C4A72A45909ACCEE552B4E2AE916 –DeleteKey

You are all done uninstalling Windows Azure PowerShell Cmdlets. Remember, Windows Azure is powerful but it's more powerful when you manage it through PowerShell Smile


We will see how to smoothly work with IIS Express Self-signed Certificate, ASP.NET Web API and HttpClient by placing the self-signed certificate in the Trusted Root CA store.
@ 10-23-2012
by Tugberk Ugurlu

If you would like to only support HTTPS with your ASP.NET Web API application, you might also want expose your application through HTTPS during the development time. This is not a big problem if you are heavily integration-testing your Web API as you can pass anything you want as a host name but if you are building your HTTP API wrapper simultaneously, you want to sometimes do manual testing to see if it’s actually working. There are sevaral ways to sort this problem out and one of them is provided directly by Visual Studio. Visual Studio allows us to create HTTPS bindings to use with IIS Express during development time. Let’s see how that works.

Note: I am assuming everybody understands that I am talking about ASP.NET Web API web host scenario with ASP.NET here. This blog post is not about self-host scenarios.

First of all, I created an empty web application through visual studio. Then, I added one of my NuGet packages: WebAPIDoodle.Bootstrap.Sample.Complex. This package will get you all ASP.NET Web API stuff and a working sample with all CRUD operations.

I also created a message handler which is going to ensure that our API is only going to be exposed over HTTPS.

public class RequireHttpsMessageHandler : DelegatingHandler {

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken) {

        if (request.RequestUri.Scheme != Uri.UriSchemeHttps) {

            var forbiddenResponse = 

            forbiddenResponse.ReasonPhrase = "SSL Required";
            return Task.FromResult<HttpResponseMessage>(forbiddenResponse);

        return base.SendAsync(request, cancellationToken);

Then, I registered this message handler as you can see below:

protected void Application_Start(object sender, EventArgs e) {

    var config = GlobalConfiguration.Configuration;


    config.MessageHandlers.Add(new RequireHttpsMessageHandler());

To configure the HTTPS endpoint with IIS Express, I simply need to click on the web application project and press F4. This will bring up the project properties and there will be a option there called "SSL Enabled".


By default, this is set to False as you can see. If we change this and set it to True, Visual Studio will create the necessary binding for our application by assigning a new port number and attaching the pre-generated self-signed certificate for that endpoint.


Now, when we open up a browser and navigate to that HTTPS endpoint, we should face a scary looking error:


As our certificate is a self-signed certificate, the browser doesn’t trust that and gives this error. This error is not a blocking issue for us and we can just click the Proceed anyway button to suppress this error and everything will be work just fine.

Let’s close the browser and create a very simple and naïve .NET console client for our API as below:

class Program {

    static void Main(string[] args) {


    public static async Task<string> GetStringAsync() {

        using (HttpClient client = new HttpClient()) {

            return await client

As I said, it is insanely simple Smile but will serve for our demo purposes. If we run this console application along with our Web API application, we should see an exception thrown as below:


This time the HttpClient is nagging at us because it didn’t trust the server certificate. If we open up the browser again and take a look at the certificate, we will see that it is also complaining that this self-signed certificate is not in the Trusted Root CA store.


One way to get rid of this problem is to place this self-signed certificate in the Trusted Root CA store and the error will go away. Let’s first open up a PowerShell Command window and see where this self-signed certificate lives.


As we now know where the certificate is, we can grab this certificate and place it in the Trusted Root CA store. There are several ways of doing this but I love PowerShell, so I am going to do this with PowerShell, too. To be able to perform the below operations, we need to open up an elevated PowerShell Command Prompt.


Let’s explain what we did above:

  • We retrieved our self-signed certificate and stuck it into a variable.
  • Then, we retrieved the Trusted Root CA store and stuck that into a variable, too.
  • Lastly, we opened up the store with Read and Write access and added the certificate there. As a final step, we closed the store.

After this change, if we take a look at the Trusted Root CA store, we will see our certificate there:


If we now run our console client application, we should see it working smoothly.


I hope this will help you as much as it helped me Smile

Script Out Everything - Initialize Your Windows Azure VM for Your Web Server with IIS, Web Deploy and Other Stuff
@ 09-17-2012
by Tugberk Ugurlu

Today, I am officially sick and tired of initializing a new Web Server every time so I decided to script it all out as much as I can. I created a new Windows Azure VM running Windows Server 2012 and installed Web Platform Installer v4 Command Line tool (aka WebPICMD.exe).

Next thing I need to do is to install the IIS Web Server Role inside my VM. To do that, I opened up the Server Manager and closed it instantly because I didn't wanna do that through a GUI either. It turned out that it is fairly easy to manage your server roles and features through PowerShell thanks to ServerManager PowerShell module. This module has couple of handy Cmdlets which enable you to manage your server’s roles and features.


To install the IIS Web Server, I run the following PowerShell command. It installs IIS Web Server (along with the necessary dependencies and management tools) and logs the output under the TEMP folder.

$logLabel = $((get-date).ToString("yyyyMMddHHmmss"))
Import-Module -Name ServerManager
Install-WindowsFeature -Name Web-Server -IncludeManagementTools -LogPath "$env:TEMP\init-webservervm_webserver_install_log_$logLabel.txt"


When we look at the installed features, we should see that IIS Web Server is now listed there:


At this stage, we have a few more necessary features to install such as ASP.NET 4.5 and Management Service. Optionally, I always want to install Dynamic Content Compression and IIS Management Scripts and Tools features. To install those features, we will run the following script:

#add additional windows features
$additionalFeatures = @('Web-Mgmt-Service', 'Web-Asp-Net45', 'Web-Dyn-Compression', 'Web-Scripting-Tools')
foreach($feature in $additionalFeatures) { 
    if(!(Get-WindowsFeature | where { $_.Name -eq $feature }).Installed) { 

        Install-WindowsFeature -Name $feature -LogPath "$env:TEMP\init-webservervm_feature_$($feature)_install_log_$((get-date).ToString("yyyyMMddHHmmss")).txt"   
#Set WMSvc to Automatic Startup
Set-Service -Name WMSvc -StartupType Automatic

#Check if WMSvc (Web Management Service) is running
if((Get-Service WMSvc).Status -ne 'Running') { 
    Start-Service WMSvc

As you can see at the end of the script, we are also setting the Management Service's startup type to automatic and finally, we are starting the service.

Now the IIS Web Server is ready, we need to get a few more bits through the Web Platform Installer v4 Command Line tool. With all of my web servers, there are two concrete tools I would like to have: Web Deploy and URL Rewrite Module. We can certainly install those manually but we can also script out their installation. WebPICMD.exe allows us to install products through command line and the following command will work for us:

$webPiProducts = @('WDeployPS', 'UrlRewrite2')
.\WebPICMD.exe /Install /Products:"$($webPiProducts -join ',')" /AcceptEULA /Log:"$env:TEMP\webpi_products_install_log_$((get-date).ToString("yyyyMMddHHmmss")).txt"

I assume that WebPICMD.exe is under your path here (if you have installed the 64x version of the product, you can find the executable file under C:\Program Files\Microsoft\Web Platform Installer). When the installation is complete, we should see the success message:


Well, we have completed most of the work but there are still couple of things to do. First of all, we need to allow incoming connections through TCP port 8172 because this is the port that Web Deploy will talk through. To enable that, we can go to Windows Firewall with Advanced Security window but that would be lame. Are we gonna use netsh? Certainly not :) With PowerShell 3.0, we can now control the Windows Firewall with Advanced Security Administration. This functionality is provided through NetSecurity PowerShell module but with the new dynamic module loading feature of PowerShell 3.0, we don’t need to separately import this. The following command will add the proper firewall rule to our server.

New-NetFirewallRule -DisplayName "Allow IIS Management Service In" -Direction Inbound -LocalPort 8172 -Protocol TCP -Action Allow

Lastly, we need to inform windows azure about this firewall rule as well because all the requests, which come from outside, will go through the load balancer and it doesn’t open up any ports by default (except for Remote Desktop ports). You can the endpoints through Windows Azure Portal but Windows Azure PowerShell Cmdlets to add this as well. The following command will add the proper rule. Just change the $serviceName and $vmName according to your credentials:

Get-AzureVM -ServiceName $serviceName -Name $vmName | Add-AzureEndpoint -Name "WebDeploy" -Protocol TCP -LocalPort 8172 -PublicPort 8172 | Update-AzureVM

When we look at the portal, we should see that our endpoint was created.


Now, everything should be working perfectly. Of course you also need to add TCP port 80 to your Endpoint lists for your VM in order for your web sites to be reachable through HTTP (assuming you will only use PORT 80 for your web applications). To test everything out, I created a web application under IIS. Then, I right clicked on it and navigate to Deploy > Configure Web Deploy Publishing.


This will bring up another dialog. This is the place where we can configure web deploy settings. There are other ways to do this as well.


Just change the VM name with your VIP address and this will generate a publish profile. We can now use this publish profile file to push our web application to the server.


When the publish is completed, we will see the complete result inside the Output window.


We jumped through lots of hoops to get this done but how is this better than doing it manually? Imagine that you bring all these scripts together and run them through multiple VMs. It’s going to save a lot of time for you. I am not an IT pro. So, this is enough to make me happy because I just proved that nearly everything that a web developer needs can be automated through PowerShell or various command line tools.


I put these together inside one script file. Follow the instructions inside the script and you will be good to go.

This doesn't add the endpoints for your VM. For this, you have another script as well:

I started to use Windows Server AppFabric for its distributed caching feature and I wanted to take a note of the useful PowerShell commands to manage the service configuration and administration.
@ 05-23-2012
by Tugberk Ugurlu

I started to use Windows Server AppFabric for its distributed caching feature and I wanted to take a note of the useful PowerShell commands to manage the service configuration and administration. When I write this blog post, Microsoft AppFabric 1.1 for Windows Server is available. I installed the caching service and caching management features firstly. Then, I configured it properly. See Configure AppFabric page for more information on configuration.

First of all, import necessary modules:

Import-Module DistributedCacheConfiguration
Import-Module DistributedCacheAdministration

You can view the commands with Get-Command Cmdlet. For example, we can see all commands which are available for DistributedCacheAdministration with the following one line of code.

Get-Command -Module DistributedCacheAdministration


Use-CacheCluster command sets the context of your PowerShell session to a particular cache cluster. Note that you must run this command before using any other Cache Administration commands in PowerShell.

Get-CacheHost command lists all cache host services that are members of the cache cluster.

Your cache host is running as a windows service and you can retrieve the status of your caching host with Get-CacheHost command. It will output a result which is similar to following:


My service is up and running but if the status indicates that the service is down, you can start it with the following command:

Start-CacheHost -HostName TugberkWin08R2 -CachePort 22233

You should be able to see your service running after this:


Get-CacheClusterInfo command from configuration module returns the cache cluster information, including details on its initialization status and its size. The following one line of code shows a sample usage.

Get-CacheClusterInfo -Provider XML -ConnectionString \\TUGBERKWIN08R2\Caching

More information on this command:

That’s it for now.


Hi 🙋🏻‍♂️ I'm Tugberk Ugurlu.
Coder 👨🏻‍💻, Speaker 🗣, Author 📚, Microsoft MVP 🕸, Blogger 💻, Software Engineering at Deliveroo 🍕🍜🌯, F1 fan 🏎🚀, Loves travelling 🛫🛬
Lives in Cambridge, UK 🏡