diff --git a/src/ResourceGraph/ResourceGraph.Test/ScenarioTests/ResourceGraphQueryTests.ps1 b/src/ResourceGraph/ResourceGraph.Test/ScenarioTests/ResourceGraphQueryTests.ps1
index baa48a3dfb79..71cdff1996e4 100644
--- a/src/ResourceGraph/ResourceGraph.Test/ScenarioTests/ResourceGraphQueryTests.ps1
+++ b/src/ResourceGraph/ResourceGraph.Test/ScenarioTests/ResourceGraphQueryTests.ps1
@@ -19,8 +19,8 @@ Run simple query
function Search-AzureRmGraph-Query
{
$queryResult = Search-AzGraph 'Resources | where tags != "" | project id, tags, properties | limit 2'
-
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
+
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
Assert-Null $queryResult.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
Assert-AreEqual 2 $queryResult.Data.Count
@@ -55,7 +55,7 @@ function Search-AzureRmGraph-PagedQuery
# Page size was artificially set to 2 rows
$queryResult = Search-AzGraph "project id" -First 3 -Skip 2
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
Assert-IsInstance System.String $queryResult.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
Assert-AreEqual 3 $queryResult.Data.Count
@@ -95,17 +95,17 @@ function Search-AzureRmGraph-Subscriptions
$queryResultOneSub = Search-AzGraph $query -Subscription $testSubId
$queryResultMultipleSubs = Search-AzGraph $query -Subscription @($testSubId, $nonExsitentTestSubId)
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultSubsFromContext
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultSubsFromContext
Assert-Null $queryResultSubsFromContext.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultSubsFromContext.Data
Assert-AreEqual $testSubId $queryResultSubsFromContext.Data.subscriptionId
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultOneSub
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultOneSub
Assert-Null $queryResultOneSub.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultOneSub.Data
Assert-AreEqual $testSubId $queryResultOneSub.Data.subscriptionId
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultMultipleSubs
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultMultipleSubs
Assert-Null $queryResultMultipleSubs.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultMultipleSubs.Data
Assert-AreEqual $testSubId $queryResultMultipleSubs.Data.subscriptionId
@@ -126,12 +126,12 @@ function Search-AzureRmGraph-ManagementGroups
$queryResultOneMg = Search-AzGraph $query -ManagementGroup $testMgId1
$queryResultMultipleMgs = Search-AzGraph $query -ManagementGroup @($testMgId1, $testMgId2, $nonExistentTestMgId) -AllowPartialScope
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultOneMg
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultOneMg
Assert-Null $queryResultOneMg.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultOneMg.Data
Assert-AreEqual $testSubId $queryResultOneMg.Data.subscriptionId
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResultMultipleMgs
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResultMultipleMgs
Assert-Null $queryResultMultipleMgs.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResultMultipleMgs.Data
Assert-AreEqual $testSubId $queryResultMultipleMgs.Data.subscriptionId
@@ -145,7 +145,7 @@ function Search-AzureRmGraph-SkipTokenQuery
{
$queryResult = Search-AzGraph "project id, properties" -SkipToken "ew0KICAiJGlkIjogIjEiLA0KICAiTWF4Um93cyI6IDMsDQogICJSb3dzVG9Ta2lwIjogMywNCiAgIkt1c3RvQ2x1c3RlclVybCI6ICJodHRwczovL2FyZy1ldXMtc2l4LXNmLmFyZy5jb3JlLndpbmRvd3MubmV0Ig0KfQ=="
- Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse $queryResult
+ Assert-IsInstance Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse[PSObject] $queryResult
Assert-IsInstance System.String $queryResult.SkipToken
Assert-IsInstance System.Collections.Generic.List[PSObject] $queryResult.Data
Assert-AreEqual 3 $queryResult.Data.Count
diff --git a/src/ResourceGraph/ResourceGraph/Az.ResourceGraph.psd1 b/src/ResourceGraph/ResourceGraph/Az.ResourceGraph.psd1
index 29b3d7e14b69..0c34a6f1dbe3 100644
--- a/src/ResourceGraph/ResourceGraph/Az.ResourceGraph.psd1
+++ b/src/ResourceGraph/ResourceGraph/Az.ResourceGraph.psd1
@@ -66,11 +66,11 @@ RequiredAssemblies = 'Microsoft.Azure.Management.ResourceGraph.dll',
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
-FormatsToProcess = 'ResourceGraph.format.ps1xml',
+FormatsToProcess = 'Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.generated.format.ps1xml',
'ResourceGraph.Autorest\Az.ResourceGraph.format.ps1xml'
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-NestedModules = @('Az.ResourceGraph.psm1',
+NestedModules = @('Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.dll',
'ResourceGraph.Autorest\Az.ResourceGraph.psm1')
# 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.
diff --git a/src/ResourceGraph/ResourceGraph/ChangeLog.md b/src/ResourceGraph/ResourceGraph/ChangeLog.md
index b0c35744ab08..2c6fb3a64f1e 100644
--- a/src/ResourceGraph/ResourceGraph/ChangeLog.md
+++ b/src/ResourceGraph/ResourceGraph/ChangeLog.md
@@ -18,6 +18,8 @@
- Additional information about change #1
-->
## Upcoming Release
+* 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]].
+* Fixed the issue when Search-AzGraph fails if no subscriptions are stored in the context.
## Version 0.10.0
* Changed output of `Search-AzGraph` to PSResourceGraphResponse which wrapped previous output under Data property.
diff --git a/src/ResourceGraph/ResourceGraph/Cmdlets/SearchAzureRmGraph.cs b/src/ResourceGraph/ResourceGraph/Cmdlets/SearchAzureRmGraph.cs
index 674d722d56da..a8d7a79313ca 100644
--- a/src/ResourceGraph/ResourceGraph/Cmdlets/SearchAzureRmGraph.cs
+++ b/src/ResourceGraph/ResourceGraph/Cmdlets/SearchAzureRmGraph.cs
@@ -27,7 +27,7 @@ namespace Microsoft.Azure.Commands.ResourceGraph.Cmdlets
/// Search-AzGraph cmdlet
///
///
- [Cmdlet(VerbsCommon.Search, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Graph", DefaultParameterSetName = "SubscriptionScopedQuery"), OutputType(typeof(PSResourceGraphResponse))]
+ [Cmdlet(VerbsCommon.Search, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "Graph", DefaultParameterSetName = "SubscriptionScopedQuery"), OutputType(typeof(PSResourceGraphResponse))]
public class SearchAzureRmGraph : ResourceGraphBaseCmdlet
{
///
@@ -150,7 +150,7 @@ public override void ExecuteCmdlet()
IList subscriptions = null;
if (managementGroups == null)
{
- subscriptions = this.GetSubscriptions().ToList();
+ subscriptions = this.GetSubscriptions()?.ToList();
if (subscriptions != null && subscriptions.Count > SubscriptionLimit)
{
subscriptions = subscriptions.Take(SubscriptionLimit).ToList();
@@ -160,7 +160,7 @@ public override void ExecuteCmdlet()
}
}
- var psResourceGraphResponse = new PSResourceGraphResponse();
+ var psResourceGraphResponse = new PSResourceGraphResponse();
QueryResponse response = null;
var resultTruncated = false;
@@ -262,7 +262,7 @@ private IEnumerable GetSubscriptions()
}
var accountSubscriptions = this.DefaultContext.Account.GetSubscriptions();
- if (accountSubscriptions.Length > 0)
+ if (accountSubscriptions?.Length > 0)
{
return accountSubscriptions;
}
diff --git a/src/ResourceGraph/ResourceGraph/ResourceGraph.format.ps1xml b/src/ResourceGraph/ResourceGraph/Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.generated.format.ps1xml
similarity index 64%
rename from src/ResourceGraph/ResourceGraph/ResourceGraph.format.ps1xml
rename to src/ResourceGraph/ResourceGraph/Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.generated.format.ps1xml
index c37333a6aec6..376e897d9630 100644
--- a/src/ResourceGraph/ResourceGraph/ResourceGraph.format.ps1xml
+++ b/src/ResourceGraph/ResourceGraph/Microsoft.Azure.PowerShell.Cmdlets.ResourceGraph.generated.format.ps1xml
@@ -1,10 +1,10 @@
-
+
- Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse
+ Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]
- Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse
+ Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]
@@ -12,19 +12,14 @@
SkipToken
-
-
- $_.SkipToken -ne $null
-
-
Data
-
+
-
+
\ No newline at end of file
diff --git a/src/ResourceGraph/ResourceGraph/Models/PSResourceGraphResponse.cs b/src/ResourceGraph/ResourceGraph/Models/PSResourceGraphResponse.cs
index 96e81b15eb35..31534deadb6e 100644
--- a/src/ResourceGraph/ResourceGraph/Models/PSResourceGraphResponse.cs
+++ b/src/ResourceGraph/ResourceGraph/Models/PSResourceGraphResponse.cs
@@ -14,17 +14,53 @@
namespace Microsoft.Azure.Commands.ResourceGraph.Models
{
+ using System.Collections;
using System.Collections.Generic;
- using System.Management.Automation;
using Microsoft.WindowsAzure.Commands.Common.Attributes;
- public class PSResourceGraphResponse
+ public class PSResourceGraphResponse : IList
{
[Ps1Xml(Target = ViewControl.List)]
public string SkipToken { get; set; }
[Ps1Xml(Target = ViewControl.List)]
public IList Data { get; set; }
+ public PSObject this[int index]
+ {
+ get => Data[index];
+ set => Data[index] = value;
+ }
+ public IEnumerator GetEnumerator()
+ {
+ return Data.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public bool IsReadOnly => Data.IsReadOnly;
+
+ public int Count => Data.Count;
+
+ public void Add(PSObject value) => Data.Add(value);
+
+ public void Clear() => Data.Clear();
+
+ public bool Contains(PSObject value) => Data.Contains(value);
+
+ public void CopyTo(PSObject[] array, int index) => Data.CopyTo(array, index);
+
+ public int IndexOf(PSObject value) => Data.IndexOf(value);
+
+ public void Insert(int index, PSObject value) => Data.Insert(index, value);
+
+ public void Remove(PSObject value) => Data.Remove(value);
+
+ public void RemoveAt(int index) => Data.RemoveAt(index);
+
+ bool ICollection.Remove(PSObject item) => Data.Remove(item);
}
}
diff --git a/src/ResourceGraph/ResourceGraph/help/Search-AzGraph.md b/src/ResourceGraph/ResourceGraph/help/Search-AzGraph.md
index cd4d771d943f..5b06bda9f2b2 100644
--- a/src/ResourceGraph/ResourceGraph/help/Search-AzGraph.md
+++ b/src/ResourceGraph/ResourceGraph/help/Search-AzGraph.md
@@ -39,12 +39,14 @@ name : nt
type : microsoft.compute/virtualmachinescalesets
location : eastus
tags : @{resourceType=Service Fabric; clusterName=gov-art-int-nt-a}
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
name : egtopic-1
type : microsoft.eventgrid/topics
location : westus2
tags :
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
```
Simple resources query requesting a subset of resource fields.
@@ -64,21 +66,28 @@ A complex query on resources featuring field selection, filtering and summarizin
### Example 3
```powershell
-PS C:\> Search-AzGraph -Query 'project id, name' -SkipToken 'skiptokenvaluefromthepreviousquery=='
+PS C:\> $response = Search-AzGraph -Query "project id, name, type, location" -First 2
+PS C:\> Search-AzGraph -Query "project id, name, type, location" -SkipToken $response.SkipToken
-id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-b/providers/Microsoft.Compute/virtualMachineScaleSets/nt2
-name : nt2
+id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkInterfaces/17ni
+name : 17ni
+type : microsoft.network/networkinterfaces
+location : westeurope
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkInterfaces/17ni
-id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-b/providers/Microsoft.EventGrid/topics/egtopic-2
-name : egtopic-2
+id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkSecurityGroups/17nsg
+name : 17nsg
+type : microsoft.network/networksecuritygroups
+location : westeurope
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/test/providers/Microsoft.Network/networkSecurityGroups/17nsg
```
-A query with the skip token passed from the previous query results
+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.
### Example 4
```powershell
-PS C:\> Search-AzGraph -Query 'project id, name, type, location, tags' -First 2 -ManagementGroup 'MyManagementGroupId' -AllowPartialScope
+PS C:\> Search-AzGraph -Query "project id, name, type, location, tags" -First 2 -ManagementGroup MyManagementGroupId -AllowPartialScope
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
@@ -86,12 +95,14 @@ name : nt
type : microsoft.compute/virtualmachinescalesets
location : eastus
tags : @{resourceType=Service Fabric; clusterName=gov-art-int-nt-a}
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.Compute/virtualMachineScaleSets/nt
id : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
name : egtopic-1
type : microsoft.eventgrid/topics
location : westus2
tags :
+ResourceId : /subscriptions/1ef51df4-f8a9-4b69-9919-1ef51df4eff6/resourceGroups/Service-INT-a/providers/Microsoft.EventGrid/topics/egtopic-1
```
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
## OUTPUTS
-### Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse
+### Microsoft.Azure.Commands.ResourceGraph.Models.PSResourceGraphResponse`1[[System.Management.Automation.PSObject]]
## NOTES
diff --git a/tools/StaticAnalysis/Exceptions/Az.ResourceGraph/BreakingChangeIssues.csv b/tools/StaticAnalysis/Exceptions/Az.ResourceGraph/BreakingChangeIssues.csv
new file mode 100644
index 000000000000..ef3ddfe731ab
--- /dev/null
+++ b/tools/StaticAnalysis/Exceptions/Az.ResourceGraph/BreakingChangeIssues.csv
@@ -0,0 +1,2 @@
+"AssemblyFileName","ClassName","Target","Severity","ProblemId","Description","Remediation"
+"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'."