Speaking at Visual Studio Live! New York

I’ll be speaking at Visual Studio Live!, September 28-October 1 in New York. Surrounded by your fellow industry professionals, Visual Studio Live! provides you with immediately usable training and education that will keep you relevant in the workforce.

I’ll be presenting the following sessions:
· Automating Your Azure Environment
· Inside the Azure Resource Manager

SPECIAL OFFER: As a speaker, I can extend $400 savings on the 4-day package. Register here: http://bit.ly/NYSPK07Reg

Amplify your knowledge at Visual Studio Live! New York — bring the issues that keep you up at night and prepare to leave this event with the answers, guidance and training you need. Register now: http://bit.ly/NYSPK07Reg

CloudDevelop – Call for Speakers

As you may know, I am one of the organizers of a cloud computing conference in Columbus, OH called CloudDevelop. CloudDevelop’s mission is to bring together the brightest minds in cloud computing for a day of networking, sharing, and learning about all things cloud computing. I am extremely excited that CloudDevelop is coming back for its 4th year on Friday, October 23rd. This year, CloudDevelop is returning to were it all started at the Ohio Union on the campus of The Ohio State University.

CloudDevelop is currently accepting speaker submissions for potential sessions at CloudDevelop. The call for speakers window opened on Monday, June 8th and runs through midnight on Friday, June 26th. The organizing committee for CloudDevelop is looking for sessions on all things cloud. CloudDevelop is platform and technology agnostic – we want sessions on anything related to cloud computing. We want a diverse mix of sessions – meaning sessions on Amazon AWS, Microsoft Azure, Google, Salesforce, Rackspace, Heroku, etc. Anything cloud related – CloudDevelop is interested in it!

You can find more information on the call for speakers at http://blog.clouddevelop.org/2015/06/15/clouddevelop-2015-calling-all-speakers/.

To submit a session, please do so at http://bit.ly/CloudDevelopSpeakers2015.

Lock Down Your Azure Resources

Note: This post is cross-post with http://blogs.msdn.com/b/cloud_solution_architect.

A common ask when working with Azure is “how do I protect my critical resources?” Often this ask is related to protecting those resources from a human doing something they shouldn’t be doing.  There are a few ways to apply varying levels of control to Azure resources: role-based access control (RBAC) and resource locks.

Role-Based Access Control (RBAC)

Using role-based access control, it is possible to restrict control-plane access to various Azure resources. Roles can be assigned at the subscription, resource group, and individual resource scope. A role is associated with specific rights (one or more “action” and “not action” values). There are currently 23 built-in roles.

Leveraging RBAC is a great way to help protect resources in Azure. With the Reader and various Contributor roles (e.g. Virtual Machine Contributor, Storage Account Contributor, SQL DB Contributor, etc.), you can effectively limit the actions that a user can take against a resource. However, even with one of the Contributor roles, it is still possible to delete specific resources. This makes it very easy to accidently delete an item . . . often an item that is not so easy to get back, like an Azure storage account. Oops! Resource locks provide a way to prevent the deletion of resources.

To learn more about RBAC, please check out Neil Mackenzie’s earlier blog post entitled “RBAC and the Azure Resource Manager”, as well as “Role-based access control in the Microsoft Azure portal” on the main Azure site.

Resource Locks

The remainder of this post will focus on a relatively new feature with Azure Resource Manager, resource locks. In order to work with resource locks, you will need to use the Azure PowerShell cmdlets in Azure Resource Manager mode.

Switch-AzureMode AzureResourceManager

You will also need to be in either an Owner or User Access Administrator role for the desired scope, as only Owners and User Access Administrators have permission to write against the Microsoft.Authorization resources, which is the resource provider that handles resource locks.

For more on information on the “actions” and “not actions” associated with specific roles, please see https://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-configure/#built-in-roles.

Create a Resource Lock

A resource lock can be applied at either the resource group or resource scope. As of Azure PowerShell version 0.9.3, there is only one lock level available – CanNotDelete.

To see resource locks in action, let’s use a basic example of creating an Azure Storage account and applying the CanNotDelete resource lock.

$resourceGroup = 'CollierMedia'
$location = 'East US'
$storageAccountName = 'collierfiles2014'

# Create a new resource group.
New-AzureResourceGroup -Name $resourceGroup -Location $location

# Create a new Azure storage account in the new resource group.
New-AzureStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccountName -Location $location -Type Standard_GRS

# Apply a resource lock to the storage account.
New-AzureResourceLock -LockLevel CanNotDelete `
-LockNotes 'No deleting!' `
-LockName 'CollierLock' `
-ResourceName $storageAccountName `
-ResourceType 'Microsoft.Storage/storageAccounts' `
-ResourceGroup $resourceGroup -Verbose

# List all the resource locks in the current subscription.

After executing the above PowerShell commands, you should see the following output result:

powershell - create account and apply lock

Notice in the above screenshot that the “CollierMedia” resource group was created, a new ‘collierfiles2014’ storage account was created in the “CollierMedia” resource group, and a resource lock applied to the storage account. Take particular note of the ResourceId for the lock – that will be helpful when trying to delete a lock.

With the resource lock in place an attempt to delete the storage account fails with an error message indicating the specified resource is locked and needs to be removed before being deleted:

powershell - delete account (masked)

The above example demonstrated creating a resource lock for a specific resource. But what about locking an entire resource group? Placing a resource lock on an entire group could be helpful in situations where you want to ensure no resources in that group are deleted – for example, a resource group containing storage accounts used for Azure Virtual Machines. The example below demonstrates placing a lock on the entire “CollierMedia” resource group.

New-AzureResourceLock -LockLevel CanNotDelete `
-LockNotes 'No deleting!' `
-LockName 'CollierGroupLock' `
-ResourceGroup 'CollierMedia' -Verbose

powershell - lock resource group (masked)

Remove a Resource Lock

One easy way to remove the resource is to use the ResourceId associated with the lock. The ResourceId is returned when creating the lock. It can also be obtained via the Get-AzureResourceLock cmdlet. By default, Get-AzureResourceLock returns a list of all the locks in the current Azure subscription.

powershell - get-azureresourcelock (masked)

View the help (> get-help Get-AzureResourceLock) for additional ways to filter the locks returned.

Use the Remove-AzureResourceLock cmdlet, providing the desired ResourceId, to remove the lock.

Remove-AzureResourceLock -ResourceId '/subscriptions/0bbbc191-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/CollierMedia/providers/Microsoft.Storage/storageAccounts/collierfiles2014/providers/Microsoft.Authorization/locks/CollierLock'

Lock Resources using an Azure Resource Manager Template

Another way to lock a resource is to do so at creation time with an Azure Resource Manager (ARM) template. An ARM template is a JSON-formatted file that describes the desired state of a logically related group of Azure resources. The template could contain the resources needed for a specific web site (i.e. Azure Redis Cache, Azure SQL Database, Azure Storage account and Azure Web App.) or perhaps just a group of related Azure Virtual Machines – the choice is yours. For more information on Azure Resource Manager templates, please follow the links below:

The ARM template below shows an example of creating an Azure storage account and applying the CannotDelete resource lock.

"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "",
"parameters": {
"newStorageAccountName": {
"type": "string",
"metadata": {
"description": "Name of the Storage Account"


"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [

"metadata": {
"description": "Storage Account type"



"location": {
"type": "string",
"allowedValues": [
"East US",
"West US",
"West Europe",
"East Asia",
"Southeast Asia"

"metadata": {
"description": "Location of storage account"

"resources": [
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('newStorageAccountName')]",
"apiVersion": "2015-05-01-preview",
"location": "[parameters('location')]",
"properties": {
"accountType": "[parameters('storageAccountType')]"

"resources": [
"type": "Microsoft.Storage/storageAccounts/providers/locks",
"name": "[concat(parameters('newStorageAccountName'), '/Microsoft.Authorization/collierLock')]",
"apiVersion": "2015-01-01",
"dependsOn": [ "[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]" ],
"properties": {
"level": "CannotDelete",
"notes": "Mike's important files - do not delete!"

The corresponding template parameters files is as follows:


"location": {

"value": "East US"


"newStorageAccountName" : {

"value" : "collierimages2015"


"storageAccountType": {

"value": "Standard_GRS"



To execute this template, the following PowerShell cmdlet can be used:

New-AzureResourceGroupDeployment -ResourceGroupName 'CollierMedia' `
-TemplateFile 'azuredeploy.json' `
-TemplateParameterFile 'azuredeploy.parameters.json' `

Tip: If you would like to validate an ARM template before deploying it, you can use the Test-AzureResourceGroupTemplate cmdlet, such as:

Test-AzureResourceGroupTemplate -ResourceGroupName 'CollierMedia' `
-TemplateFile 'azuredeploy.json' `
-TemplateParameterFile 'azuredeploy.parameters.json' `

Executing the above cmdlets should result in the following output:

powershell - new-azureresourcegroup - create account with locks 2

If we execute the Get-AzureResourceLock cmdlet again, we would notice the resource lock, “collierlock”, successfully applied to just the newly created ‘collierimages2015’ storage account.

powershell - get-azureresourcelock 2 (masked)

One thing to notice about the ARM template for creating the resource lock on the storage account is the name of the nested resource. In the template (see screenshot below as well), you will notice the resource name is a concatenation of the storage account name and the name of the lock – specifically “/Microsoft.Authorization/collierlock”. In this example, “collierlock” is the name of the resource lock.

arm - resource lock name example

The resource name needs to reflect that this is a nested resource. Otherwise, if the resource name was something as simple as “collierlock”, attempting to validate the template with Test-AzureResourceGroupTemplate will result in an error such as the following:

Code    : InvalidTemplate

Message : Deployment template validation failed: ‘The template resource ‘collierlock’ for type ‘Microsoft.Storage/storageAccounts/providers/locks’ at line ’49’ and column ’14’ has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name.’.

Wrapping It Up

Azure’s Role Based Access Control features, along with resource locks, provide multiple options helping to secure critical Azure resources. RBAC roles provide a great way to limit actions against various types of Azure resources. However, an Owner can still delete a resource. Mistakes happen, and a valuable resource might be accidentally deleted. By leveraging a resource lock on those most crucial Azure resources, you can help to eliminate those “oops . . . did I delete that” moments.

The preceding sections demonstrated how to create a resource lock against an individual storage account, removing the resource lock, and applying a resource lock as part of an Azure Resource Manager template. For another example of using resource locks, please see Alexandre Brisebois’ post at https://alexandrebrisebois.wordpress.com/2015/05/26/protect-mission-critial-azure-virtual-machines-from-accidental-deletion/. In his post, Alexandre demonstrates how to create a resource lock against Azure Virtual Machines.


Special thanks to Neil Mackenzie, Charles Lamanna, and Ryan Jones for helping to review this post. Credit to Ryan Jones’ sample on GitHub for information on how to create the resource lock for the storage account.

Audit Logs for Azure Events

Note: This post is cross-post with http://blogs.msdn.com/b/cloud_solution_architect.

A common ask when working with Microsoft Azure is, “how can I view audit logs to determine who made changes to the subscription(s) and the related Azure resources?” With the new Audit Logs feature now available in the Azure Preview Portal (https://portal.azure.com), keeping track of changes becomes easier than ever.

Before getting started, I would like to point out that Dushyant Gill has an excellent post in which he provides one way to answer three very important questions:

  1. Who all has access to my subscriptions?
  2. What access does a specific user have on my subscription?
  3. Who gained (or lost) access to my subscriptions in the past n days?

In Dushyant’s post, he describes a PowerShell module he wrote that makes it easy to generate reports which answer the above questions.

In this post, I will describe one approach for working with the new Azure Audit Logs to determine what changed, and also how to view logs related to the addition or removal of co-administrators. Along with the PowerShell module described in Dushyant’s post, this should allow much more insights into the actions taken against an Azure subscription.

What Changed?

By opening the new Audit Logs blade in the Azure Preview Portal, you can view many of the events that occurred against the subscription.

Audit Logs - Single

The Audit Logs blade will show five key pieces of information for the list of operations:

  1. Operation name
  2. Level: Critical, Error, Warning, or Informational
  3. Status: Succeeded or Failed
  4. Resource
  5. Time

Note 1: Use the Filter action at the top of the Audit Logs blade to modify the operations displayed.

Note 2: Audit logs are available for only the Azure resources available in the Azure Preview Portal and/or the Azure Resource Manager API.


Clicking on a specific operation will open additional blades to view more detailed information.

Full Audit Logs

The Detail blade will allow you to view key pieces of information such as who made the change, when the change was made, what was the Azure resource and resource group affected, etc.

Audit Logs - Detail Blade

If the change is related to a role assignment (i.e. adding a user to one of the new Role Based Access Control (RBAC) related roles – Virtual Machine Contributor, Website Contributor, etc.), the Detail blade will show additional information to show the user that was added to the role. At the time of this writing, however, the user and role is displayed as a GUID and not the corresponding friendly name (e.g. email address or role name). It is anticipated this will be cleaned up in a feature update to the Azure Preview Portal. In the meantime, you can leverage a few Azure PowerShell cmdlets to piece together the relevant information.

In the Details blade, have a look at the PROPERTIES value. There are two key pieces of information here: the PrincipalId and the RoleDefinitionId.

Audit Logs - Add User to RBAC Role

For the cmdlets below, you will need to switch to the Azure Resource Manager mode in Azure Powershell by executing the command below.  Azure PowerShell version 0.8.15 is used in this post, although the cmdlets below first appeared in version 0.8.14.

Switch-AzureMode AzureResourceManager


To determine the role to which the user was assigned, use the Get-AzureRoleDefintion cmdlet. This cmdlet returns all the role definitions, so you will need to search for the specific definition (the GUID after “roleDefinition”) as indicated the PROPERTIES in the Detail blade.

Get-AzureRoleDefinition | where { ($_.Id -like "*de139f84-1756-47ae-9be6-808fbbe84772" )}


To get the user added to the role, use the Get-AzureAdUser cmdlet. For the -ObjectId parameter, use the PrincipalId value from the PROPERTIES in the Detail blade.

Get-AzureADUser -ObjectId b458cfbc-a101-45c1-9575-1ec43aefcc45


What about Co-Administrators and Management Certificates?

When it comes to permissions in Azure, there are three approaches that can be used: the co-administrator model, management certificates, and Role Based Access Control (RBAC). The co-administrator model has been the security model in working with Azure for quite some time. People that wanted to work with Azure (assuming they were not the subscription owner) could be granted access to the Azure subscription as a co-administrator. As a co-administrator, they could take any action they desired against any Azure service.  If non-interactive administrative access was needed, a management certificate could be added to the target subscription(s).

Going back to the earlier topic of what change was made and by whom – how can we tell when a co-administrator or management certificate was added to the subscription?

For management certificates, you can use the List Subscription Operations service management API call. There is an Operation Name parameter in the response that should include AddSubscriptionCertificate and RemoveSubscriptionCertificate for the respective action.


An astute observer of the MSDN documentation for List Subscription Operations will notice there is no corresponding operation for co-administrators. To obtain information about co-administrators being added or removed from a subscription, we can leverage the new audit logs available in the Azure Preview Portal and Azure Resource Manager API. Co-administrators in the Azure Management Portal actually correspond to the Owner role available in the Azure Preview Portal (and thus Azure Resource Manager). Adding or removing a co-administrator via the Azure Management Portal creates an event with Azure Resource Manager that is then logged. However, as of the time of this writing, the addition or removal of co-administrators is not yet reported in the Azure Preview Portal’s Audit Logs.

To get the audit logs related to the addition or remove of co-administrators, you can use the Get-AzureResourceProviderLog PowerShell cmdlet. This cmdlet retrieves the operations associated for a specific Resource Provider – in this case we would want operations against the Microsoft.Authoriztion provider. For example, to view the logs for a certain date range, you could execute a command similar to the following:

Get-AzureResourceProviderLog -ResourceProvider "Microsoft.Authorization" -StartTime "2015-03-10" -EndTime "2015-03-11" -DetailedOutput

A screenshot of the output is below. In the screenshot you’ll notice you can see the adminEmail and adminType for the user added via the Azure Management Portal.

Get-AzureResourceProviderLog - Add CoAdmins

Alternatively, you could get all the authorization events starting from a specific date up until the current time:

Get-AzureResourceProviderLog -ResourceProvider "Microsoft.Authorization" -StartTime "2015-03-11" -DetailedOutput

Get-AzureResourceProviderLog - Remove CoAdmins

It should be noted that there currently does seem to be at least two known bugs related to the shown information:

  1. If the removed co-admin is an Azure AD user (as opposed to a Microsoft Account), the adminEmail is empty
  2. The Caller value is not populating


But Wait! There’s More!!

The Get-AzureResourceProviderLog cmdlet shown above is just one of the new audit log cmdlets now available. It is easy to view the additional cmdlets by executing the following command:

get-help get-*Azure*log*
Name Description
Get-AzureSubscriptionIdLog Gets the operations associated with the current subscriptionId
Get-AzureResourceProviderLog Gets the operations associated with a Resource Provider
Get-AzureResourceLog Gets the operations associated with a ResourceId
Get-AzureResourceGroupLog Gets the deployment log for a resource group
Get-AzureCorrelationIdLog Gets the operations associated with a CorrelationId.



The new Audit Logs feature in the Azure Preview Portal, combined with new Azure PowerShell cmdlets, make it easier than ever to have insights into the changes made to an Azure subscription. Together, with the module described in Dushyant Gill’s post, many of the administrative actions taken against an Azure subscription and related resources are now easily viewable.

Please be sure to be using at least version 0.8.14 (that’s when the cmdlets mentioned in this post first appeared) of the Azure PowerShell cmdlets, and switch to use the AzureResourceManager mode for the cmdlets as well.

New Book – Microsoft Azure Essentials

In early February, Microsoft Press released a free new eBook entitled Fundamentals of Azure: Microsoft Azure Essentials. This is a book I, along with Azure MVP Robin Shahan spent several months on in late 2014. To see if finally be published is truly exciting!Book Cover

The goal of the book is to serve as primer for those new to cloud computing in general, and the Microsoft Azure platform specifically. We do not go too deep on the topics, and we don’t cover all the services available in Azure. We cover the core concepts people need to get started and be successful.

Writing a book is hard work – much harder than I originally anticipated. I had friends tell me it would be a lot of work – they were right! Writing a book on Azure adds to the challenge, I think. The reason is Azure is a constantly evolving platform. It’s hard to write a book on something that changes several times a month. We tried to keep up with the changes as best we could. But, inevitably some things will be inaccurate by the time to book is published or shortly thereafter.

Writing a book is also fun! While many nights and weekends were sacrificed to write this book, it was a very rewarding experience. I know I learned a lot while writing this book. I had many late night Skype calls with Robin to talk through how we wanted topics to flow. I had many great email conversations with the Azure MVPs that helped to provide early feedback on the book. A lot of work, but fun – and that’s the best kind of work!

You can find the book at http://aka.ms/fundamentalsofazure and get it in PDF, EPUB, or Mobi formats.

Topics covered in the book include.

  • Getting started with Azure: Understand what cloud computing is, visit the management
    portals, and learn about billing.
  • Websites and Cloud Services: Learn about Azure Websites, from deployment to monitoring, and gain an understanding of the web and worker roles used in Azure Cloud Services.
  • Virtual Machines: Explore the basic features of Azure Virtual Machines, including how to create, configure, and manage them.
  • Storage: Read about the basics of Azure Storage, including blobs, tables, queues, and file shares.
  • Virtual Networks: Learn the basics of virtual networks, including how to create one, and why a virtual network might be necessary. This also covers site-to-site and point-to-site networking, as well as ExpressRoute.
  • Databases: Explore two relational database options available in Azure: Azure SQL Database and SQL Server in Azure Virtual Machines.
  • Azure Active Directory: Explore basic features of Azure AD, including creating a directory, users and groups, and using the application gallery.
  • Management Tools: Explore three common tools for working with Azure: Visual Studio 2013 and the Azure SDK, Azure PowerShell cmdlets, and the Cross-Platform Command-Line Interface
  • Business Scenarios: Explore four common scenarios for utilizing Azure features: development and test, hybrid, application and infrastructure modernization, and Azure Mobile Services.

Determine the RDP User for Web/Worker Role

Note: This post is cross-post with http://blogs.msdn.com/b/cloud_solution_architect.

It is widely known that it is possible to add Remote Desktop (RDP) to a Cloud Service (web/worker role). Adding RDP is often done as a support mechanism – enabling the desire to see what is happening with the virtual machine and how the deployed code is working, or not.

Options to Enable Remote Desktop

There are two ways to add Remote Desktop support to a Cloud Service deployment:

1. Using Visual Studio, Remote Desktop can be added when the service is deployed by clicking the “Enable Remote Desktop for all roles” option in the publishing wizard. This approach will add two modules, RemoteAccess and RemoteForwarder, into the service model. You can read more on MSDN about setting up the connection in the service model.


2. Using the Azure Management Portal, for the desired Cloud Service, first navigate to the CONFIGURE section and then select the REMOTE option in the bottom command bar. You can read more about this approach at http://azure.microsoft.com/en-us/documentation/articles/cloud-services-how-to-configure/#remoteaccess.


Determine the Username

There are scenarios in which Remote Desktop is disabled when the Cloud Service is deployed, and only enabled in the event of a support incident when it is deemed RDP is the best support option. In this case, a co-administrator can enable RDP via the Azure Management Portal (as mentioned previously).  When first enabling RDP you set the username and password for the local machine account to be created on the role instance.  But what about after RDP is enabled – how do you know the local username that was created?  Is this information logged?

Enabling Remote Desktop in a Cloud Service is done via an extension. To learn more about extensions with Cloud Services and using them to enable Remote Desktop, I would encourage you to read Azure MVP Gaurav Mantri’s excellent blog post on the topic. Gaurav’s post shows how to add the Remote Desktop extension via the Service Management API. This information can be also useful when needing to retrieve details about a previously added Remote Desktop extension.

When Remote Desktop is enabled by using the extension model (e.g. enabling Remote Desktop via the portal), the operation logs in the Azure Management Portal (in the Management Services section) will show a new operation – AddHostedServiceExtension. If you were to look at the details for this extension, you would see something similar to the following:

<SubscriptionOperation xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
     <OperationParameters xmlns:d2p1="http://schemas.datacontract.org/2004/07/Microsoft.WindowsAzure.ServiceManagement">
               <d2p1:Value><?xml version="1.0" encoding="utf-16"?><Extension xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/windowsazure"><ProviderNameSpace>Microsoft.Windows.Azure.Extensions</ProviderNameSpace><Type>RDP</Type><Id>RDP-a2d56066-1a78-40a9-98f3-e0a941a55a59</Id><Version>1.*</Version></Extension></d2p1:Value>
          <SubscriptionCertificateThumbprint />

A key piece of information in the above XML is the “input” OperationParameter. There are two key pieces of data here – the Type of the extension is “RDP” and the ID.  The type of “RDP” lets us know that we are looking at the correct extension – the extension which added Remote Desktop support to the Cloud Service. The ID provides a unique identifier for the specific extension’s configuration information. With that ID, we can use the Get Extension operation in the Azure Service Management  API to retrieve public configuration, which will then provide the username created when enabling Remote Desktop.

In order to retrieve the public configuration, there are three steps you will need to perform:

  1. Set up authentication with the Azure Service Management API. See the Authenticating Service Management Requests topic in MSDN for more information.
  2. Make a request to the Get Extension operation, providing the RDP extension ID retrieved from the Azure Management Portal.  For example, https://management.core.windows.net/0bbbc191-xxxxxxxxxxxxxxxx/services/hostedservices/rdpdemo1/extensions/RDP-a2d56066-1a78-40a9-98f3-e0a941a55a59. This can be done using a tool such as Fiddler, or by writing code against the Service Management API. The response should contain the base64 encoded public configuration data.
  3. Decode the public configuration. Once decoded, you will be able to find the username used when enabling RDP.
<PublicConfig xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
     <Expiration>2015-02-04 05:00:00Z</Expiration>