diff --git a/src/Cake.AzureDevOps/AzureDevOpsAliases.Projects.cs b/src/Cake.AzureDevOps/AzureDevOpsAliases.Projects.cs
new file mode 100644
index 0000000..95073c2
--- /dev/null
+++ b/src/Cake.AzureDevOps/AzureDevOpsAliases.Projects.cs
@@ -0,0 +1,49 @@
+namespace Cake.AzureDevOps
+{
+ using System.Collections.Generic;
+ using Cake.AzureDevOps.Collections;
+ using Cake.AzureDevOps.Projects;
+ using Cake.Core;
+ using Cake.Core.Annotations;
+
+ ///
+ /// Contains functionality related to Azure DevOps projects.
+ ///
+ public static partial class AzureDevOpsAliases
+ {
+ ///
+ /// Gets all projects or a collection.
+ ///
+ /// The context.
+ /// Settings for getting the projects.
+ ///
+ /// Get the projects associated with an Azure DevOps collection:
+ ///
+ ///
+ ///
+ ///
+ /// The projects or an empty list of projects if no projects were found for the .
+ [CakeMethodAlias]
+ [CakeAliasCategory("Azure Pipelines")]
+ [CakeNamespaceImport("Cake.AzureDevOps.Projects")]
+ [CakeNamespaceImport("Cake.AzureDevOps.Collections")]
+ public static IEnumerable AzureDevOpsProjects(
+ this ICakeContext context,
+ AzureDevOpsCollectionSettings settings)
+ {
+ context.NotNull(nameof(context));
+ settings.NotNull(nameof(settings));
+
+ return AzureDevOpsProjectsHelper.GetAzureDevOpsProjects(context.Log, settings);
+ }
+ }
+}
diff --git a/src/Cake.AzureDevOps/Collections/AzureDevOpsCollectionSettings.cs b/src/Cake.AzureDevOps/Collections/AzureDevOpsCollectionSettings.cs
new file mode 100644
index 0000000..b817106
--- /dev/null
+++ b/src/Cake.AzureDevOps/Collections/AzureDevOpsCollectionSettings.cs
@@ -0,0 +1,40 @@
+namespace Cake.AzureDevOps.Collections
+{
+ using Cake.AzureDevOps.Authentication;
+
+ ///
+ /// Settings for aliases handling collections.
+ ///
+ public class AzureDevOpsCollectionSettings : BaseAzureDevOpsCollectionSettings
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// based on the instance of a class.
+ ///
+ /// Settings containing the parameters.
+ public AzureDevOpsCollectionSettings(AzureDevOpsCollectionSettings settings)
+ : base(settings)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class using environment variables
+ /// as set by an Azure Pipelines build.
+ ///
+ /// Credentials to use to authenticate against Azure DevOps.
+ public AzureDevOpsCollectionSettings(IAzureDevOpsCredentials credentials)
+ : base(credentials)
+ {
+ }
+
+ ///
+ /// Constructs the settings object using the access token provided by Azure Pipelines.
+ ///
+ /// The instance of class.
+ public static AzureDevOpsCollectionSettings UsingAzurePipelinesOAuthToken()
+ {
+ var accessToken = EnvironmentVariableHelper.GetSystemAccessToken();
+ return new AzureDevOpsCollectionSettings(new AzureDevOpsOAuthCredentials(accessToken));
+ }
+ }
+}
diff --git a/src/Cake.AzureDevOps/IProjectClientFactory.cs b/src/Cake.AzureDevOps/IProjectClientFactory.cs
new file mode 100644
index 0000000..5525b14
--- /dev/null
+++ b/src/Cake.AzureDevOps/IProjectClientFactory.cs
@@ -0,0 +1,30 @@
+namespace Cake.AzureDevOps
+{
+ using System;
+ using Cake.AzureDevOps.Authentication;
+ using Microsoft.TeamFoundation.Core.WebApi;
+ using Microsoft.VisualStudio.Services.Identity;
+
+ ///
+ /// The interface for a Git client factory.
+ ///
+ internal interface IProjectClientFactory
+ {
+ ///
+ /// Creates the instance of the class.
+ ///
+ /// The URL of the Azure DevOps team project collection.
+ /// The credentials to connect to Azure DevOps.
+ /// The instance of class.
+ ProjectHttpClient CreateProjectClient(Uri collectionUrl, IAzureDevOpsCredentials credentials);
+
+ ///
+ /// Creates the instance of the class.
+ ///
+ /// The URL of the Azure DevOps team project collection.
+ /// The credentials to connect to Azure DevOps.
+ /// Returns identity which is authorized.
+ /// The instance of class.
+ ProjectHttpClient CreateProjectClient(Uri collectionUrl, IAzureDevOpsCredentials credentials, out Identity authorizedIdentity);
+ }
+}
diff --git a/src/Cake.AzureDevOps/ProjectClientFactory.cs b/src/Cake.AzureDevOps/ProjectClientFactory.cs
new file mode 100644
index 0000000..19e8c6d
--- /dev/null
+++ b/src/Cake.AzureDevOps/ProjectClientFactory.cs
@@ -0,0 +1,35 @@
+namespace Cake.AzureDevOps
+{
+ using System;
+ using Cake.AzureDevOps.Authentication;
+ using Microsoft.TeamFoundation.Core.WebApi;
+ using Microsoft.VisualStudio.Services.Identity;
+ using Microsoft.VisualStudio.Services.WebApi;
+
+ ///
+ internal class ProjectClientFactory : IProjectClientFactory
+ {
+ ///
+ public ProjectHttpClient CreateProjectClient(Uri collectionUrl, IAzureDevOpsCredentials credentials)
+ {
+ return this.CreateProjectClient(collectionUrl, credentials, out _);
+ }
+
+ ///
+ public ProjectHttpClient CreateProjectClient(Uri collectionUrl, IAzureDevOpsCredentials credentials, out Identity authorizedIdentity)
+ {
+ var connection =
+ new VssConnection(collectionUrl, credentials.ToVssCredentials());
+
+ authorizedIdentity = connection.AuthorizedIdentity;
+
+ var projectClient = connection.GetClient();
+ if (projectClient == null)
+ {
+ throw new AzureDevOpsException("Could not retrieve the ProjectHttpClient object");
+ }
+
+ return projectClient;
+ }
+ }
+}
diff --git a/src/Cake.AzureDevOps/Projects/AzureDevOpsProject.cs b/src/Cake.AzureDevOps/Projects/AzureDevOpsProject.cs
new file mode 100644
index 0000000..6f007f5
--- /dev/null
+++ b/src/Cake.AzureDevOps/Projects/AzureDevOpsProject.cs
@@ -0,0 +1,20 @@
+namespace Cake.AzureDevOps.Projects
+{
+ using System;
+
+ ///
+ /// Class for writing issues to Azure DevOps pull requests.
+ ///
+ public sealed class AzureDevOpsProject
+ {
+ ///
+ /// Gets the project identifier.
+ ///
+ public Guid Id { get; internal set; }
+
+ ///
+ /// Gets the project name.
+ ///
+ public string Name { get; internal set; }
+ }
+}
diff --git a/src/Cake.AzureDevOps/Projects/AzureDevOpsProjectsHelper.cs b/src/Cake.AzureDevOps/Projects/AzureDevOpsProjectsHelper.cs
new file mode 100644
index 0000000..615099f
--- /dev/null
+++ b/src/Cake.AzureDevOps/Projects/AzureDevOpsProjectsHelper.cs
@@ -0,0 +1,41 @@
+namespace Cake.AzureDevOps.Projects
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using Cake.AzureDevOps.Collections;
+ using Cake.Core.Diagnostics;
+
+ ///
+ /// Provides functions for AzureDevOps projects.
+ ///
+ internal static class AzureDevOpsProjectsHelper
+ {
+ ///
+ /// Gets the projects for the parameter .
+ ///
+ /// The Cake log context.
+ /// Settings for getting the collection.
+ /// The projects or an empty list of projects if no projects were found for the .
+ internal static IEnumerable GetAzureDevOpsProjects(
+ ICakeLog log,
+ AzureDevOpsCollectionSettings settings)
+ {
+ log.NotNull(nameof(log));
+ settings.NotNull(nameof(settings));
+
+ using (var projectHttpClient = new ProjectClientFactory().CreateProjectClient(settings.CollectionUrl, settings.Credentials))
+ {
+ var projects =
+ projectHttpClient
+ .GetProjects()
+ .ConfigureAwait(false)
+ .GetAwaiter()
+ .GetResult()
+ .Select(x => x.ToAzureDevOpsProject())
+ .ToList();
+
+ return projects;
+ }
+ }
+ }
+}
diff --git a/src/Cake.AzureDevOps/Projects/TeamProjectReferenceExtensions.cs b/src/Cake.AzureDevOps/Projects/TeamProjectReferenceExtensions.cs
new file mode 100644
index 0000000..8fc9e96
--- /dev/null
+++ b/src/Cake.AzureDevOps/Projects/TeamProjectReferenceExtensions.cs
@@ -0,0 +1,27 @@
+namespace Cake.AzureDevOps.Projects
+{
+ using Microsoft.TeamFoundation.Core.WebApi;
+
+ ///
+ /// Extensions for the class.
+ ///
+ internal static class TeamProjectReferenceExtensions
+ {
+ ///
+ /// Converts a to an .
+ ///
+ /// Team project to convert.
+ /// Converted team project.
+ public static AzureDevOpsProject ToAzureDevOpsProject(this TeamProjectReference teamProjectReference)
+ {
+ teamProjectReference.NotNull(nameof(teamProjectReference));
+
+ return
+ new AzureDevOpsProject
+ {
+ Id = teamProjectReference.Id,
+ Name = teamProjectReference.Name,
+ };
+ }
+ }
+}