diff --git a/src/Beta/Users.User/Users.User/readme.md b/src/Beta/Users.User/Users.User/readme.md
index f83779b1fa9..761faec1931 100644
--- a/src/Beta/Users.User/Users.User/readme.md
+++ b/src/Beta/Users.User/Users.User/readme.md
@@ -34,6 +34,6 @@ input-file: $(spec-doc-repo)/$(title).yml
### Versioning
``` yaml
-module-version: 0.5.1
+module-version: 0.7.0
release-notes: See https://aka.ms/GraphPowerShell-Release.
```
diff --git a/src/readme.graph.md b/src/readme.graph.md
index 9a5451e343e..f8893b802a4 100644
--- a/src/readme.graph.md
+++ b/src/readme.graph.md
@@ -81,7 +81,9 @@ directive:
parameter-name: Top
set:
parameter-name: PageSize
- alias: Top
+ alias:
+ - Top
+ - Limit
- where:
parameter-name: Select
set:
@@ -378,7 +380,7 @@ directive:
}
return $;
}
-# Temporarily disable paging.
+# Add custom -All parameter to *_List cmdlets that support Odata next link.
- from: source-file-csharp
where: $
transform: >
@@ -388,7 +390,15 @@ directive:
} else {
let odataNextLinkRegex = /(^\s*)(if\s*\(\s*result.OdataNextLink\s*!=\s*null\s*\))/gmi
if($.match(odataNextLinkRegex)) {
- $ = $.replace(odataNextLinkRegex, '$1result.OdataNextLink = null;\n$1if (result.OdataNextLink != null)$1');
+ $ = $.replace(odataNextLinkRegex, '$1if (result.OdataNextLink != null && this.ShouldIteratePages(this.InvocationInformation.BoundParameters, result.Value.Length))\n$1');
+ let psBaseClassImplementationRegex = /(\s*:\s*)(global::System.Management.Automation.PSCmdlet)/gmi
+ $ = $.replace(psBaseClassImplementationRegex, '$1Microsoft.Graph.PowerShell.Cmdlets.Custom.ListCmdlet');
+
+ let beginProcessingRegex = /(^\s*)(protected\s*override\s*void\s*BeginProcessing\(\)\s*{)/gmi
+ $ = $.replace(beginProcessingRegex, '$1$2\n$1$1if (this.InvocationInformation.BoundParameters.ContainsKey("PageSize")){ InitializePaging(ref this.__invocationInfo, ref this._pageSize); }\n$1');
+
+ let odataNextLinkCallRegex = /(^\s*)(await\s*this\.Client\.UsersUserListUser_Call\(requestMessage\,\s*onOk\,\s*onDefault\,\s*this\,\s*Pipeline\)\;)/gmi
+ $ = $.replace(odataNextLinkCallRegex, '$1requestMessage.RequestUri = GetOverflowItemsNextLinkUri(requestMessage.RequestUri);\n$1$2');
}
return $;
}
diff --git a/tools/Custom/ListCmdlet.cs b/tools/Custom/ListCmdlet.cs
new file mode 100644
index 00000000000..2fd7cdd448c
--- /dev/null
+++ b/tools/Custom/ListCmdlet.cs
@@ -0,0 +1,118 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+namespace Microsoft.Graph.PowerShell.Cmdlets.Custom
+{
+
+ public partial class ListCmdlet : global::System.Management.Automation.PSCmdlet
+ {
+ /// Backing field for property.
+ private global::System.Management.Automation.SwitchParameter _all;
+
+ /// List All pages
+ [global::System.Management.Automation.Parameter(Mandatory = false, HelpMessage = "List all pages")]
+ [Microsoft.Graph.PowerShell.Runtime.Info(
+ Required = false,
+ ReadOnly = false,
+ Description = @"List all pages",
+ SerializedName = @"$all",
+ PossibleTypes = new[] { typeof(global::System.Management.Automation.SwitchParameter) })]
+ [global::Microsoft.Graph.PowerShell.Category(global::Microsoft.Graph.PowerShell.ParameterCategory.Runtime)]
+ public global::System.Management.Automation.SwitchParameter All { get => this._all; set => this._all = value; }
+
+ ///
+ /// Default number of items per page.
+ ///
+ internal const int DefaultPageSize = 100;
+
+ ///
+ /// Maximum number of items per page.
+ ///
+ internal const int MaxPageSize = 999;
+
+ ///
+ /// Original page size/top/limit passed to Cmdlet via parameter.
+ ///
+ internal int originalPageSize = 0;
+
+ ///
+ /// Total number of pages required to iterate page collections excluding overflow items.
+ ///
+ internal int requiredPages = 0;
+
+ ///
+ /// A count of iterated pages thus far.
+ ///
+ internal int iteratedPages = 0;
+
+ ///
+ /// Total number of overflow items, less than the maximum number of items in a page.
+ /// Modulus of original page size.
+ ///
+ internal int overflowItemsCount = 0;
+
+ ///
+ /// Total number of fetched items.
+ ///
+ internal int totalFetchedItems = 0;
+
+ ///
+ /// Initializes paging values.
+ ///
+ /// A reference to object.
+ /// A reference to page size parameter.
+ public void InitializePaging(ref global::System.Management.Automation.InvocationInfo invocationInfo, ref int PageSize)
+ {
+ if (PageSize > MaxPageSize)
+ {
+ invocationInfo.BoundParameters["All"] = true;
+ originalPageSize = PageSize;
+ requiredPages = PageSize / DefaultPageSize;
+ overflowItemsCount = PageSize % DefaultPageSize;
+ invocationInfo.BoundParameters["PageSize"] = DefaultPageSize;
+ PageSize = DefaultPageSize;
+ }
+ }
+
+ ///
+ /// Determines whether the cmdlet should follow the OData next link url.
+ ///
+ /// The bound parameters of the cmdlet.
+ /// Current page items count.
+ /// True if it can iterate pages; False if it can't.
+ public bool ShouldIteratePages(global::System.Collections.Generic.Dictionary boundParameters, int itemsCount)
+ {
+ iteratedPages++;
+ totalFetchedItems += itemsCount;
+ if ((boundParameters.ContainsKey("All") && !boundParameters.ContainsKey("PageSize")) ||
+ (boundParameters.ContainsKey("PageSize") && totalFetchedItems < originalPageSize))
+ return true;
+ else
+ return false;
+ }
+
+ ///
+ /// Gets an OData next link for the overflow items.
+ ///
+ /// The OData next link returned by the service.
+ /// An OData next link URI for the overflow items.
+ public global::System.Uri GetOverflowItemsNextLinkUri(global::System.Uri requestUri)
+ {
+ var nextLinkUri = new global::System.UriBuilder(requestUri);
+ if (requiredPages == iteratedPages && overflowItemsCount > 0)
+ {
+ if (nextLinkUri.Query.Contains("$top"))
+ {
+ global::System.Collections.Specialized.NameValueCollection queryString = global::System.Web.HttpUtility.ParseQueryString(nextLinkUri.Query);
+ queryString["$top"] = global::System.Uri.EscapeDataString(overflowItemsCount.ToString());
+ nextLinkUri.Query = queryString.ToString();
+ }
+ else
+ {
+ nextLinkUri.Query += $"$top=" + global::System.Uri.EscapeDataString(overflowItemsCount.ToString());
+ }
+ }
+ return nextLinkUri.Uri;
+ }
+ }
+}
\ No newline at end of file