Skip to content

Commit 0089ff9

Browse files
authored
Merge pull request #11134 from anusapan/iot-device-module-cs
[IoT Hub] Get module connection string cmdlet
2 parents 0342cf0 + 58d7437 commit 0089ff9

File tree

9 files changed

+760
-246
lines changed

9 files changed

+760
-246
lines changed

src/IotHub/IotHub.Test/ScenarioTests/IotHubDPModuleTests.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ function Test-AzureRmIotHubModuleLifecycle
6565
$modules = Get-AzIotHubModule -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName -DeviceId $device1
6666
Assert-True { $modules.Count -eq 2}
6767

68+
# Get module connection string
69+
$moduleCS = Get-AzIotHubMCS -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName -DeviceId $device1 -ModuleId $module2
70+
Assert-True { $moduleCS.ModuleId -eq $module2 }
71+
Assert-True { $moduleCS.ConnectionString -eq "HostName=$IotHubName.azure-devices.net;DeviceId=$device1;ModuleId=$module2;x509=true" }
72+
6873
# Get module detail
6974
$module = Get-AzIotHubModule -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName -DeviceId $device1 -ModuleId $module2
7075
Assert-True { $module.Id -eq $module2 }

src/IotHub/IotHub.Test/SessionRecords/Microsoft.Azure.Commands.IotHub.Test.ScenarioTests.IotHubDPModuleTests/TestAzureIotHubModuleLifecycle.json

Lines changed: 369 additions & 243 deletions
Large diffs are not rendered by default.

src/IotHub/IotHub/Az.IotHub.psd1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,16 @@ CmdletsToExport = 'Add-AzIotHubKey', 'Get-AzIotHubEventHubConsumerGroup',
9797
'Get-AzIotHubDevice', 'Remove-AzIotHubDevice',
9898
'Set-AzIotHubDevice', 'Add-AzIotHubModule',
9999
'Get-AzIotHubModule', 'Remove-AzIotHubModule',
100-
'Set-AzIotHubModule', 'Get-AzIotHubDeviceConnectionString'
100+
'Set-AzIotHubModule', 'Get-AzIotHubDeviceConnectionString',
101+
'Get-AzIotHubModuleConnectionString'
101102
# Variables to export from this module
102103
# VariablesToExport = @()
103104

104105
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
105106
AliasesToExport = 'Get-AzIotHubEHCG', 'Add-AzIotHubEHCG', 'Remove-AzIotHubEHCG',
106107
'Set-AzIotHubVC', 'Get-AzIotHubCVC', 'Add-AzIotHubMsgEnrich',
107108
'Get-AzIotHubMsgEnrich', 'Remove-AzIotHubMsgEnrich',
108-
'Set-AzIotHubMsgEnrich', 'Get-AzIotHubDCS'
109+
'Set-AzIotHubMsgEnrich', 'Get-AzIotHubDCS', 'Get-AzIotHubMCS'
109110

110111
# DSC resources to export from this module
111112
# DscResourcesToExport = @()

src/IotHub/IotHub/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- Remove-AzIotHubModule
3030
- Set-AzIotHubModule
3131
* Add cmdlet to get the connection string of a target IoT device in an Iot Hub.
32+
* Add cmdlet to get the connection string of a module on a target IoT device in an Iot Hub.
3233

3334
## Version 2.1.0
3435
* Added support to manage devices in an Iot Hub. New Cmdlets are:

src/IotHub/IotHub/IotHub/DataPlane/Device/GetAzIotHubDeviceConnectionString.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ public override void ExecuteCmdlet()
8989
if (this.DeviceId != null)
9090
{
9191
Device device = registryManager.GetDeviceAsync(this.DeviceId).GetAwaiter().GetResult();
92-
this.WriteObject(GetDeviceConnectionString(device, iotHubDescription.Properties.HostName));
92+
if (device != null)
93+
{
94+
this.WriteObject(GetDeviceConnectionString(device, iotHubDescription.Properties.HostName));
95+
}
9396
}
9497
else
9598
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright Microsoft Corporation
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
// http://www.apache.org/licenses/LICENSE-2.0
6+
// Unless required by applicable law or agreed to in writing, software
7+
// distributed under the License is distributed on an "AS IS" BASIS,
8+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
// See the License for the specific language governing permissions and
10+
// limitations under the License.
11+
// ----------------------------------------------------------------------------------
12+
13+
namespace Microsoft.Azure.Commands.Management.IotHub.Models
14+
{
15+
/// <summary>
16+
/// Connection string of the module.
17+
/// </summary>
18+
19+
public class PSModuleConnectionString
20+
{
21+
/// <summary>
22+
/// Module ID.
23+
/// </summary>
24+
public string ModuleId { get; set; }
25+
26+
/// <summary>
27+
/// Module Connection String.
28+
/// </summary>
29+
public string ConnectionString { get; set; }
30+
}
31+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.Management.IotHub
16+
{
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Management.Automation;
21+
using Microsoft.Azure.Commands.Management.IotHub.Common;
22+
using Microsoft.Azure.Commands.Management.IotHub.Models;
23+
using Microsoft.Azure.Devices;
24+
using Microsoft.Azure.Management.IotHub;
25+
using Microsoft.Azure.Management.IotHub.Models;
26+
using ResourceManager.Common.ArgumentCompleters;
27+
28+
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "IotHubModuleConnectionString", DefaultParameterSetName = ResourceParameterSet)]
29+
[Alias("Get-" + ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "IotHubMCS")]
30+
[OutputType(typeof(PSModuleConnectionString))]
31+
public class GetAzIotHubModuleConnectionString : IotHubBaseCmdlet
32+
{
33+
private const string ResourceIdParameterSet = "ResourceIdSet";
34+
private const string ResourceParameterSet = "ResourceSet";
35+
private const string InputObjectParameterSet = "InputObjectSet";
36+
37+
[Parameter(Position = 0, Mandatory = true, ParameterSetName = InputObjectParameterSet, ValueFromPipeline = true, HelpMessage = "IotHub object")]
38+
[ValidateNotNullOrEmpty]
39+
public PSIotHub InputObject { get; set; }
40+
41+
[Parameter(Position = 0, Mandatory = true, ParameterSetName = ResourceParameterSet, HelpMessage = "Name of the Resource Group")]
42+
[ValidateNotNullOrEmpty]
43+
[ResourceGroupCompleter]
44+
public string ResourceGroupName { get; set; }
45+
46+
[Parameter(Position = 0, Mandatory = true, ParameterSetName = ResourceIdParameterSet, ValueFromPipelineByPropertyName = true, HelpMessage = "IotHub Resource Id")]
47+
[ValidateNotNullOrEmpty]
48+
[ResourceIdCompleter("Microsoft.Devices/IotHubs")]
49+
public string ResourceId { get; set; }
50+
51+
[Parameter(Position = 1, Mandatory = true, ParameterSetName = ResourceParameterSet, HelpMessage = "Name of the Iot Hub")]
52+
[ValidateNotNullOrEmpty]
53+
public string IotHubName { get; set; }
54+
55+
[Parameter(Position = 1, Mandatory = true, ParameterSetName = InputObjectParameterSet, HelpMessage = "Target Device Id.")]
56+
[Parameter(Position = 1, Mandatory = true, ParameterSetName = ResourceIdParameterSet, HelpMessage = "Target Device Id.")]
57+
[Parameter(Position = 2, Mandatory = true, ParameterSetName = ResourceParameterSet, HelpMessage = "Target Device Id.")]
58+
[ValidateNotNullOrEmpty]
59+
public string DeviceId { get; set; }
60+
61+
[Parameter(Mandatory = false, ParameterSetName = InputObjectParameterSet, HelpMessage = "Target Module Id.")]
62+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdParameterSet, HelpMessage = "Target Module Id.")]
63+
[Parameter(Mandatory = false, ParameterSetName = ResourceParameterSet, HelpMessage = "Target Module Id.")]
64+
[ValidateNotNullOrEmpty]
65+
public string ModuleId { get; set; }
66+
67+
[Parameter(Mandatory = false, ParameterSetName = InputObjectParameterSet, HelpMessage = "Shared access policy key type for auth.")]
68+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdParameterSet, HelpMessage = "Shared access policy key type for auth.")]
69+
[Parameter(Mandatory = false, ParameterSetName = ResourceParameterSet, HelpMessage = "Shared access policy key type for auth.")]
70+
public PSKeyType KeyType { get; set; }
71+
72+
public override void ExecuteCmdlet()
73+
{
74+
IotHubDescription iotHubDescription;
75+
if (ParameterSetName.Equals(InputObjectParameterSet))
76+
{
77+
this.ResourceGroupName = this.InputObject.Resourcegroup;
78+
this.IotHubName = this.InputObject.Name;
79+
iotHubDescription = IotHubUtils.ConvertObject<PSIotHub, IotHubDescription>(this.InputObject);
80+
}
81+
else
82+
{
83+
if (ParameterSetName.Equals(ResourceIdParameterSet))
84+
{
85+
this.ResourceGroupName = IotHubUtils.GetResourceGroupName(this.ResourceId);
86+
this.IotHubName = IotHubUtils.GetIotHubName(this.ResourceId);
87+
}
88+
89+
iotHubDescription = this.IotHubClient.IotHubResource.Get(this.ResourceGroupName, this.IotHubName);
90+
}
91+
92+
IEnumerable<SharedAccessSignatureAuthorizationRule> authPolicies = this.IotHubClient.IotHubResource.ListKeys(this.ResourceGroupName, this.IotHubName);
93+
SharedAccessSignatureAuthorizationRule policy = IotHubUtils.GetPolicy(authPolicies, PSAccessRights.RegistryRead);
94+
PSIotHubConnectionString psIotHubConnectionString = IotHubUtils.ToPSIotHubConnectionString(policy, iotHubDescription.Properties.HostName);
95+
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(psIotHubConnectionString.PrimaryConnectionString);
96+
Device device = registryManager.GetDeviceAsync(this.DeviceId).GetAwaiter().GetResult();
97+
if (device != null)
98+
{
99+
List<Module> modules = registryManager.GetModulesOnDeviceAsync(this.DeviceId).GetAwaiter().GetResult().ToList();
100+
if (this.ModuleId != null)
101+
{
102+
if (modules.Any(m => m.Id.Equals(this.ModuleId)))
103+
{
104+
this.WriteObject(GetModuleConnectionString(modules.FirstOrDefault(m => m.Id.Equals(this.ModuleId)), iotHubDescription.Properties.HostName));
105+
}
106+
}
107+
else
108+
{
109+
IList<PSModuleConnectionString> psModuleConnectionStringCollection = new List<PSModuleConnectionString>();
110+
foreach (Module module in modules)
111+
{
112+
psModuleConnectionStringCollection.Add(GetModuleConnectionString(module, iotHubDescription.Properties.HostName));
113+
}
114+
115+
this.WriteObject(psModuleConnectionStringCollection, true);
116+
}
117+
}
118+
}
119+
120+
private PSModuleConnectionString GetModuleConnectionString(Module module, string hostName)
121+
{
122+
string key;
123+
switch (module.Authentication.Type)
124+
{
125+
case AuthenticationType.Sas:
126+
key = string.Format("SharedAccessKey={0}", this.KeyType.Equals(PSKeyType.primary) ? module.Authentication.SymmetricKey.PrimaryKey : module.Authentication.SymmetricKey.SecondaryKey);
127+
break;
128+
case AuthenticationType.SelfSigned:
129+
case AuthenticationType.CertificateAuthority:
130+
key = "x509=true";
131+
break;
132+
default:
133+
throw new ArgumentNullException("Unable to get authentication type of device.");
134+
}
135+
136+
PSModuleConnectionString psModuleConnectionString = new PSModuleConnectionString
137+
{
138+
ModuleId = module.Id,
139+
ConnectionString = $"HostName={hostName};DeviceId={module.DeviceId};ModuleId={module.Id};{key}"
140+
};
141+
142+
return psModuleConnectionString;
143+
}
144+
}
145+
}

src/IotHub/IotHub/help/Az.IotHub.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ Lists all message enrichments or a particular message enrichment for your IoT Hu
6868
### [Get-AzIotHubModule](Get-AzIotHubModule.md)
6969
Get the details of an IoT device module or list modules located on an IoT device in an IoT Hub.
7070

71+
### [Get-AzIotHubModuleConnectionString](Get-AzIotHubModuleConnectionString.md)
72+
Get the connection string of a target IoT device module in an Iot Hub.
73+
7174
### [Get-AzIotHubQuotaMetric](Get-AzIotHubQuotaMetric.md)
7275
Gets the Quota Metrics for an IotHub.
7376

0 commit comments

Comments
 (0)