Skip to content

Commit d0fb2f6

Browse files
fenwicktmakharch
andauthored
Fix for output type and null subscriptions collection in ResourceGraph (#15135)
* Fixed null subscriptions exception, added change log * Added output type fix and updated tests Changes from PR #15125 * regenerated ps1xml, updated examples * Updated md file for the output type and changelog * added breaking change issues csv after rebasing with master * added parenthesses to csv to fix parsing issue Co-authored-by: makharch <makharch@microsoft.com>
1 parent dbf0b22 commit d0fb2f6

File tree

8 files changed

+81
-35
lines changed

8 files changed

+81
-35
lines changed

src/ResourceGraph/ResourceGraph.Test/ScenarioTests/ResourceGraphQueryTests.ps1

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ Run simple query
1919
function Search-AzureRmGraph-Query
2020
{
2121
$queryResult = Search-AzGraph 'Resources | where tags != "" | project id, tags, properties | limit 2'
22-
23-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
22+
23+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
2424
Assert-Null $queryResult.SkipToken
2525
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
2626
Assert-AreEqual 2 $queryResult.Data.Count
@@ -55,7 +55,7 @@ function Search-AzureRmGraph-PagedQuery
5555
# Page size was artificially set to 2 rows
5656
$queryResult = Search-AzGraph "project id" -First 3 -Skip 2
5757

58-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
58+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
5959
Assert-IsInstance System.String $queryResult.SkipToken
6060
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
6161
Assert-AreEqual 3 $queryResult.Data.Count
@@ -95,17 +95,17 @@ function Search-AzureRmGraph-Subscriptions
9595
$queryResultOneSub = Search-AzGraph $query -Subscription $testSubId
9696
$queryResultMultipleSubs = Search-AzGraph $query -Subscription @($testSubId, $nonExsitentTestSubId)
9797

98-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultSubsFromContext
98+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultSubsFromContext
9999
Assert-Null $queryResultSubsFromContext.SkipToken
100100
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultSubsFromContext.Data
101101
Assert-AreEqual $testSubId $queryResultSubsFromContext.Data.subscriptionId
102102

103-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultOneSub
103+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultOneSub
104104
Assert-Null $queryResultOneSub.SkipToken
105105
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultOneSub.Data
106106
Assert-AreEqual $testSubId $queryResultOneSub.Data.subscriptionId
107107

108-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultMultipleSubs
108+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultMultipleSubs
109109
Assert-Null $queryResultMultipleSubs.SkipToken
110110
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultMultipleSubs.Data
111111
Assert-AreEqual $testSubId $queryResultMultipleSubs.Data.subscriptionId
@@ -126,12 +126,12 @@ function Search-AzureRmGraph-ManagementGroups
126126
$queryResultOneMg = Search-AzGraph $query -ManagementGroup $testMgId1
127127
$queryResultMultipleMgs = Search-AzGraph $query -ManagementGroup @($testMgId1, $testMgId2, $nonExistentTestMgId) -AllowPartialScope
128128

129-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultOneMg
129+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultOneMg
130130
Assert-Null $queryResultOneMg.SkipToken
131131
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultOneMg.Data
132132
Assert-AreEqual $testSubId $queryResultOneMg.Data.subscriptionId
133133

134-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultMultipleMgs
134+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultMultipleMgs
135135
Assert-Null $queryResultMultipleMgs.SkipToken
136136
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultMultipleMgs.Data
137137
Assert-AreEqual $testSubId $queryResultMultipleMgs.Data.subscriptionId
@@ -145,7 +145,7 @@ function Search-AzureRmGraph-SkipTokenQuery
145145
{
146146
$queryResult = Search-AzGraph "project id, properties" -SkipToken "ew0KICAiJGlkIjogIjEiLA0KICAiTWF4Um93cyI6IDMsDQogICJSb3dzVG9Ta2lwIjogMywNCiAgIkt1c3RvQ2x1c3RlclVybCI6ICJodHRwczovL2FyZy1ldXMtc2l4LXNmLmFyZy5jb3JlLndpbmRvd3MubmV0Ig0KfQ=="
147147

148-
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
148+
Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
149149
Assert-IsInstance System.String $queryResult.SkipToken
150150
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
151151
Assert-AreEqual 3 $queryResult.Data.Count

src/ResourceGraph/ResourceGraph/Az.ResourceGraph.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ RequiredAssemblies = 'Microsoft.Azure.Management.ResourceGraph.dll',
6666
# TypesToProcess = @()
6767

6868
# Format files (.ps1xml) to be loaded when importing this module
69-
FormatsToProcess = 'ResourceGraph.format.ps1xml',
69+
FormatsToProcess = 'Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.generated.format.ps1xml',
7070
'ResourceGraph.Autorest\Az.ResourceGraph.format.ps1xml'
7171

7272
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
73-
NestedModules = @('Az.ResourceGraph.psm1',
73+
NestedModules = @('Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.dll',
7474
'ResourceGraph.Autorest\Az.ResourceGraph.psm1')
7575

7676
# Functions 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 functions to export.

src/ResourceGraph/ResourceGraph/ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Fixed the output print issue for `Search-AzGraph` by updating the output type to Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]].
22+
* Fixed the issue when Search-AzGraph fails if no subscriptions are stored in the context.
2123

2224
## Version 0.10.0
2325
* Changed output of `Search-AzGraph` to PSResourceGraphResponse which wrapped previous output under Data property.

src/ResourceGraph/ResourceGraph/Cmdlets/SearchAzureRmGraph.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Microsoft.Azure.Commands.ResourceGraph.Cmdlets
2727
/// Search-AzGraph cmdlet
2828
/// </summary>
2929
/// <seealso cref="Microsoft.Azure.Commands.ResourceGraph.Utilities.ResourceGraphBaseCmdlet" />
30-
[Cmdlet(VerbsCommon.Search, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Graph", DefaultParameterSetName = "SubscriptionScopedQuery"), OutputType(typeof(PSResourceGraphResponse))]
30+
[Cmdlet(VerbsCommon.Search, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Graph", DefaultParameterSetName = "SubscriptionScopedQuery"), OutputType(typeof(PSResourceGraphResponse<PSObject>))]
3131
public class SearchAzureRmGraph : ResourceGraphBaseCmdlet
3232
{
3333
/// <summary>
@@ -150,7 +150,7 @@ public override void ExecuteCmdlet()
150150
IList<string> subscriptions = null;
151151
if (managementGroups == null)
152152
{
153-
subscriptions = this.GetSubscriptions().ToList();
153+
subscriptions = this.GetSubscriptions()?.ToList();
154154
if (subscriptions != null && subscriptions.Count > SubscriptionLimit)
155155
{
156156
subscriptions = subscriptions.Take(SubscriptionLimit).ToList();
@@ -160,7 +160,7 @@ public override void ExecuteCmdlet()
160160
}
161161
}
162162

163-
var psResourceGraphResponse = new PSResourceGraphResponse();
163+
var psResourceGraphResponse = new PSResourceGraphResponse<PSObject>();
164164
QueryResponse response = null;
165165

166166
var resultTruncated = false;
@@ -262,7 +262,7 @@ private IEnumerable<string> GetSubscriptions()
262262
}
263263

264264
var accountSubscriptions = this.DefaultContext.Account.GetSubscriptions();
265-
if (accountSubscriptions.Length > 0)
265+
if (accountSubscriptions?.Length > 0)
266266
{
267267
return accountSubscriptions;
268268
}
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0"?>
22
<Configuration>
33
<ViewDefinitions>
44
<View>
5-
<Name>Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse</Name>
5+
<Name>Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]</Name>
66
<ViewSelectedBy>
7-
<TypeName>Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse</TypeName>
7+
<TypeName>Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]</TypeName>
88
</ViewSelectedBy>
99
<ListControl>
1010
<ListEntries>
1111
<ListEntry>
1212
<ListItems>
1313
<ListItem>
1414
<PropertyName>SkipToken</PropertyName>
15-
<ItemSelectionCondition>
16-
<ScriptBlock>
17-
$_.SkipToken -ne $null
18-
</ScriptBlock>
19-
</ItemSelectionCondition>
2015
</ListItem>
2116
<ListItem>
2217
<PropertyName>Data</PropertyName>
23-
</ListItem>
18+
</ListItem>
2419
</ListItems>
2520
</ListEntry>
2621
</ListEntries>
2722
</ListControl>
2823
</View>
2924
</ViewDefinitions>
30-
</Configuration>
25+
</Configuration>

src/ResourceGraph/ResourceGraph/Models/PSResourceGraphResponse.cs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,53 @@
1414

1515
namespace Microsoft.Azure.Commands.ResourceGraph.Models
1616
{
17+
using System.Collections;
1718
using System.Collections.Generic;
18-
using System.Management.Automation;
1919
using Microsoft.WindowsAzure.Commands.Common.Attributes;
2020

21-
public class PSResourceGraphResponse
21+
public class PSResourceGraphResponse<PSObject> : IList<PSObject>
2222
{
2323
[Ps1Xml(Target = ViewControl.List)]
2424
public string SkipToken { get; set; }
2525

2626
[Ps1Xml(Target = ViewControl.List)]
2727
public IList<PSObject> Data { get; set; }
28+
public PSObject this[int index]
29+
{
30+
get => Data[index];
31+
set => Data[index] = value;
32+
}
2833

34+
public IEnumerator<PSObject> GetEnumerator()
35+
{
36+
return Data.GetEnumerator();
37+
}
38+
39+
IEnumerator IEnumerable.GetEnumerator()
40+
{
41+
return GetEnumerator();
42+
}
43+
44+
public bool IsReadOnly => Data.IsReadOnly;
45+
46+
public int Count => Data.Count;
47+
48+
public void Add(PSObject value) => Data.Add(value);
49+
50+
public void Clear() => Data.Clear();
51+
52+
public bool Contains(PSObject value) => Data.Contains(value);
53+
54+
public void CopyTo(PSObject[] array, int index) => Data.CopyTo(array, index);
55+
56+
public int IndexOf(PSObject value) => Data.IndexOf(value);
57+
58+
public void Insert(int index, PSObject value) => Data.Insert(index, value);
59+
60+
public void Remove(PSObject value) => Data.Remove(value);
61+
62+
public void RemoveAt(int index) => Data.RemoveAt(index);
63+
64+
bool ICollection<PSObject>.Remove(PSObject item) => Data.Remove(item);
2965
}
3066
}

src/ResourceGraph/ResourceGraph/help/Search-AzGraph.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ name : nt
3939
type : microsoft.compute/virtualmachinescalesets
4040
location : eastus
4141
tags : @{resourceType=Service Fabric; clusterName=gov-art-int-nt-a}
42+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
4243
4344
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
4445
name : egtopic-1
4546
type : microsoft.eventgrid/topics
4647
location : westus2
4748
tags :
49+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
4850
```
4951

5052
Simple resources query requesting a subset of resource fields.
@@ -64,34 +66,43 @@ A complex query on resources featuring field selection, filtering and summarizin
6466

6567
### Example 3
6668
```powershell
67-
PS C:\> Search-AzGraph -Query 'project id, name' -SkipToken 'skiptokenvaluefromthepreviousquery=='
69+
PS C:\> $response = Search-AzGraph -Query "project id, name, type, location" -First 2
70+
PS C:\> Search-AzGraph -Query "project id, name, type, location" -SkipToken $response.SkipToken
6871
6972
70-
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-b/providers/Microsoft.Compute/virtualMachineScaleSets/nt2
71-
name : nt2
73+
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkInterfaces/17ni
74+
name : 17ni
75+
type : microsoft.network/networkinterfaces
76+
location : westeurope
77+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkInterfaces/17ni
7278
73-
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-b/providers/Microsoft.EventGrid/topics/egtopic-2
74-
name : egtopic-2
79+
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkSecurityGroups/17nsg
80+
name : 17nsg
81+
type : microsoft.network/networksecuritygroups
82+
location : westeurope
83+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkSecurityGroups/17nsg
7584
```
7685

77-
A query with the skip token passed from the previous query results
86+
A query with the skip token passed from the previous query results. Please note that keeping id in the results is mandatory to get back a skip token.
7887

7988
### Example 4
8089
```powershell
81-
PS C:\> Search-AzGraph -Query 'project id, name, type, location, tags' -First 2 -ManagementGroup 'MyManagementGroupId' -AllowPartialScope
90+
PS C:\> Search-AzGraph -Query "project id, name, type, location, tags" -First 2 -ManagementGroup MyManagementGroupId -AllowPartialScope
8291
8392
8493
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
8594
name : nt
8695
type : microsoft.compute/virtualmachinescalesets
8796
location : eastus
8897
tags : @{resourceType=Service Fabric; clusterName=gov-art-int-nt-a}
98+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
8999
90100
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
91101
name : egtopic-1
92102
type : microsoft.eventgrid/topics
93103
location : westus2
94104
tags :
105+
ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
95106
```
96107

97108
A query scoped to the management group that allows the query to succeed with partial scope result if MyManagementGroupId has more than N subscriptions underneath.
@@ -229,7 +240,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
229240
230241
## OUTPUTS
231242
232-
### Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse
243+
### Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]
233244

234245
## NOTES
235246

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"AssemblyFileName","ClassName","Target","Severity","ProblemId","Description","Remediation"
2+
"Az.ResourceGraph","Microsoft.Azure.Commands.ResourceGraph.Cmdlets.SearchAzureRmGraph","Search-AzGraph","0","1020","The cmdlet 'Search-AzGraph' no longer has output type 'Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse'.","Make cmdlet 'Search-AzGraph' return type 'Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse'."

0 commit comments

Comments
 (0)