Tag Archives: powershell

What is Azure DNS? And how do I get started?

One of the new Azure services announced at Ignite was Azure DNS. A globally replicated and highly available DNS service leveraging Anycast for fast DNS responses from anywhere around the globe. Wow. Since it’s using well known management tools (Powershell) and integration interfaces (REST and C#) Azure DNS is really easy to build upon and maximize on the investment.

The only thing I’m missing (for obvious reasons) is the ability to register and manage domains at a registrar level. Hopefully a <insert domain registrar name here> Resource Provider is only a matter of time.

I’m very excited about this since I am wasting was wasting a boatload of money on two A0 VMs in an availability set hosting DNS. Since I had a small boat it only fit about $30/month.. 😉
With Azure DNS I’m only paying $0.25 per zone and $0.20 per 1 billion queries. So I basically cut my DNS cost by 99% and reduced my management cost by about the same amount.

Gettings started with Azure DNS

To sign up for Azure DNS, which is currently in preview, you’ll have to use Powershell. Be sure you have at least version 0.9.1 installed. Even tho DNS Cmdlets have been hiding since November 26th, 2014.
You easily can download and install the latest version with the help of this post.

Switch-AzureMode -Name AzureResourceManager
# Had to re-register the Microsoft.Network provider for the DNS feature to ever become Registered
Register-AzureProvider -ProviderNamespace Microsoft.Network
Register-AzureProviderFeature -ProviderNamespace Microsoft.Network -FeatureName azurednspreview

Wait until RegistrationState turns into Registered. It should happen almost instantly.

Get-AzureProviderFeature -ProviderNamespace Microsoft.Network -FeatureName azurednspreview | fl *

FeatureName : azurednspreview
ProviderName : Microsoft.Network
RegistrationState : Registered

Next we’ll create our first DNS Zone. All zones must be placed inside a Resource Group.

New-AzureResourceGroup -Name WE-DMZ-DNS -Location westeurope
New-AzureDnsZone -Name runbookautomation.se -ResourceGroupName WE-DMZ-DNS
# Get DNS zone name server
(Get-AzureDnsRecordSet -ZoneName runbookautomation.se -ResourceGroupName WE-DMZ-DNS -Name '@' -RecordType NS).Records

Next up is the slow and tricky part. The last row in the previous snippet expands the name servers of your newly created zone. These name servers need to be configured at your domain registrar.

This is how it looked like at my registrar:

Once the DNS changes have replicated and Resolve-DnsName returns something like this you are good to go. The key property here is PrimaryServer.

Lastly we’ll create a CNAME record:

# Get the target Zone
$Zone = Get-AzureDnsZone -Name runbookautomation.se -ResourceGroupName WE-DMZ-DNS
# Create the DNS Record Set
$RecordSet = New-AzureDnsRecordSet -Name blog -RecordType CNAME -Ttl 3600 -Zone $Zone
# Add the CNAME value to the DNS Record Set
Add-AzureDnsRecordConfig -RecordSet $RecordSet -Cname blog-runbookautomation-se.azurewebsites.net
# Apply changes to Record Set in Azure
Set-AzureDnsRecordSet -RecordSet $RecordSet

Below is the complete code using variables for easier use.

Update Azure Powershell module with Powershell

A couple of months ago I shared a script that downloaded and installed the latest version of the Azure Powershell module. Since that time a lot of things have changed.

The module has moved from azure-sdk-tools to azure-powershell on GitHub!
The module has been updated from version 0.8.6 to version 0.9.1 with the help of over 3000 commits!
The module has gone from 434 cmdlets up to 761 cmdlets!

Below is a new snippet that leverages the GitHub API to download and install the latest Azure Powershell module:

Download and invoke the script to update. Or just run this one-liner:

Getting an accurate last logon date of Active Directory users

Sometimes the LastLogonTimeStamp attribute just doesn’t cut it and other times LastLogon just isn’t accurate on the Domain Controller you’re querying.

This attribute is not replicated and is maintained separately on each domain controller in the domain. To get an accurate value for the user’s last logon in the domain, the Last-Logon attribute for the user must be retrieved from every domain controller in the domain. The largest value that is retrieved is the true last logon time for that user.

Manually checking each DC and determinating the largest datetime value of LastLogon is clearly out the question so we’ll use Powershell instead!

To maintain as much flexibility as possible, ease of use and respect already established methods of working against AD with Powershell I’ve created a function that allows pipeline input from Get-ADUser and SamAccountName arrays (read: Import-CSV and Get-Content).

Per usual you’ll find the script at TechNet Gallery!

   Gets the newest LastLogon date based on data from all Domain Controllers in the Forest.
   Get the newest LastLogon attribute for the specified user by iterating through all Domain Controllers in the forest.
   Output is structured and enables sorting, CSV export and further processing.
    # Get LastLogon date for one username:
    C:\PS> Get-ADUserLastLogon -SamAccountName username

    DomainController : dc01.contoso.com
    Enabled          : True
    Name             : User Name
    SamAccountName   : username
    LastLogon        : 2015-03-30 15:11:06

    # Get LastLogon date for multiple usernames and output as table:
    C:\PS> "username","nameuser" | Get-ADUserLastLogon | Format-Table -AutoSize

    DomainController     Enabled Name        SamAccountName LastLogon
    ----------------     ------- ----        -------------- ---------
    dc01.contoso.com        True User Name   username       2015-03-30 15:11:06
    dc02.contoso.com        True Name User   nameuser       2015-03-30 13:58:38
    # Get LastLogon date for all users under an Organizational Unit:
    C:\PS> $OU = "OU=ServiceAccounts,DC=contoso,DC=com"
    C:\PS> $ADUsers = Get-ADUsers -Filter * -SearchBase $OU
    C:\PS> $ADUsers | Get-ADUserLastLogon -Properties Title
    # Get LastLogon date for the first 50 users of a remote forest and remote credentials:
    C:\PS> $Cred = Get-Credential
    C:\PS> Get-ADUserLastLogon -All -Count 50 -Forest contoso.org -Credential $Cred
    # Get LastLogon date for the first 5 users and output the AD User object of the first users:
    C:\PS> $Result = Get-ADUserLastLogon -All -Count 5 -Passthru
    C:\PS> $Result[0].TargetObject
.PARAMETER SamAccountName
    Account name, as a string, to get LastLogon date.
    Account, from Get-ADUser cmdlet, to get LastLogon date.
    Gets all AD users of the specified domain.
    Use together with -Count parameter to restrict amount of results.
    Max amount of results when using -All parameter.
    Name of the remote forest. Needs to be resolvable.
.PARAMETER Properties
    Adds AD attributes to the output.
    Adds the Get-ADUser cmdlet output object into the TargetObject property.
.PARAMETER Credential
    Credentials to use with Get-ADUser and/or connecting to a remote forest.
    Version: 20150330.1
    Author: Daniel Grenemark
    Email: daniel@grenemark.se
    Twitter: @desek
    Blog: https://runbookautomation.wordpress.com/

TechNet Gallery URL: https://gallery.technet.microsoft.com/Get-AD-User-Last-Logon-4c6b6fa6

Publishing SCSM Request Offerings like an engineer!

Ever had the great idea that you’d create an enumeration list that you’ll use on several RO’s to maximize data quality and ensure successful automation?

I’ve had it. Several times in fact.

However, for obvious reasons I don’t want to relate this enumeration to any class. I want it to be stand-alone and only be used with one or several RO(s). As all “centrally managed lists” I want a change in the list to reflect on all RO(s). And as most of you know you have to map every prompt to a property of a class that is defined in the template related to the RO to be able to publish it.
There’s actually a requirement for this on the data layer and not just in the GUI, which I tought at first.

So how do you map an enumeration that is not a property of any class?

Since all configuration of RO’s are saved in a Management Pack and in XML format we should start by reading the Management Pack XML Schema Reference.
After a few clicks we should notice that the <Extension> element (which contains the RO definition) isn’t documented on MSDN. Thank you very much! Continue reading

Working with schedules in Azure Automation (and SMA)

The few of us that have started working with Azure Automation and/or SMA have probably noticed the lack of functionality that would equal a monitoring activity in Orchestrator.

I’ve seen some solutions which consist of a Runbook being set in an infinite loop with a sleep timer at the bottom.
In practice this method would replicated the desired functionality, that is, until the Runbook hits the maximum runtime value and kills the process. If you’re using Azure Automation this would also mean that you’ll be consuming Automation Minutes. 24/7.

What you’ll want to do with Azure Automation and SMA is to work with schedules to mimic a monitoring activity. And this can be a hassle to manage… Unless you’re using the right tools! 🙂
(Hint: Powershell.)

First we’ll want to create the required schedules. In 99% of the cases I work with hourly schedules at different minute intervals and I create them with the following script found at Technet Gallery.

If you use the “-Verbose” parameter you’ll get output on the schedule creation process.

And lastly we’ll want to assign Runbooks to the required schedules so the Runbook executes at the right time with the following script:

By piping to “Out-Gridview -Passthru” I can easily filter all the schedules and select the ones I want. Oh, and they script writes the intervals into the Description property of the schedules. This makes life a bit easier if you want the Runbook to execute, for example, every 5 minutes.


The result would look something like this in the Azure Management Portal:


I hope this helps you to manage your Automation Runbooks in a more efficient way and lower your Azure bill!

Again, the script can be found at: https://gallery.technet.microsoft.com/Generate-Azure-Automation-1dab9193

Powershell User Group Sweden – October 2013 Meeting!

As promised during my session at the Powershell User Group Sweden meet last week I will publish my scripts used in my SMA session. And here they are!

For those of you not attending the meet I had the opportunity to give a super compact lesson in Powershell Workflow to cover the basics. Workflows are after all the foundation of SMA. I gave the attendees an overview of SMA administration. Both in powershell/ISE and the Windows Azure Pack portal!


Continue reading

Windows Powershell Remoting Resources

Running powershell locally is always great fun, but what about remoting?

There’s a whole lot of things to think about besides Enter-PSsessoin and Invoke-Command. Here’s some resources to get you started!

eBook: Secrets of PowerShell Remoting by Don Jones and Dr. Tobias Weltner

Blog post: Understanding Powershell Remote Management by Ed Wilson

Blog post: Learn How to Manage Remote PowerShell Sessions by Ed Wilson

Video: Advanced Automation with Windows PowerShell (MDC-400) by Jeffrey Snover and Don Jones

Video: Getting started with PowerShell 3.0 Jump Start by Microsoft Virtual Academy

Remember that PowerShell is just not a marketing gimmick, it’s the feature of administration and automation!