List of time zones consumed by Azure

When creating Azure Automation scripts, you may have to reference time zones by name.  Below is a table of acceptable values you may use in your scripts to denote the proper time zone.

Name of Time Zone Time
Dateline Standard Time (UTC-12:00) International Date Line West
UTC-11 (UTC-11:00) Coordinated Universal Time-11
Hawaiian Standard Time (UTC-10:00) Hawaii
Alaskan Standard Time (UTC-09:00) Alaska
Pacific Standard Time (Mexico) (UTC-08:00) Baja California
Pacific Standard Time (UTC-08:00) Pacific Time (US & Canada)
US Mountain Standard Time (UTC-07:00) Arizona
Mountain Standard Time (Mexico) (UTC-07:00) Chihuahua, La Paz, Mazatlan
Mountain Standard Time (UTC-07:00) Mountain Time (US & Canada)
Central America Standard Time (UTC-06:00) Central America
Central Standard Time (UTC-06:00) Central Time (US & Canada)
Central Standard Time (Mexico) (UTC-06:00) Guadalajara, Mexico City, Monterrey
Canada Central Standard Time (UTC-06:00) Saskatchewan
SA Pacific Standard Time (UTC-05:00) Bogota, Lima, Quito, Rio Branco
Eastern Standard Time (Mexico) (UTC-05:00) Chetumal
Eastern Standard Time (UTC-05:00) Eastern Time (US & Canada)
US Eastern Standard Time (UTC-05:00) Indiana (East)
Venezuela Standard Time (UTC-04:30) Caracas
Paraguay Standard Time (UTC-04:00) Asuncion
Atlantic Standard Time (UTC-04:00) Atlantic Time (Canada)
Central Brazilian Standard Time (UTC-04:00) Cuiaba
SA Western Standard Time (UTC-04:00) Georgetown, La Paz, Manaus, San Juan
Newfoundland Standard Time (UTC-03:30) Newfoundland
E. South America Standard Time (UTC-03:00) Brasilia
SA Eastern Standard Time (UTC-03:00) Cayenne, Fortaleza
Argentina Standard Time (UTC-03:00) City of Buenos Aires
Greenland Standard Time (UTC-03:00) Greenland
Montevideo Standard Time (UTC-03:00) Montevideo
Bahia Standard Time (UTC-03:00) Salvador
Pacific SA Standard Time (UTC-03:00) Santiago
UTC-02 (UTC-02:00) Coordinated Universal Time-02
Azores Standard Time (UTC-01:00) Azores
Cape Verde Standard Time (UTC-01:00) Cabo Verde Is.
Morocco Standard Time (UTC) Casablanca
UTC (UTC) Coordinated Universal Time
GMT Standard Time (UTC) Dublin, Edinburgh, Lisbon, London
Greenwich Standard Time (UTC) Monrovia, Reykjavik
W. Europe Standard Time (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
Central Europe Standard Time (UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
Romance Standard Time (UTC+01:00) Brussels, Copenhagen, Madrid, Paris
Central European Standard Time (UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb
W. Central Africa Standard Time (UTC+01:00) West Central Africa
Namibia Standard Time (UTC+01:00) Windhoek
Jordan Standard Time (UTC+02:00) Amman
GTB Standard Time (UTC+02:00) Athens, Bucharest
Middle East Standard Time (UTC+02:00) Beirut
Egypt Standard Time (UTC+02:00) Cairo
Syria Standard Time (UTC+02:00) Damascus
E. Europe Standard Time (UTC+02:00) E. Europe
South Africa Standard Time (UTC+02:00) Harare, Pretoria
FLE Standard Time (UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
Turkey Standard Time (UTC+02:00) Istanbul
Israel Standard Time (UTC+02:00) Jerusalem
Kaliningrad Standard Time (UTC+02:00) Kaliningrad (RTZ 1)
Libya Standard Time (UTC+02:00) Tripoli
Arabic Standard Time (UTC+03:00) Baghdad
Arab Standard Time (UTC+03:00) Kuwait, Riyadh
Belarus Standard Time (UTC+03:00) Minsk
Russian Standard Time (UTC+03:00) Moscow, St. Petersburg, Volgograd (RTZ 2)
E. Africa Standard Time (UTC+03:00) Nairobi
Iran Standard Time (UTC+03:30) Tehran
Arabian Standard Time (UTC+04:00) Abu Dhabi, Muscat
Azerbaijan Standard Time (UTC+04:00) Baku
Russia Time Zone 3 (UTC+04:00) Izhevsk, Samara (RTZ 3)
Mauritius Standard Time (UTC+04:00) Port Louis
Georgian Standard Time (UTC+04:00) Tbilisi
Caucasus Standard Time (UTC+04:00) Yerevan
Afghanistan Standard Time (UTC+04:30) Kabul
West Asia Standard Time (UTC+05:00) Ashgabat, Tashkent
Ekaterinburg Standard Time (UTC+05:00) Ekaterinburg (RTZ 4)
Pakistan Standard Time (UTC+05:00) Islamabad, Karachi
India Standard Time (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi
Sri Lanka Standard Time (UTC+05:30) Sri Jayawardenepura
Nepal Standard Time (UTC+05:45) Kathmandu
Central Asia Standard Time (UTC+06:00) Astana
Bangladesh Standard Time (UTC+06:00) Dhaka
N. Central Asia Standard Time (UTC+06:00) Novosibirsk (RTZ 5)
Myanmar Standard Time (UTC+06:30) Yangon (Rangoon)
SE Asia Standard Time (UTC+07:00) Bangkok, Hanoi, Jakarta
North Asia Standard Time (UTC+07:00) Krasnoyarsk (RTZ 6)
China Standard Time (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi
North Asia East Standard Time (UTC+08:00) Irkutsk (RTZ 7)
Singapore Standard Time (UTC+08:00) Kuala Lumpur, Singapore
W. Australia Standard Time (UTC+08:00) Perth
Taipei Standard Time (UTC+08:00) Taipei
Ulaanbaatar Standard Time (UTC+08:00) Ulaanbaatar
Tokyo Standard Time (UTC+09:00) Osaka, Sapporo, Tokyo
Korea Standard Time (UTC+09:00) Seoul
Yakutsk Standard Time (UTC+09:00) Yakutsk (RTZ 8)
Cen. Australia Standard Time (UTC+09:30) Adelaide
AUS Central Standard Time (UTC+09:30) Darwin
E. Australia Standard Time (UTC+10:00) Brisbane
AUS Eastern Standard Time (UTC+10:00) Canberra, Melbourne, Sydney
West Pacific Standard Time (UTC+10:00) Guam, Port Moresby
Tasmania Standard Time (UTC+10:00) Hobart
Magadan Standard Time (UTC+10:00) Magadan
Vladivostok Standard Time (UTC+10:00) Vladivostok, Magadan (RTZ 9)
Russia Time Zone 10 (UTC+11:00) Chokurdakh (RTZ 10)
Central Pacific Standard Time (UTC+11:00) Solomon Is., New Caledonia
Russia Time Zone 11 (UTC+12:00) Anadyr, Petropavlovsk-Kamchatsky (RTZ 11)
New Zealand Standard Time (UTC+12:00) Auckland, Wellington
UTC+12 (UTC+12:00) Coordinated Universal Time+12
Fiji Standard Time (UTC+12:00) Fiji
Tonga Standard Time (UTC+13:00) Nuku'alofa
Samoa Standard Time (UTC+13:00) Samoa
Line Islands Standard Time (UTC+14:00) Kiritimati Island

[Tutorial] Using Fiddler to debug SAML tokens issued from ADFS

Problem:

Many applications want to federate with leverage certain attributes like nameid (nameidentifier), but the problem is the format is wildly different from one application to another.  In this case, one application might use a unique value like an employee ID, another UPN, another email address, and so on.  Or maybe it isn't an attribute, but you are leveraging SHA1 as your signature hashing algorithm and the application is looking for MD5.

In this case, sometimes you may not be sure what you are sending to the application and are looking to the vendor to help you understand what you need to change in ADFS or if you are working on a custom application, need help debugging your claims rules to integrate into that application.  In this case, I will show you how to leverage Fiddler to acquire the SAML Tokens issued by ADFS to validate what attributes/values you are passing to the federate application.

Tutorial:

  1. Grab the latest copy of Fiddler from their website (it is a free download)
    1. https://www.telerik.com/download/fiddlerDownload Fiddler
  2. Install Fiddler on your local machine
    1. Double click fiddlersetup.exe
      Run fiddlersetup
    2. Agree to the End User License Agreement
      Fiddler Install - Accept EULA
    3. Set the installation directory and click Install
      Fiddler Install - Destination Folder
    4. Close the setup wizard
      Fiddler Install - Close Installation
  3. Launch Fiddler
    Launch Fiddler - Windows 10
  4. Click Cancel if prompted about AppContainers
    Fiddler - AppContainer Configuration - Cancel
  5. With Fiddler open click on Tools -> Telerik Fiddler Options...
    Fiddler - Tools - Telerik Fiddler Options
  6. Click on the HTTPS tab and check Decrypt HTTPS traffic and click OK
    1. Note: you may be prompted to trust a certificate.  You must trust the certificate so Fiddler can intercept your encrypted traffic and decrypt it.  Fiddler will not permanently capture traffic when the application is closed.
      Fiddler - Tools - Telerik Fiddler Options - HTTPS - Decrypt HTTPS traffic
  7. Close out of Fiddler
    Fiddler - Close
  8. Open Fiddler
    Launch Fiddler - Windows 10
  9. Open up Internet Explorer in one window and Fiddler side-by-side.  Drag the Crosshair icon onto Internet Explorer.  This will target only traffic in this process (browser window) to help filter down intercepted traffic.
    Fiddler - Process Selector - Drag Drop
  10. Select the X icon with a dropdown and click Remove all to clear your trace
    Fiddler - X - Remove All
  11. Go to the url of the federated application and login.  In this case, I am going to use https://outlook.com/owa/jackstromberg.com; once you have logged into the application or received the error to your application upon login, click File - Capture Traffic to stop the logs
    Fiddler - File - Capture Traffic - ADFS
  12. Within your logs, look for the last 200 response from your ADFS server before being redirected to your application (which will not show up as a 302, since we are posting to the new URL)
    Fiddler - HTTPS 200 - ADFS - SAML Post
  13. Click on the Inspectors tab, and select the Raw tab at the bottom and copy the value from the hidden input tag with the name of wresult
    Fiddler - Inspectors - Raw - wresult - encoded html
  14. Paste the encoded HTML into my HTML Encoder/Decoder in the Encoded text box and click Decode.
    1. Note: The encoder/decoder is all JavaScript based that functions client/side, so no data will leave your network.
      JackStromberg - HTML Encoder - Decoder - SAML
  15. Copy the Decoded HTML and paste it into an XML formatter of your choice.  Here I am using Bing:
    Bing - XML Formatter - SAML Token
  16. Copy the result into Notepad and you can now read the information
    Notepad - SAML Decoded - Formatted XML

Going into the claim and how it works is outside the scope of this tutorial, but as you can see in the last screenshot above we have the raw SAML token we will send to the relying party trust to consume.  At this point, the vendor can be involved to help troubleshoot any values or attributes that are in an incorrect format.

[How-To] Deploy HUB Licensed VMs in Azure

What is HUB and why should I use it?

For customers that are looking to go to Azure and help cut down on some of the running costs by utilizing existing licensing they own from on-premises, Microsoft has released a program called Hybrid Use Benefit (HUB).  The Hybrid Use Benefit program essentially allows you to run  VMs in Azure at a reduced rate (cost of a Linux VM for example), under the assumption that you have volume license keys covering the core totals of VMs running in Azure.

Official information on this program can be found here: https://azure.microsoft.com/en-us/pricing/hybrid-use-benefit/

A Microsoft employee has created some instructions on how Microsoft customers can take use of this program.  Unfortunately, as outlined in the document, there is no way as of 6/27/2016 to take an existing VM in Azure and convert it to the HUB program.  A VM must originate from on-premises in order to take advantage of this program, there are no workarounds such as building the VM in Azure, downloading it to on-prem, and reuploading it back to Azure.  In this case, this article will cover the necessary steps (step by step) on getting a "HUB" VM deployed in Azure.

Update: October 24, 2016: HUB is now supported on Azure Site Recovery for failed over instances to Azure from another datacenter.  Information on leveraging HUB for ASR instances can be found here: https://azure.microsoft.com/en-us/blog/hybrid-use-benefit-migration-with-asr/

Goal: This article will focus on 3 items:

  1. How to properly configure a VHD for the HUB program
  2. How to upload the VHD into Azure
  3. How to deploy VMs from your VHD

1. How to properly configure a VHD for the HUB program

There are two ways you can bring a HUB image into Azure.  You can convert the ISO from Microsoft to a VHD directly, or you can install Hyper-V, update/customize the VM, and generalize it.

In this tutorial, we will go over converting the Microsoft provided ISO to VHD, under the assumption you do not have Hyper-V installed.  In the scenario where you do not have Hyper-V, but you want to customize the image before uploading it into Azure, I would recommend installing the Hyper-V role on your Windows 7/10 machine and creating the VHD from that.  The only caveat you will run into is you must run SysPrep before uploading the VHD into Azure, as outlined here.

Hyper-V Way

For the Windows 7/10 machines, you can install the Hyper-V role by navigating to Programs and Features, select Turn Windows features on or off
Control Panel - Programs and Features - Turn windows features on or off

Check Hyper-V from the list.
Control Panel - Programs and Features - Turn windows features on or off - Hyper-V

Additionally, installation via PowerShell or DISM is covered in this Microsoft blog post: https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/quick_start/walkthrough_install

Again, ensure after making changes to your VHD, you generalize the machine and shut it down as outlined here: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-upload-image/

PowerShell Way

A few Microsoft employees/consultants have released a PowerShell script that will take a Microsoft provided ISO and convert/generalize it into VHD format.  We can simply take this converted VHD and upload it into Azure as-is.  Please note, the only downside to creating the VM this way is that the machine may not be completely patched, so you will have to rely on the machines doing Windows Updates once they make it into the lands of Azure.

Pro Tip: If you are going to create the VHD from an ISO, I would recommend doing this from an Azure VM.  Since the VHD/disk we are creating will originate from the source media of a "local instance", your VM will deploy fine with HUB licensing.  The advantage of creating the VM in Azure is the upload of your VM will take significantly less time due to the high throughput of egress traffic in Azure.  When going through this tutorial, I ended up maxing out my storage account's read rate before hitting network connectivity bottlenecks.  Please note, bandwidth fees may apply in Azure for utilizing this method though.

  1. Download the Convert-WindowsImage.ps1 script from Microsoft
    1. https://gallery.technet.microsoft.com/scriptcenter/Convert-WindowsImageps1-0fe23a8f
  2. Download your Windows Server ISO from the Microsoft Volume Licensing center
    1. https://www.microsoft.com/Licensing/servicecenter/default.aspx
  3. Open PowerShell as an Administrator
    Server 2012 - PowerShell - Run as Administrator
  4. Navigate to the directory that contains both the ISO and the Covert-WindowsImage.ps1 script
    Convert-WindowsImage and Windows Server ISO - PowerShell
  5. Execute the following command to pre-load (dot-source) the PowerShell function
    Convert-WindowsImage and Windows Server ISO - PowerShell - Load Function

    . .\Convert-WindowsImage.ps1
  6. Execute the following command
    Convert-WindowsImage and Windows Server ISO - PowerShell - Execute Function

    Convert-WindowsImage -SourcePath "en_windows_server_2012_r2_with_update_x64_dvd_6052708.ISO" -VHDFormat VHD -Edition "ServerDataCenterCore" -VHDPartitionStyle MBR -BCDinVHD NativeBoot -ExpandOnNativeBoot:$false -RemoteDesktopEnable -Verbose
  7. You should receive a "Done" message once the VHD has been created
    Convert-WindowsImage and Windows Server ISO - PowerShell - Execute Function -Completed

2. How to upload the VHD into Azure

First, you will need the latest Azure PowerShell Modules.  These can be downloaded for free from the Azure website.  If you are new to Azure, this will be a link to the Web Platform installer, in which the link below should automatically select the Azure PowerShell modules to be downloaded.  You do not need the Command Line installer if prompted, only the Azure PowerShell Modules.

https://www.microsoft.com/web/handlers/webpi.ashx/getinstaller/WindowsAzurePowershellGet.3f.3f.3fnew.appids

Web Platform Installer 5 - Microsoft Azure PowerShell

Once installed, complete the instructions below.

  1. Open up PowerShell
    Server 2012 - PowerShell - Run as Administrator
  2. Login to your Azure account
    Login-AzureRmAccount

    Login-AzureRmAccount
  3. Execute the following command below, substituting in the correct values applicable to your environment:
    -RessourceGroupName - Specifies the name of the resource group of the virtual machine.
    -Destination - Specifies the URI of a blob in Blob Storage. The parameter supports SAS URI, although patching scenarios destination cannot be an SAS URI.  My URL shows Premium storage, but Premium storage is not required for HUB.
    -LocalFilePath - Specifies the path of the local .vhd file.
    Login-AzureRmAccount - Add-AzureRmVhd - Completed

    Add-AzureRmVhd -ResourceGroupName Test -Destination "https://armpremiumstoragetest.blob.core.windows.net/vhds/WindowsServer2012R2-HUB-Image.vhd" -LocalFilePath "E:\Blog\9600.17415.amd64fre.winblue_r4.141028-1500_Server_ServerDatacenterCore_en-US.vhd"

3. How to deploy VMs from your VHD

Copy the template below:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vmName": {
      "type": "string",
      "metadata": {
        "description": "Name of the VM you wish to deploy"
      }
    },
	"VMStorageAccount": {
      "type": "string",
      "metadata": {
        "description": "This is the name of the your storage account to deploy the VM to"
      }
    },
	"virtualNetworkName": {
      "type": "string",
      "metadata": {
        "description": "Name of the virtual network the VM should be deployed to"
      }
    },
	"subnetName": {
      "type": "string",
      "metadata": {
        "description": "Name of the subnet the VM should be deployed to"
      }
    },
	"publicIPAddressName": {
      "type": "string",
      "metadata": {
        "description": "Name of the public IP address for your VM."
      }
    },
    "dnsLabelPrefix": {
      "type": "string",
      "metadata": {
        "description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error."
      }
    },
    "adminUserName": {
      "type": "string",
      "metadata": {
        "description": "UserName for the Virtual Machine"
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Password for the Virtual Machine"
      }
    },
	"publicIPAddressType": {
      "type": "string",
      "allowedValues": [
        "Dynamic",
        "Static"
      ],
	  "defaultValue": "Dynamic",
      "metadata": {
        "description": "IP Address type for the public IP of the VM"
      }
    },
    "vmSize": {
      "type": "string",
      "metadata": {
        "description": "This is the size of your VM"
      },
	  "defaultValue": "Standard_DS1_v2"
    }
  },
  "variables": {
    "location": "[resourceGroup().location]",
    "nicName": "[concat(parameters('vmName'),'nic')]",
	"osDiskVhdUri": "https://myosdiskvhduri.blob.core.windows.net/vhds/myimage.vhd",
	"osType": "Windows",
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
    "subnet1Ref": "[concat(variables('vnetID'),'/subnets/',parameters('subnetName'))]",
    "osDiskVhdName": "[concat('https://',parameters('VMStorageAccount'),'.blob.core.windows.net/vhds/',parameters('vmName'),'-osDisk.vhd')]",
    "apiVersion": "2015-06-15"
  },
  "resources": [
    {
      "apiVersion": "[variables('apiVersion')]",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[parameters('publicIPAddressName')]",
      "location": "[variables('location')]",
      "properties": {
        "publicIPAllocationMethod": "[parameters('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[parameters('dnsLabelPrefix')]"
        }     
      }
    },
    {
      "apiVersion": "[variables('apiVersion')]",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[variables('nicName')]",
      "location": "[variables('location')]",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('publicIPAddressName'))]"
              },
              "subnet": {
                "id": "[variables('subnet1Ref')]"
              }
            }
          }
        ]
      }
    },
    {
      "apiVersion": "[variables('apiVersion')]",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[parameters('vmName')]",
      "location": "[variables('location')]",
      "dependsOn": [
        "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
      ],
      "properties": {
        "licenseType": "Windows_Server",
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
                 },
        "storageProfile": {
          "osDisk": {
            "name": "[concat(parameters('vmName'),'-osDisk')]",
            "osType": "[variables('osType')]",
            "caching": "ReadWrite",
            "createOption": "FromImage",
            "image": {
              "uri": "[variables('osDiskVhdUri')]"
            },
            "vhd": {
              "uri": "[variables('osDiskVhdName')]"
            }
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
             "enabled": "true",
             "storageUri": "[concat('https://',parameters('VMStorageAccount'),'.blob.core.windows.net')]"
          }
        }
      }
    }
  ]
}
  1. Login to the Azure Portal
    1. https://portal.azure.com
  2. Select Browse, click Templates, click Add
    Azure - Browse - Templates - Add
  3. Type in a Name and Description, click OK
    Azure - Browse - Templates - Add - General
  4. Paste in the template above, ensure you change the osDiskVhdUri, and click OK
    Azure - Browse - Templates - Add - General - change uri
  5. Once you have deploy the script, click Add, select your template, and click DeployDeploy from Template

At this point, you should be able to deploy from the template and create your VM from the HUB licensed VHD! 🙂

Notes: The above script takes into account that you are deploying against standard storage.  You may need to edit the above script if you want to deploy to premium storage as diagnostics data does not support being deployed to a Premium Storage account as of 6/27/2016.

Notes: The above script assumes your Virtual Network and Subnet have been previously created.  It will not create a virtual network and subnet if they do not exist.

Enable SSO (Single Sign On) to On-Premises Exchange OWA (Outlook Web Access) via Azure AD Application Proxy

Edit: This scenario is unofrtunately no longer supported by Microsoft.  More details can be found here: https://learn.microsoft.com/microsoft-365/enterprise/configure-exchange-server-for-hybrid-modern-authentication

Wouldn't it be awesome to be able to do the following with Outlook Web Access being published in your on-premises environment today?

  • Cheap proxy solution to prevent direct internet access to your servers
  • Mask the IPs of your on-premises infrastructure
  • Enable Azure MFA (Multi-Factor Authentication) for OWA?
  • Have a Single-Sign on experience into Outlook Web Application via federation?
  • Have the application be selectable from your "My Apps" page (myapps.microsoft.com)
  • Have the application be selectable from the "Waffle Menu" of Office 365

If you are looking for any of the above, you are in-luck and we can enable this easily through Azure AD Application Proxy.  If you organization is using Office 365 or Azure AD already and have licensing for Azure AD Premium or Basic, you are good to go.  If you have the Enterprise Mobility Suite, this will grant you to Azure AD Premium licensing which should make you good to go as well.

Configuration

  1. Prerequisite: Enable Kerberos Authentication for Outlook Web Access On-Premises
    1. Login to one of your domain controllers and open up Active Directory Users and Computers
      Server Manager - Active Directory Users and Computers
    2. Find the Computer object within your organization we will run the Azure AD Connector on later in the tutorial and right click Properties on it
      Active Directory Users and Computers - Computers - OWA - Properties
    3. Select the Delegation tab, select Trust this computer for delegation to specified services only, check Use any authentication protocol, and click on Add...
      Active Directory Users and Computers - Computers - OWA - Properties - Delegation - Add
    4. Select Users or Computers...
      Active Directory Users and Computers - Computers - OWA - Properties - Delegation - Add - users or Computers
    5. Type in the machine name and click OK
      Active Directory Users and Computers - Computers - OWA - Properties - Delegation - Add - users or Computers - Select Users or Computers
    6. Select http and click OK
      Active Directory Users and Computers - Computers - OWA - Properties - Delegation - Add - users or Computers - http
    7. Click OK on the Add Services page
  2. Pre-Requisite: Enable Exchange On-Premises to use Integrated Windows Authentication (instructions for Exchange 2010 or 2013 can be found below)
    1. Exchange 2010
      1. Open the Exchange Management Console for your Exchange server
        Exchange Management Console (2010)
      2. Expand Server Configuration, select Client Access, under Outlook Web App, right click on your web app and select Properties
        Exchange Management Console (2010) - Outlook Web App
      3. Select the Authentication tab and check Use one or more standard authentication methods.  Once checked, check Integrated Windows authentication and click the Apply and OK buttons.
        Exchange Management Console (2010) - Outlook Web App Properties - Authentication - Integrated Windows Authentication
      4. Open a command prompt
        cmd as Administrator
      5. Execute the iisreset command
        cmd - iisreset
    2. Exchange 2013
      1. Open the Exchange Administrative Center
        Exchange Administrative Center (2013)
      2. Login to the admin center, click on Servers and select the Virtual Directories tab
        Exchange Administrative Center (2013) - admin center - servers -virtual directories
      3. Select server and then double click on the OWA Virtual Directory and select the applications tab
        Exchange Administrative Center (2013) - admin center - servers -virtual directories - owa - authentication
      4. On the authentication tab, select Use one or more standard authentication methods, select Integrated Windows authentication, and click save
        Exchange Administrative Center (2013) - admin center - servers -virtual directories - owa - authentication - integrated windows authentication
      5. Open a command prompt
        Elevated Command Prompt
      6. Execute the iisrest command
        cmd - iisreset
  3. Login to the Azure Portal
    1. https://portal.azure.com
  4. Select All services -> Azure Active Directory on the left side
  5. Select Application proxy in the sub blade and select + Configure app

  6. Enter in the following information for the application:
    1. Name: Outlook Web Access
    2. Internal URL: https://owa.yourdomain.com/owa/ (this is the internal URL to owa)
    3. Pre-Authentication: Azure Active Directory
    4. Connector Group: Default
    5. Click + Add

    6. Select OK if not prompted about having a connector
  7. Once your application is created, you should be redirected to Azure Active Directory -> Enterprise Applications -> Outlook Web Access.  On this blade, select Single sign-on and then select the Windows Integrated Authentication button

  8. Use the following configuration
    1. Internal Application SPN: http/owa.yourdomain.com
      1. This is the Service Principal Name to the Exchange Server.  The value for this was provided earlier in this tutorial.
    2. Delegated Login Identity: User Principal Name
    3. Click Save
    4. Note: If you cannot do Kerberos based authentication (Integrated Windows Authentication) in your environment, you can Discard the changes continue to use Azure AD Application proxy, however the end user will be prompted for credentials just as if they browsed directly to OWA.
  9. Go back to All Services -> Azure Active Directory -> Application Proxy and click the Download connector service button

      

    1. Click the Accept terms & Download button
    2. Note: Although the download has a generic name, the download is customized specifically for your application (Outlook Web Access in this case).  If you create other applications within your Azure AD tenant, make sure you always use the Download button inside of each application so it generates the correct installer.
  10. Copy the AADApplicationProxyConnectorInstaller.exe connector to any server in your environment that can access your OWA instance internally and run the installer
    AADApplicationProxyConnectorInstaller Downloaded
  11. Check I agree to the license terms and conditions and click Install
    Microsoft Azure Active Directory Application Proxy Connector - I agree
  12. Type in your Global Administrator credentials to register the agent to your Azure AD tenant and click Sign in
    Microsoft Azure Active Directory Application Proxy Connector - Credential Prompt
  13. Click Close if it shows Setup Success
    Microsoft Azure Active Directory Application Proxy Connector - SuccessOptional: You can run the Connector Troubleshooter if you would like.  It will install a quick application that will show you the results of the test in your web browser once it has completed.
    Azure AD Application Proxy Connector Troubleshooter
  14. Go back to the Azure Portal and navigate to Azure Active Directory -> Enterprise Applications -> Outlook Web Access.  Select Users and groups and click the +Add user button to assign the group or users that should use the application.
      

    1. Note: This group could be synchronized from on-premises to Azure AD or created in the cloud
    2. Note: Assigning a user or group to this application will automatically make the application show up in the My Apps portal
    3. Note: Users or Groups must be defined to use the application or they will receive an error upon logging in

Test

  1. Login to https://myapps.microsoft.com as one of the assigned users to the Outlook Web Access application
  2. Select the Outlook Web Access application

If all went well, you should be logged into Outlook Web Access on-premises and see your corresponding mailbox.  At this point, I would proceed with adding a vanity domain name that matches your organization as well as corresponding SSL certificate for the domain name instead of leveraging the default msapprpoxy.net domain name.  Additionally, you can always find a nice little icon for the application to make it look like OWA as well 🙂

Creating self-signed certificates with makecert

If you are even in a bind and need a quick self-signed SSL cert and have the Windows SDK installed on your machine, there's a chance you may have the makecert utility and can generate a quick self-signed SSL cert.

The command is as follows:

makecert -r -pe -n "CN=SelfSigned SSL" -a sha1 -ss My -len 2048 -sy 24 -b 01/01/2015 -e 01/01/2050

A complete list of each of the switches can be found here:
https://msdn.microsoft.com/library/windows/desktop/aa386968.aspx

Additionally, a nice MSDN article has been posted on this subject as well: https://msdn.microsoft.com/en-us/library/ff699202.aspx

MakeCert is available as part of the Windows SDK, which you can download from http://go.microsoft.com/fwlink/p/?linkid=84091

[How To] Establish a Point-to-Site VPN connection between Azure and a client

In this guide, we will go over setting up a Point-to-Site VPN connection that will allow an on-premise virtual machine talk to a resource/VM that is hosted in Microsoft Azure.  In this guide, we will take advantage of the new Preview Portal for this guide.

  1. Login to the Microsoft Azure Preview Portal
    1. https://portal.azure.com/
  2. Create a VNET
    1. Click on the + New button
      Azure - New button
    2. Select Networking, Virtual NetworkAzure - Create - Networking - Virtual Networking
    3. Type in a Name for your VNET
      Azure - Create - Networking - Virtual Networking - Name
    4. Select Address Space, configure the parameters of your cloud based virtual network, and click OK
      Azure - Create - Networking - Virtual Networking - Address space
    5. Select Resource Group, Create a new resource group, enter a name for the group and click OK
      Azure - Create - Networking - Virtual Networking - Resource Group - Create resource group
    6. Click Location and select the location closest to you
      Azure - Create - Networking - Virtual Networking - Location - East US 2
    7. Click Create
      Azure - Create - Networking - Virtual Networking - Virtual Network - Create
  3. With the Virtual Network blade still open, select VPN connections
    Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections
  4. On the New VPN Connection blade, select Point-to-site, in the Address Spaces prompts, enter in each of your subnets, ensure Create gateway immediately is checked and then click on Subnet, size and routing type
    Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections - New VPN Connection
  5. Select Subnet on the Gateway configuration blade
    Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections - Gateway configuration
  6. Enter in a new subnet that will be used for clients connecting through the VPN tunnel and then click OK
    Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections - Gateway configuration - Add subnet
  7. Click OK on the Gateway configuration blade
    Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections - Gateway configuration w Subnet
  8. Click OK on the New VPN Connection blade
  9. If you refresh the Azure portal, you should now see on the VPN connections section that it is trying to create the gateway.  Based on my experience, this process can take awhile to setup (10-15 minutes), so this is something you will want to provision and then get up and grab a cup of coffee
    1. In the process of provisioning
      Azure - VPN Connections - Creating the gateway
    2. Provisioned gateway
      Azure - VPN Connections - Gateway created
  10. Generate and upload certificates
    1. Generate a self-signed SSL certificate via command prompt
      1. You can use whatever utility you are most comfortable with; I'd recommend using makecert if you have Visual Studio installed (can be found here: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\x64).  If you don't have Visual Studio, you can use openSSL
      2. Using Visual Studio's command prompt
        1. Execute the following command to generate a root certificate
          1. makecert -sky exchange -r -n "CN=AzureVLANRootCertificate" -pe -a sha1 -len 2048 -ss My "AzureVLANRootCertificate.cer"
        2. Execute the following command to generate a client certificate
          1. makecert.exe -n "CN=AzureVLANClientCertificate" -pe -sky exchange -m 96 -ss My -in "AzureVLANRootCertificate" -is my -a sha1
        3. Notes: The root certificate and client certificate can have whatever name you wish, just ensure that in the client certificate, the root certificate's name matches the root certificate you just generated
  11. Upload your root certificate
    1. On the Virtual Network blade, click on VPN Connections
      Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned
    2. Click on Point-to-siteAzure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned - VPN connections - Point-to-Site
    3. Click on Manage Certificate
      Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned - VPN connections - Point-to-Site - Manage Certificate
    4. Click on Upload
      Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned - VPN connections - Point-to-Site - Manage Certificate - Upload
    5. Select your certificate and click OK
      Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned - VPN connections - Point-to-Site - Manage Certificate - Upload - Certificate
  12. Establish a connection
    1. Go back to the Point-to-site connection blade and select the VPN Client for your supported OS
      Azure - Create - Networking - Virtual Networking - Virtual Network - VPN Connections Provisioned - VPN connections - Point-to-Site - VPN Client 64-bit
    2. Save and Run the VPN installer
      Azure - Save - Point-to-site VPN
    3. Install the VPN Client by clicking on Yes
      Azure - Save - Point-to-site VPN - Install
    4. Connect to Azure via the VPN connection
      Windows 8 - Networks - CloudVNET
    5. Click Connect on the VPN dialog
      Windows 8 - Networks - CloudVNET - CloudVNET
    6. Click Continue to temporarily add routes to Azure while the VPN connection is established
      Windows 8 - Networks - CloudVNET - CloudVNET Routes
  13. Verify you are connected via the Point-to-site connections blade
    Azure - Networking - Point-to-site VPN connection established

At this point, this specific client that is connected to Azure should have access to all internal devices on the Server's subnet we created in step 2-4! 🙂

Notes:

Official MSDN information can be found here: https://msdn.microsoft.com/en-us/library/azure/dn133792.aspx

Azure - Error Number: 18456 Error Code: -2146232060 Message: Login failed for user 'yourusername'

Symptom: When trying o provision a new website or database, you receive the following error message:

Error Number: 18456 Error Code: -2146232060 Message: Login failed for user 'yourusername'
Error Number 18456 Error Code -2146232060 Message Login failed for user yourusername

Solution: The username or password you specified for your database is incorrect; you should be using the credentials your provided when you provisioned your existing SQL server, not what you would like as a virtual user to provision with the new database.

---

Since it is early this AM, I rushed through the portal thinking, oh since I am creating a new database, the portal will prompt me to create a new virtual account; this is not intended functionality. In the screenshot below you can see we select "Create a new SQL database"

Create Website - Create a new SQL database

In this scenario, I actually wish to use an existing database server I have already provisioned.  When using an existing database, you will need to provide the credentials to the server itself so the new database can be provisioned.  If you wish to add a separate user account that only has access to this database for a specific application, which is a recommended practice for security, you will need to use SQL Manager, Visual Studio, or another utility to connect to the database and provision a new virtual user account with privileges to this particular database.

New Website - Custom Create - Specify database settings - existing server

 

Exporting TPM Owner Key and BitLocker Recovery Password from Active Directory via PowerShell

Synopsis: When looking up a BitLocker Recovery Password or TPM Owner Key, the process can be quite laborious.  This post contains a PowerShell script to help automate the process of manually looking at attributes in Active Directory to pull such information.

Download a copy of the script here (make sure to remove the .txt at the end): Get-TPMandBitlockerInfo.ps1.txt

Run the script with PowerShell

Get-TPMOwnerInfo - Run with PowerShell

Here are the results it should return
Get-TPMOwnerInfo - PowerShell

 

Here is a copy of the script in Plain Text

<#
.SYNOPSIS
    Automates the process on gathering BitLocker recovery password and TPM owner password.

.DESCRIPTION
    This script will lookup multiple attribute in Active Directory and display the correlating
    values that hold sensitive BitLocker information.  Additionally, the TPM Owner Password
    can be exported to a .tpm file, which can be used to make changes to the correlating machine.

.NOTES
    File Name      : Get-TPMandBitlockerInfo.ps1
    Author         : Jack Stromberg (jackstromberg.com)
    Prerequisite   : PowerShell V2 over Vista and upper
    Version History: 2/5/2015 (original release)

.LINK
    Script posted over at:
    http://jackstromberg.com/2015/02/exporting-tpm-owner-key-and-bitlocker-recovery-password-from-active-directory-via-powershell/
#>

clear
Write-Host "~Enter in the correct credentials to access the BitLocker and TPM Owner attributes~"
$UserName = Read-Host "Enter User Name" 
$Password = Read-Host -AsSecureString "Enter Your Password" 
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName , $Password 

# Get input on which machine to lookup
$computer = Read-Host 'Enter in machine name'

# Import our Active Directory PowerShell commands
Import-Module ActiveDirectory

# Check if the Computer Object exists in AD
$computerObject = Get-ADComputer -Filter {cn -eq $computer} -Property msTPM-OwnerInformation, msTPM-TpmInformationForComputer -Credential $credential
if($computerObject -eq $null){
    Write-Host "Computer object not found.  Exiting the script..."
    Cmd /c pause
	Exit
}

# Windows Vista and 7 stores the TPM owner password in the msTPM-OwnerInformation attribute, check that first.
# If the key hasn't been stored there, check the msTPM-TpmInformationForComputer object to see if it was backed up on a Win 8 or greater machine
if($computerObject.'msTPM-OwnerInformation' -eq $null){
    #Check if the computer object has had the TPM info backed up to AD
    if($computerObject.'msTPM-TpmInformationForComputer' -ne $null){
        # Grab the TPM Owner Password from the msTPM-InformationObject
        $TPMObject = Get-ADObject -Identity $computerObject.'msTPM-TpmInformationForComputer' -Properties msTPM-OwnerInformation  -Credential $credential
        $TPMRecoveryKey = $TPMObject.'msTPM-OwnerInformation'
    }else{
        $TPMRecoveryKey = '<not set>'
    }
}else{
    # Windows 7 and older OS TPM Owner Password
    $TPMRecoveryKey = $computerObject.'msTPM-OwnerInformation'
}

# Check if the computer object has had a BitLocker Recovery Password backed up to AD
$BitLockerObject = Get-ADObject -Filter {objectclass -eq 'msFVE-RecoveryInformation'} -SearchBase $computerObject.DistinguishedName -Properties 'msFVE-RecoveryPassword' -Credential $credential | Select-Object -Last 1
if($BitLockerObject.'msFVE-RecoveryPassword'){
    $BitLockerRecoveryKey = $BitLockerObject.'msFVE-RecoveryPassword'
}else{
    $BitLockerRecoveryKey = '<not set>'
}

#Print out our findings
Write-Host 'TPM Owner Recovery Key:' $TPMRecoveryKey
Write-Host 'BitLocker Recovery Password:' $BitLockerRecoveryKey

# Export TPM Owner Password File
if($computerObject.'msTPM-TpmInformationForComputer' -ne $null){
    $exportToFile = Read-Host 'Would you like to export the recovery key [y or n]'
    if($exportToFile -ne 'y'){
        Exit
    }

    $TPMOwnerFile = '<?xml version="1.0" encoding="UTF-8"?><ownerAuth>' + $TPMRecoveryKey + '</ownerAuth>'
    $TPMOwnerFile | Out-File "TPMOwnerPasswordFile.tpm"
}else{
    Cmd /c pause
}

[Tutorial] Configuring BitLocker to store recovery keys in Active Directory

This guide is more of a reflection on the steps I took to publish the BitLocker recovery keys of machines deployed on an Active Directory domain.  Microsoft has gobs and gobs of information on this subject which can be a tad overwhelming, so I have tried to consolidate this article down as much as possible, citing Microsoft sources where found.  If you have any questions, comments, feedback, please feel free to leave a message below.

Prerequisites

  • Domain Controllers are running Windows Server 2003 SP1 or greater
  • Schema Admin or an Enterprise Admin user account privileges

Step 1: Verify your schema is ready (and extend it if applicable)

Based on what I have read, if your DCs were introduced with Server 2008 Beta 3 or later, your schema will be ready, if you started with anything older, your AD environment will more than likely will not have the schema objects/attributes.

Verify you have the schema changes if running Server 2003 R2 or older:

If you are on Server 2003 you will need to open up ADSI edit and verify you have the schema changes (here you can see we are missing the five schema changes for BitLocker)

ADSI Edit - Server 2003 R2 - BitLocker

Verify you have the schema changes if running Server 2008 or newer:

If you are on Server 2008 or greater and have powershell, you can execute the following command (here you can see we have the necessary schema changes to proceed, if you receive 0 results, you will need to extend your schema):

Get-ADObject -SearchBase ((GET-ADRootDSE).SchemaNamingContext) -Filter {Name -like "ms-FVE-*"}

AD-Schema objects for BitLocker

Extending your schema if you don't have the schema changes above

If you need the schema update (you are missing the five schema objects listed in the above powershell command), you can execute the following command via Command Prompt on your Domain Controller:

Note: If you are on Server 2008 r2, it is recommended you extend your schema to Server 2012 or if you just want the BitLocker attributes, use these two ldf files: https://technet.microsoft.com/en-us/library/jj635854.aspx

ldifde -i -v -f BitLockerTPMSchemaExtension.ldf -c "DC=X" "DC=mydomain,DC=local" -k -j .

Yes, you do want the trailing period (.) at the end of the command.  It is literally apart of the command, so ensure you execute the command exactly like above (changing your domain of course).   You can see the official technet article here for more information on the command: https://technet.microsoft.com/en-us/library/cc766015(v=ws.10).aspx

If you would like to verify everything went well, Microsoft has posted some output on what the command should write: https://technet.microsoft.com/en-us/library/cc722060(v=ws.10).aspx

Step 2: Set the required permissions for backing up TPM password information

Next, we need to add an access control entry (ACE) so that backing up TPM recovery information is possible.

Head over to the following Microsoft document and download each of the VBS scripts they have displayed: Save the following VBS scripts from the following website: https://technet.microsoft.com/en-us/library/dn466534.aspx#Sample scripts

  1. Ensure you are on one of your domain controllers
  2. Open up a command prompt as an administrator
    Server 2012 - Administrative Command Prompt
  3. Navigate to your BitLocker folder
    BitLocker Folder C Drive
  4. Execute the following command on your domain controller
    1. cscript Add-TPMSelfWriteACE.vbs
      cscript add-tpmselfwriteace for bitlocker
  5. Delegate msTPM-OwnerInformation
    1. Open up Active Directory Users and Computers
      Server Manager - Active Directory Users and Computers
    2. Navigate to the OU that stores your computers, right click, and select Delegate Control...
      Active Directory Users and Computers - Computers - Delegate Control
    3. Click Next > button on the welcome screen
      Delegation of Control Wizard - Welcome
    4. Click the Add... button
      Delegation of Control Wizard - Users or Groups - Add
    5. Type in SELF, hit the Check Names button, and click OK
      Delegation of Control Wizard - Users or Groups - Add - SELF
    6. Click Next >
      Delegation of Control Wizard - Users or Groups - Add - SELF - Next
    7. Select Create a custom task to delegate and click Next >
      Delegation of Control Wizard - Tasks to Delegate - Create a custom task to delegate
    8. Check Only the following objects in the folder, check Computer objects, click Next >
      Delegation of Control Wizard - Active Directory Object Type - Only the following objects in the folder - Computer Objects
    9. Check Property-specific, scroll down and find Write msTPM-OwnerInformation and click Next >
      Delegation of Control Wizard - Permissions - Property-specific - Write msTPM-OwnerInformation
    10. Click Finish
      Delegation of Control Wizard - SELF - Finish

Step 3: Configure group policy to back up BitLocker and TPM recovery information to Active Directory

In this step, we will push out the actual policy that tells the machine to push BitLocker and TPM recovery info to Active Directory.  We will try to follow some of Microsoft's best practices on deploying the group policy here: https://technet.microsoft.com/en-us/library/dd875532(WS.10).aspx

  1. Login to your domain controller
  2. In Server Manager, open up Group Policy Management
    Server Manager - Tools - Group Policy Management
  3. Select the policy you want to edit/deploy for this and hit Edit...
    Group Policy Management - Edit
  4. Expand Computer Configuration, expand Policies, expand Administrative Templates, open Windows Components, and then select BitLocker Drive Encryption
    Group Policy Management Editor - Computer - Configuration - Administrative Templates - Windows Components - BitLocker Drive Encryption
  5. Follow the below configuration for each policy (most of these are Microsoft's best practices with a few notes I have made in the Settings)
    CATEGORY SETTING NAME SETTING
    Global Store BitLocker recovery information in Active Directory Domain Services  Set to enabled, check Require BitLocker backup to AD DS, ensure Recovery passwords and key packages is selected
    Global Choose drive encryption method and cipher strength Set to not configured.
    Global Prevent memory overwrite on restart Set to not configured.
    Global Provide the unique identifiers for your organization Set to enabled, and enter an identifier in the BitLocker identification field (based on what I can tell, you can enter your organization name here).
    Operating system drives Choose how BitLocker-protected operating system drives can be recovered Set to enabled, Allow 48-digit recovery password, Allow 256-bit recovery key, omit recovery options from the BitLocker setup wizard, Store recovery passwords and key packages, Do not enable BitLocker until recovery information is stored to AD DS for operating system drives.For more information about storing BitLocker recovery information in AD DS, see Backing Up BitLocker and TPM Recovery Information to AD DS.
    Operating system drives Configure minimum PIN length for startup Set to enabled, and require a personal identification number (PIN) of at least seven numerals.
    Operating system drives Require additional authentication at startup Set to enabled, and require the use of a startup PIN with a Trusted Platform Module (TPM).
    Fixed data drives Choose how BitLocker-protected fixed drives can be recovered Set to enabled, Allow 48-digit recovery password, Allow 256-bit recovery key, omit recovery options from the BitLocker setup wizard, Store recovery passwords and key packages, Do not enable BitLocker until recovery information is stored to AD DS for operating system drives.
    Fixed data drives Configure use of passwords for fixed data drives If your organization does not have a public key infrastructure (PKI), set to enabled, require password complexity, and set a minimum password length of at least 12 characters.
    Fixed data drives Configure use of smart cards on fixed data drives If your organization has a PKI, set to enabled, and require the use of smart cards with fixed data drives.
    Removable data drives Choose how BitLocker-protected removable drives can be recovered Set to enabled, Allow 48-digit recovery password, Allow 256-bit recovery key, omit recovery options from the BitLocker setup wizard, Store recovery passwords and key packages, Do not enable BitLocker until recovery information is stored to AD DS for operating system drives.
    Removable data drives Configure use of passwords for removable data drives Set to enabled, set a minimum password length of at least 12 characters, and require password complexity if your organization does not have a PKI or if there is a need to access BitLocker-protected drives from computers running Windows XP or Windows Vista.
    Removable data drives Configure use of smart cards on removable data drives Set to enabled, and require the use of smart cards with removable data drives if your organization has a PKI.
    Removable data drives Control use of BitLocker on removable drives Set to enabled, Allow users to apply BitLocker protection on removable data drives, and uncheck Allow users to suspend and decrypt BitLocker protection on removable data drives.
    Removable data drives Deny write access to removable data drives not protected by BitLocker Set to enabled, and Do not allow write access to devices configured in another organization.

    noteNOTE
    This policy cannot be enabled if your organization uses recovery keys or startup keys. Recovery keys and startup keys must be stored on unencrypted USB drives.
  6. Next, configure Group Policy to backup the TPM owner information; open Computer Configuration, open Administrative Templates, open System, and then open Trusted Platform Module Services
    Group Policy Management Editor - Computer - Configuration - Administrative Templates - System - Trusted Platform Module Services
  7. Double-click Turn on TPM backup to Active Directory, check Enabled, and click OK
    Group Policy Management Editor - Computer - Configuration - Administrative Templates - System - Trusted Platform Module Services - Turn on TPM backup to ADDS - Enabled

    1. Note: If you are on Server 2008 R2, make sure you select Require TPM backup to AD DS.  Based on what I can find, if you are on Server 2012 R2, this option has been removed.
  8. Define a BitLocker Drive Encryption Data Recovery Agent
    1. Open Computer Configuration, open Policies, open Windows Settings, open Security Settings, open Public Key Policies, and right click on BitLocker Drive Encryption and select Add Data Recovery Agent...
    2. Click Next > on the Add Recovery Agent Wizard
    3. Select a Recovery agent and click Next >
      1. If you are using PKI, select the Browse Directory... button and select a user that has been configured with an EFS certificate.  I found this guide the most helpful on setting this process up (if anyone has a guide to an official Microsoft document explaining the best practices on configuring this, please drop a comment below: http://technetlibrary.com/use-data-recovery-agent-dra-decrypt-encrypted-files-domain/163)
        1. Here is the only official Microsoft article that I could find that explains the configuration of the Data Recovery Agent: https://technet.microsoft.com/en-us/library/dd875560%28v=ws.10%29.aspx#BKMK_proc_dra
      2. If you don't have a PKI environment setup, you can use a self signed certificate by opening up a command prompt and executing the following command: cipher /r:administrator
        1. Copied from the cipher command: This command generates an EFS recovery key and certificate, then writes them to a .PFX file (containing certificate and private key) and a .CER file (containing only the certificate). An administrator may add the contents of the .CER to the EFS recovery policy to create the recovery key for users, and import the .PFX to recover individual files. If SMARTCARD is specified, then writes the recovery key and certificate to a smart card. A .CER file is generated (containing only the certificate). No .PFX file is generated.
    4. Click Finish on the Add Recovery Agent Wizard

Step 4: Install the BitLocker Password Recovery Viewer

  1. On your domain controller, open up Server Manager
  2. Select Manage, Add Roles and Features
    Server 2012 - Manage - Add Roles and Features
  3. Click Next >
    Add Roles and Features Wizard - Before you begin
  4. Click Next >
    Add Roles and Features Wizard - Select installation type
  5. Click Next >
    Add Roles and Features Wizard - Select destination server
  6. Click Next > (You don't need to add any additional roles)
    Add Roles and Features Wizard - Server Roles - Default
  7. Check BitLocker Drive Encryption (click Add Features when prompted) and click Next >
    Add Roles and Features Wizard - Features - BitLocker Drive Encryption - Add features dialog
    Add Roles and Features Wizard - Features - BitLocker Drive Encryption
  8. Click Install
    Add Roles and Features Wizard - Features - BitLocker Drive Encryption - Install
  9. Click Close
    Add Roles and Features Wizard - Features - BitLocker Drive Encryption - Install - Close
  10. Repeat these steps for each domain controller you want to manage BitLocker on

Step 5: Push existing BitLocker protected machines to Active Directory (optional step)

  1. Open an Administrative Command prompt on the client machine that has a BitLocker enabled drive
    Server 2012 - Administrative Command Prompt
  2. Execute the following command to get your current BitLocker information
    manage-bde -protectors -get c:
    command prompt - manage-bde -protectors -get c
  3. Execute the following command to publish this information to AD
    manage-bde -protectors -adbackup c: -id {yourNumericalPasswordID}
    command prompt - manage-bde -protectors -adbackup c-id
  4. Login to one of the domain controllers you installed the BitLocker Recovery Viewer feature and open up Active Directory Users and Computers
    Server Manager - Active Directory Users and Computers
  5. Find your computer object and right click Properties on it
    Active Directory Users and Computers - Computers - Computer - Properties
  6. Select the BitLocker Recovery tab and verify the recovery passwords have been published
    Active Directory Users and Computers - Computers - Computer - Properties - BitLocker Recovery Tab

 

Notes: By default, Windows Vista and greater clients running BitLocker will backup the owner the owner password to the msTPM-OwnerInformation attribute.  If you notice this field is <Not Set> for your Windows 8 and greater machines, ensure you check the TPM Devices container in Active Directory Users and Computers for the recovery information.

To automate the process of looking up the Bitlocker Recovery Password and Owner TPM Recovery Key, I have written a powershell script which can be found here: http://jackstromberg.com/2015/02/exporting-tpm-owner-key-and-bitlocker-recovery-password-from-active-directory-via-powershell/

[Tutorial] Configuring Lync Server 2013 to block calls based on Caller ID

Synopsis: Out of the box, Lync Server 2013 does not have any way to block specific calls destined to any user or specific user inside of an organization.  However, Microsoft added in the ability for users/partners/etc. to write custom scripts to help allow flexibility in Lync.  That being said, this tutorial will go over deploying a custom script to allow Lync Server to block calls based on caller ID.

Before we begin, I would like to give credit to a few individuals.  This guide will make use of David Paulino's guide/script for Lync Server 2013 (http://uclobby.com/2014/07/31/calleridblock/), which was a converted script from VoIP Norm's original Lync Server 2010 script (http://voipnorm.blogspot.co.uk/2011/06/blocking-calls-in-lync-based-on-caller.html).  The only changes in this article is a more step-by-step deployment guide as well as the ability to control blocking of numbers at a user level and the ability to optionally leave comments on why a rule was added.

Tutorial

  1. Download a copy of the CallerIDBlock.am.txt script (or copy and paste this script into a file called CallerIDBlock.am) (if you downloaded this file, make sure you remove the .txt at the end)
    1. <?xml version="1.0" ?>
      <lc:applicationManifest
      lc:appUri="http://jackstromberg.com/2015/02/CallerIDBlock"
      xmlns:lc="http://schemas.microsoft.com/lcs/2006/05">
      <lc:requestFilter methodNames="ALL" strictRoute="true"/>
      <lc:responseFilter reasonCodes="NONE"/>
      <lc:scriptOnly/>
      <lc:file name="BlockedTelephoneNumbers"
      path="\\<Lync Share Path>\CallerIDBlock\BlockedTelephoneNumbers.txt"
      delimitedBy="comma"
      keyColumnName="FromSIP"
      static="false">
      <lc:column name="FromSIP" />
      <lc:column name="ToSIP" />
      <lc:column name="Action" />
      <lc:column name="Comments" />
      </lc:file>
      <lc:splScript><![CDATA[
      /*
      Module Name: CallerIDBlock.am
      */if(sipRequest.Method == "INVITE"){
      fromSIPUser = GetUserName(GetUri(sipRequest.From));
      toSIPUser = GetUserName(GetUri(sipRequest.To));
      sep = IndexOfString(fromSIPUser, ";");Log ("Debugr", false, "CallerIDBlock processing request:");
      Log ("Debugr", false, "From - ", fromSIPUser);
      Log ("Debugr", false, "To - ", toSIPUser);
      if(sep != -1) {
      fromSIPUser = SubString(fromSIPUser, 0, sep);
      }

      action = BlockedTelephoneNumbers[fromSIPUser].Action;
      if(action == "block") {
      if(BlockedTelephoneNumbers[fromSIPUser].ToSIP == "*" || BlockedTelephoneNumbers[fromSIPUser].ToSIP == toSIPUser){
      Log ("Debugr", false, "Rejected by CallerIDBlock");
      Respond(403, "Forbidden");
      }
      } else {
      Log ("Debugr", false, "Allowed by CallerIDBlock");
      }
      }
      return;
      ]]></lc:splScript>
      </lc:applicationManifest>

  2. Download a copy of the BlockedTelephoneNumbers.txt file (or copy and paste the code below into a file called BlockedTelephoneNumbers.txt)
    1. FromSIP,ToSIP,Action,Comments
  3. Edit the CallerIDBlock.am file and change the BlockedTelephoneNumbers path to be your fileshare
    CallerIDBlock - LyncPath - Notepad
  4. Edit the list of blocked numbers inside the BlockedTelephoneNumbers.txt file
    1. Notes: The FromSIP address is the Caller ID of the incoming call; the ToSIP is the individual that is trying to be reached (side-note, in this particular script, if you set this field so an asterisk (*), this will be a wildcard for any/every user; the Action should be set to "block" to block the call; the Comments field is an optional field to document when/why the number was added to be blocked
      BlockedTelephoneNumbers Example
  5. Create a new folder where your Lync share is
    LyncShare - CallerIDBlock
  6. Copy the CallerIDBlock.am and BlcokedTelephoneNumbers.txt files to your Lync Share where your new CallerIDBlock folder is
    LyncShare - CallerIDBlock - Script and Numbers
  7. Add the CallerIDBlock script as a Lync Server Application
    1. Open up the Lync Server Manage Shell as an Administrator
      Lync Server Management Shell - Run as administrator
    2. New-CsServerApplication -Identity "Service:Registrar:<Lync Front End Pool>/CallerIDBlock" -Uri http://jackstromberg.com/2015/02/CallerIDBlock -Critical $false -ScriptName "\\<Lync Share Path>\CallerIDBlock\CallerIDBlock.am"
      New-CsServerApplication -Identity CallerIDBlock
  8. Enable the CallerIDBlockLync Server Application
    1. Set-CsServerApplication -Identity "Service:Registrar:<Lync Front End Pool>/CallerIDBlock" -Enabled $true
      Set-CsServerApplication -Identity CallerIDBlock
  9. Verify the script is actively listening for calls
    1. Open up Event Viewer, navigate to Applications and Services Logs, Lync Server, and verify you see Event ID 30208
      Event Viewer - Applications and Services Logs - Lync Server - Event ID 30208