Skip to content

Commit cb5631d

Browse files
committed
Add cmdlet to get device connection string
1 parent a59f6cc commit cb5631d

File tree

11 files changed

+789
-280
lines changed

11 files changed

+789
-280
lines changed

src/IotHub/IotHub.Test/ScenarioTests/IotHubDPDeviceTests.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ function Test-AzureRmIotHubDeviceLifecycle
6565
$devices = Get-AzIotHubDevice -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName
6666
Assert-True { $devices.Count -eq 3}
6767

68+
# Get device connection string
69+
$deviceCS = Get-AzIotHubDCS -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName -DeviceId $device3
70+
Assert-True { $deviceCS.DeviceId -eq $device3 }
71+
Assert-True { $deviceCS.ConnectionString -eq "HostName=$IotHubName.azure-devices.net;DeviceId=$device3;x509=true" }
72+
6873
# Update Device
6974
$updatedDevice1 = Set-AzIoTHubDevice -ResourceGroupName $ResourceGroupName -IotHubName $IotHubName -DeviceId $device1 -Status 'Disabled' -StatusReason 'Reason1'
7075
Assert-True { $updatedDevice1.Id -eq $device1 }

src/IotHub/IotHub.Test/SessionRecords/Microsoft.Azure.Commands.IotHub.Test.ScenarioTests.IotHubDPDeviceTests/TestAzureIotHubDeviceLifecycle.json

Lines changed: 379 additions & 253 deletions
Large diffs are not rendered by default.

src/IotHub/IotHub/Az.IotHub.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ CmdletsToExport = 'Add-AzIotHubKey', 'Get-AzIotHubEventHubConsumerGroup',
9696
'Get-AzIotHubDevice', 'Remove-AzIotHubDevice',
9797
'Set-AzIotHubDevice', 'Add-AzIotHubModule',
9898
'Get-AzIotHubModule', 'Remove-AzIotHubModule',
99-
'Set-AzIotHubModule'
99+
'Set-AzIotHubModule', 'Get-AzIotHubDeviceConnectionString'
100100
# Variables to export from this module
101101
# VariablesToExport = @()
102102

103103
# 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.
104104
AliasesToExport = 'Get-AzIotHubEHCG', 'Add-AzIotHubEHCG', 'Remove-AzIotHubEHCG',
105105
'Set-AzIotHubVC', 'Get-AzIotHubCVC', 'Add-AzIotHubMsgEnrich',
106106
'Get-AzIotHubMsgEnrich', 'Remove-AzIotHubMsgEnrich',
107-
'Set-AzIotHubMsgEnrich'
107+
'Set-AzIotHubMsgEnrich', 'Get-AzIotHubDCS'
108108

109109
# DSC resources to export from this module
110110
# DscResourcesToExport = @()

src/IotHub/IotHub/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- Get-AzIotHubModule
2929
- Remove-AzIotHubModule
3030
- Set-AzIotHubModule
31+
* Add cmdlet to get the connection string of a target IoT device in an Iot Hub.
3132

3233
## Version 2.0.1
3334
* Update references in .psd1 to use relative path
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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.Management.Automation;
20+
using Microsoft.Azure.Commands.Management.IotHub.Common;
21+
using Microsoft.Azure.Commands.Management.IotHub.Models;
22+
using Microsoft.Azure.Devices;
23+
using Microsoft.Azure.Management.IotHub;
24+
using Microsoft.Azure.Management.IotHub.Models;
25+
using Newtonsoft.Json;
26+
using ResourceManager.Common.ArgumentCompleters;
27+
28+
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "IotHubDeviceConnectionString", DefaultParameterSetName = ResourceParameterSet)]
29+
[Alias("Get-" + ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "IotHubDCS")]
30+
[OutputType(typeof(PSDeviceConnectionString))]
31+
public class GetAzIotHubDeviceConnectionString : 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(Mandatory = false, ParameterSetName = InputObjectParameterSet, HelpMessage = "Target Device Id.")]
56+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdParameterSet, HelpMessage = "Target Device Id.")]
57+
[Parameter(Mandatory = false, ParameterSetName = ResourceParameterSet, HelpMessage = "Target Device Id.")]
58+
public string DeviceId { get; set; }
59+
60+
[Parameter(Mandatory = false, ParameterSetName = InputObjectParameterSet, HelpMessage = "Shared access policy key type for auth.")]
61+
[Parameter(Mandatory = false, ParameterSetName = ResourceIdParameterSet, HelpMessage = "Shared access policy key type for auth.")]
62+
[Parameter(Mandatory = false, ParameterSetName = ResourceParameterSet, HelpMessage = "Shared access policy key type for auth.")]
63+
public PSKeyType KeyType { get; set; }
64+
65+
public override void ExecuteCmdlet()
66+
{
67+
IotHubDescription iotHubDescription;
68+
if (ParameterSetName.Equals(InputObjectParameterSet))
69+
{
70+
this.ResourceGroupName = this.InputObject.Resourcegroup;
71+
this.IotHubName = this.InputObject.Name;
72+
iotHubDescription = IotHubUtils.ConvertObject<PSIotHub, IotHubDescription>(this.InputObject);
73+
}
74+
else
75+
{
76+
if (ParameterSetName.Equals(ResourceIdParameterSet))
77+
{
78+
this.ResourceGroupName = IotHubUtils.GetResourceGroupName(this.ResourceId);
79+
this.IotHubName = IotHubUtils.GetIotHubName(this.ResourceId);
80+
}
81+
82+
iotHubDescription = this.IotHubClient.IotHubResource.Get(this.ResourceGroupName, this.IotHubName);
83+
}
84+
85+
IEnumerable<SharedAccessSignatureAuthorizationRule> authPolicies = this.IotHubClient.IotHubResource.ListKeys(this.ResourceGroupName, this.IotHubName);
86+
SharedAccessSignatureAuthorizationRule policy = IotHubUtils.GetPolicy(authPolicies, PSAccessRights.RegistryRead);
87+
PSIotHubConnectionString psIotHubConnectionString = IotHubUtils.ToPSIotHubConnectionString(policy, iotHubDescription.Properties.HostName);
88+
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(psIotHubConnectionString.PrimaryConnectionString);
89+
if (this.DeviceId != null)
90+
{
91+
Device device = registryManager.GetDeviceAsync(this.DeviceId).GetAwaiter().GetResult();
92+
this.WriteObject(GetDeviceConnectionString(device, iotHubDescription.Properties.HostName));
93+
}
94+
else
95+
{
96+
IEnumerable<string> deviceResults = registryManager.CreateQuery("Select * from Devices").GetNextAsJsonAsync().GetAwaiter().GetResult();
97+
IList<PSDeviceConnectionString> psDeviceConnectionStringCollection = new List<PSDeviceConnectionString>();
98+
foreach (string deviceResult in deviceResults)
99+
{
100+
Device device = registryManager.GetDeviceAsync(JsonConvert.DeserializeObject<Device>(deviceResult).Id).GetAwaiter().GetResult();
101+
psDeviceConnectionStringCollection.Add(GetDeviceConnectionString(device, iotHubDescription.Properties.HostName));
102+
}
103+
104+
this.WriteObject(psDeviceConnectionStringCollection, true);
105+
}
106+
}
107+
108+
private PSDeviceConnectionString GetDeviceConnectionString(Device device, string hostName)
109+
{
110+
string key;
111+
switch (device.Authentication.Type)
112+
{
113+
case AuthenticationType.Sas:
114+
key = string.Format("SharedAccessKey={0}", this.KeyType.Equals(PSKeyType.primary) ? device.Authentication.SymmetricKey.PrimaryKey : device.Authentication.SymmetricKey.SecondaryKey);
115+
break;
116+
case AuthenticationType.SelfSigned:
117+
case AuthenticationType.CertificateAuthority:
118+
key = "x509=true";
119+
break;
120+
default:
121+
throw new ArgumentNullException("Unable to get authentication type of device.");
122+
}
123+
124+
PSDeviceConnectionString psDeviceConnectionString = new PSDeviceConnectionString
125+
{
126+
DeviceId = device.Id,
127+
ConnectionString = $"HostName={hostName};DeviceId={device.Id};{key}"
128+
};
129+
130+
return psDeviceConnectionString;
131+
}
132+
}
133+
}
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 device.
17+
/// </summary>
18+
19+
public class PSDeviceConnectionString
20+
{
21+
/// <summary>
22+
/// Device ID.
23+
/// </summary>
24+
public string DeviceId { get; set; }
25+
26+
/// <summary>
27+
/// Device Connection String.
28+
/// </summary>
29+
public string ConnectionString { get; set; }
30+
}
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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.Models
16+
{
17+
/// <summary>
18+
/// Shared private key.
19+
/// </summary>
20+
public enum PSKeyType
21+
{
22+
primary,
23+
secondary
24+
}
25+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ Gets the IotHub connectionstrings.
5050
### [Get-AzIotHubDevice](Get-AzIotHubDevice.md)
5151
Lists all devices or a particular device contained within an Azure IoT Hub.
5252

53+
### [Get-AzIotHubDeviceConnectionString](Get-AzIotHubDeviceConnectionString.md)
54+
Get the connection string of a target IoT device in an Iot Hub.
55+
5356
### [Get-AzIotHubEventHubConsumerGroup](Get-AzIotHubEventHubConsumerGroup.md)
5457
Gets all the eventhub consumergroups.
5558

0 commit comments

Comments
 (0)