How to create a Service Bus Namespace and an Event Hub using a PowerShell script
This week I received the same two questions twice from two different customers: how can I create a Service Bus namespace from a PowerShell script? Moreover, after I created the Service Bus namespace, how can I create an event hub from a PowerShell script? The answer to the first question is easy: to create a new Azure Service Bus namespace you can use the New-AzureSBNamespace PowerShell cmdlet. The answer to the second question is also straightforward: to create a new Event Hub you can use the CreateEventHub method of the NamespaceManager class. The second question should be posed in a different way: how can I use the classes of the Microsoft.ServiceBus.dll assembly inside a PowerShell script? The following post shows a PowerShell script that you can use to create a Service Bus namespace, an Event Hub and a Consumer Group for the newly created Event Hub.
<#
.SYNOPSIS
This script can be used to provision a namespace and an event hub.
.DESCRIPTION
This script can be used to provision a namespace and an event hub.
In particular, the script allows to specify the following parameters:
-- Event Hub path
-- Event hub message retention in days
-- Event Hub partition count
-- Event Hub user metadata
-- Service Bus Namespace
-- Azure Datacenter location
.PARAMETER Path
Specifies the full path of the event hub.
.PARAMETER PartitionCount
Specifies the current number of shards on the event hub.
.PARAMETER MessageRetentionInDays
Specifies the number of days to retain the events for this event hub.
.PARAMETER UserMetadata
Specifies the user metadata for the event hub.
.PARAMETER ConsumerGroupName
Specifies the name of a custom consumer group.
.PARAMETER ConsumerGroupUserMetadata
Specifies the user metadata for the custom consumer group.
.PARAMETER Namespace
Specifies the name of the Service Bus namespace.
.PARAMETER CreateACSNamespace
Specifies whether to create an ACS namespace associated to the Service Bus namespace.
.PARAMETER Location
Specifies the location to create the namespace in. The default value is "West Europe".
Valid values:
-- East Asia
-- East US
-- North Central US
-- North Europe
-- West Europe
-- West US
#>
[CmdletBinding(PositionalBinding=$True)]
Param(
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z0-9]*$")]
[String]$Path, # required needs to be alphanumeric
[Int]$PartitionCount = 16, # optional default to 16
[Int]$MessageRetentionInDays = 7, # optional default to 7
[String]$UserMetadata = $null, # optional default to $null
[String]$ConsumerGroupName = "MyConsumerGroup", # optional default to "MyConsumerGroup"
[String]$ConsumerGroupUserMetadata = $null, # optional default to $null
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z0-9]*$")]
[String]$Namespace, # required needs to be alphanumeric
[Bool]$CreateACSNamespace = $False, # optional default to $false
[String]$Location = "West Europe" # optional default to "West Europe"
)
# Set the output level to verbose and make the script stop on error
$VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"
# WARNING: Make sure to reference the latest version of the \Microsoft.ServiceBus.dll
Write-Output "Adding the [Microsoft.ServiceBus.dll] assembly to the script..."
Add-Type -Path "C:\Projects\Azure\ServiceBusExplorerNew\ServiceBusExplorer2.4Git\bin\Debug\Microsoft.ServiceBus.dll"
Write-Output "The [Microsoft.ServiceBus.dll] assembly has been successfully added to the script."
# Mark the start time of the script execution
$startTime = Get-Date
# Create Azure Service Bus namespace
$CurrentNamespace = Get-AzureSBNamespace -Name $Namespace
# Check if the namespace already exists or needs to be created
if ($CurrentNamespace)
{
Write-Output "The namespace [$Namespace] already exists in the [$($CurrentNamespace.Region)] region."
}
else
{
Write-Host "The [$Namespace] namespace does not exist."
Write-Output "Creating the [$Namespace] namespace in the [$Location] region..."
New-AzureSBNamespace -Name $Namespace -Location $Location -CreateACSNamespace $CreateACSNamespace -NamespaceType Messaging
$CurrentNamespace = Get-AzureSBNamespace -Name $Namespace
Write-Host "The [$Namespace] namespace in the [$Location] region has been successfully created."
}
# Create the NamespaceManager object to create the event hub
Write-Host "Creating a NamespaceManager object for the [$Namespace] namespace..."
$NamespaceManager = [Microsoft.ServiceBus.NamespaceManager]::CreateFromConnectionString($CurrentNamespace.ConnectionString);
Write-Host "NamespaceManager object for the [$Namespace] namespace has been successfully created."
# Check if the event hub already exists
if ($NamespaceManager.EventHubExists($Path))
{
Write-Output "The [$Path] event hub already exists in the [$Namespace] namespace."
}
else
{
Write-Output "Creating the [$Path] event hub in the [$Namespace] namespace: PartitionCount=[$PartitionCount] MessageRetentionInDays=[$MessageRetentionInDays]..."
$EventHubDescription = New-Object -TypeName Microsoft.ServiceBus.Messaging.EventHubDescription -ArgumentList $Path
$EventHubDescription.PartitionCount = $PartitionCount
$EventHubDescription.MessageRetentionInDays = $MessageRetentionInDays
$EventHubDescription.UserMetadata = $UserMetadata
$NamespaceManager.CreateEventHub($EventHubDescription);
Write-Host "The [$Path] event hub in the [$Namespace] namespace has been successfully created."
}
# Create the consumer group if not exists
Write-Output "Creating the consumer group [$ConsumerGroupName] for the [$Path] event hub..."
$ConsumerGroupDescription = New-Object -TypeName Microsoft.ServiceBus.Messaging.ConsumerGroupDescription -ArgumentList $Path, $ConsumerGroupName
$ConsumerGroupDescription.UserMetadata = $ConsumerGroupUserMetadata
$NamespaceManager.CreateConsumerGroupIfNotExists($ConsumerGroupDescription);
Write-Host "The consumer group [$ConsumerGroupName] for the [$Path] event hub has been successfully created."
# Mark the finish time of the script execution
$finishTime = Get-Date
# Output the time consumed in seconds
$TotalTime = ($finishTime - $startTime).TotalSeconds
Write-Output "The script completed in $TotalTime seconds."
Note 1: as highlighted in the comments, make sure to load the latest version of the Microsoft.ServiceBus.dll assembly in the script.
Note 2: you can follow the same approach to create topics, queues, subscriptions and notification hubs instead of event hubs.
The picture below shows the result of the execution of the script with the following parameters:
powershell .\CreateEventHub.ps1 -Path ioteventhub -PartitionCount 32 -MessageRetentionInDays 3 -UserMetadata 'This event hub is used by the devices of the IoT solution' -ConsumerGroupName iotconsumergroup -ConsumerGroupUserMetadata 'This consumer group is used by the IoT solution' -Namespace iotsolution -Location 'West Europe'
I’d like to remark that this kind of scripts should be:
- parametric to be reusable
- included in the source control system (Visual Studio Online or GitHub) along with the solution and versioned as the application code
- executed as part of the Continuous Delivery process used to automatically deploy the solution to a QA environment when a new version of the application is built
In fact, you probably heard the term DevOps more and more times. The term remarks the need to integrate development and operations tasks to build software solutions efficiently over time. This goal can be achieved using a process in which you develop an application, deploy it, learn from production usage of it, change it in response to what you learn, and repeat the cycle quickly and reliably.
To achieve this result, you have to build a development and deployment cycle that is repeatable, reliable, predictable, and has low cycle time. In particular, to create the staging and production environment for an Azure application and to deploy the solution in an automated way and integrate this task in the Continuous integration (CI) and Continuous delivery (CD) processes, you should use parametric PowerShell scripts.
Note: Continuous integration (CI) means that whenever a developer checks in code to the source repository, a build is automatically triggered. Continuous delivery (CD) takes this one-step further: after a build and automated unit tests are successful, you automatically deploy the application to an environment where you can do more in-depth testing.
You can download the script along with the PowerShell scripts to create queues, topics and Subscription on MSDN Code Gallery: Service Bus PowerShell Scripts
Comments
Anonymous
January 13, 2015
Hello, I tried to run the solution but I getting the following exception that the functions "EventHubExists" was not found. I'm loading the ServiceBus assembly with the version 2.5.41204.0. I tried in the following ways: Add-Type -Path ".Microsoft.ServiceBus.dll" Add-Type -Path ".Microsoft.ServiceBus.dll" -ReferencedAssemblies "System.Runtime.Serialization.dll" , but still I support that the assembly is not loaded correctly. I have at the same level the SB assembly. Do you have any ideas?Anonymous
January 13, 2015
Found the problem. The script should be run directly from cmd or PowerShell ISEAnonymous
January 13, 2015
Hi Radu... better so ;) Thanks for the feedback!Anonymous
June 08, 2015
Hi Paalo, I am trying to create Topic with the scripts, but I am consistently getting this error "Add-Type : Could not load file or assembly 'file:///D:DeployCreateTopicMicrosoft.ServiceBus.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)" I have latest Azure PowerShell installed and I am referring to the latest version of ServiceBus DLLAnonymous
June 09, 2015
Did you check the path and version of the Microsoft.ServiceBus.dll library? Ciao PaoloAnonymous
June 30, 2015
when i run methods from PowerShell ISE it complains about missing methods EventHubExists , CreateEventHubIfNotExists i run Add-Type -Path "C:...ServiceBusExplorerpackagesWindowsAzure.ServiceBus.2.7.3libnet40-fullMicrosoft.ServiceBus.dll" $NamespaceManager = [Microsoft.ServiceBus.NamespaceManager]::CreateFromConnectionString($CurrentNamespace.ConnectionString); and $NamespaceManager | gm does not have EventHubExists , CreateEventHubIfNotExists same error - missing $NamespaceManager.EventHubExists when i run scripts from PM Console from Visual Studio 2013 (but if i put some code in C#, then it shows method presense: var nm = new NamespaceManager(""); var b2 = nm.EventHubExists("asdf"); // no compile error here.... ). any help appreciated, thanksAnonymous
June 30, 2015
found the problem - multiple ServiceBus packages were instelled (from 2.4..) when i deleted all except latest WindowsAzure.ServiceBus.2.7.2, WindowsAzure.ServiceBus.2.7.3 - those methods became available in powershell.Anonymous
June 30, 2015
It's great to see people finding the right answer by themselves ;) Ciao PaoloAnonymous
July 06, 2015
Hi Paolo, Thanks a lot for the detailed description. The script works great and it saves me a lot of time. One thing that I'm currently struggling is that I can't find a way to specify Shared Access Policy Rules for an Event Hub. Basically I can't create an instance of Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule object in PowerShell. Do you have any samples how that can be done? Thanks in advance, AlexAnonymous
July 06, 2015
Hi Alex thanks for the positive feedback ;) I don't have time to change the script to add a SAS policy rule, but I'll show you a C# snippet to accomplish this task. :) authorizationRule = new SharedAccessAuthorizationRule(SenderSharedAccessKey, SharedAccessAuthorizationRule.GenerateRandomKey(), new[] { AccessRights.Send }); eventHubDescription.Authorization.Add(authorizationRule); await namespaceManager.UpdateEventHubAsync(eventHubDescription); Ciao PaoloAnonymous
July 06, 2015
That's exactly what I was trying to implement in Powershell. $Key = [Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule]::GenerateRandomKey() $Rights = [Microsoft.ServiceBus.Messaging.AccessRights]::Listen, [Microsoft.ServiceBus.Messaging.AccessRights]::Send $AccessRule = New-Object -TypeName Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule -ArgumentList "SendReceiveRule", $Key, (,$Rights) $EventHubDescription.Authorization.Add($AccessRule) $NamespaceManager.CreateEventHub($EventHubDescription) Unfortunately it doesn't work. Powershell complains about SharedAccessAuthorizationRule constructor =(Anonymous
July 07, 2015
I found a way to do it =) One extra step was needed: $Key = [Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule]::GenerateRandomKey() $Rights = [Microsoft.ServiceBus.Messaging.AccessRights]::Listen, [Microsoft.ServiceBus.Messaging.AccessRights]::Send $RightsColl = New-Object -TypeName System.Collections.Generic.List[Microsoft.ServiceBus.Messaging.AccessRights] (,[Microsoft.ServiceBus.Messaging.AccessRights[]]$Rights) $AccessRule = New-Object -TypeName Microsoft.ServiceBus.Messaging.SharedAccessAuthorizationRule -ArgumentList "SendReceive", $Key, $RightsColl $EventHubDescription.Authorization.Add($AccessRule) Thanks again!Anonymous
July 07, 2015
Thanks Alex! I will update the script when I have some spare time! ;) Ciao PaoloAnonymous
July 13, 2015
found the problem - multiple ServiceBus packages were instelled (from 2.4..) when i deleted all except latest WindowsAzure.ServiceBus.2.7.2, WindowsAzure.ServiceBus.2.7.3 - those methods became available in powershell. How to delete other installed version of ServiceBus Packages. Am trying to use this method in a deployment server, with Visual Studio Installed. How to get 2.7.2 and 2.7.3 packages installed ? ThanksAnonymous
July 13, 2015
The comment has been removedAnonymous
July 13, 2015
Hi Pradebban The error is clear even if it's strange as the AuthorizationRules.Add method expects one argument. See msdn.microsoft.com/.../microsoft.servicebus.messaging.authorizationrules.add.aspx. By the way, look at the message by Alex Turetsky on this thread. He was able to accomplish the same task that you are trying to achieve, that is, create a custom shared access policy. Ciao PaoloAnonymous
July 13, 2015
Hi Paolo Thanks for the response. Yes i tried to implement using the same snippet. However was not able to find the method, $NamespaceManager.EventHubExists I made the below change to explicitly use the dll which i got along with Service Bus Explorer $asm = [System.Reflection.Assembly]::LoadFrom("D:testMicrosoft.ServiceBus.dll"); $nmType = $asm.GetType("Microsoft.ServiceBus.NamespaceManager"); $info = $nmType.GetMethod("CreateFromConnectionString"); $NamespaceManager = $info.Invoke($null, $CurrentNamespace.ConnectionString); However, there is version mismatch issues with Microsoft.ServiceBus.dll and i suspect that being the reason of failure of AuthorizationRules.Add method How can i get the nuget package of the latest Version. I would prefer to install the modules rather than needing a solution to install the package nuget. Please note: The latest version of Azure Powershell modules (2.6) gets the Microsoft.ServiceBus.dll which is not same as the one i get from the service Bus Explorer. I would need the Azure modules for most of other automation and make this Event Hub share access policy work. Basically i would need, both work together. Excuse for any wrong assumptions. I am relatively new to .net and powershell Thanks!Anonymous
August 13, 2015
Need help...I'm a beginner...following the solution by Alex Turetsky the Rule is added, but for the time of the session. (I can't see from portal; and if I close and reopen the shell the rule is not present. What's my mistake? ThanksAnonymous
August 14, 2015
Sorry to all... Just Solved: $SbnMan.UpdateEventHub($EventHubDescription) Thanks!Anonymous
August 19, 2015
Thanks Giulio for the feedback! Ciao PaoloAnonymous
October 12, 2015
thanx a lot Paolo Salvatori its really help me !!! and thank u Alex Turetsky your sharing help me too :)