STEPHEN THOMAS WHEELER
Tampa, FL | 954.612.5197 | swheeler@intrastart.com | LinkedIn Profile | Public Repos


Professional Summary

I am a hands-on software engineer and Azure solutions architect with deep expertise in designing and building cloud-based systems. I bring a strategic mindset to technical problem-solving and lead with a balance of innovation, precision, and mentorship. My leadership roles have involved system architecture, establishing development standards, code reviews, and fostering cross-functional team collaboration.

My technical focus spans Microsoft Azure, Microsoft Graph API, Apache Solr, and multi-cloud environments (Azure, AWS, GCP). I work extensively with modern DevOps pipelines (Azure DevOps CI/CD), AI/ML technologies (Azure Cognitive Services), and secure distributed computing. I’m fluent in C# and C++ and have experience across all .NET technologies, async programming, parallel processing, and micro-service architecture and relational and no-sql data base technologies.

I’m a continuous learner who values technical depth, collaborative engineering culture, and solving complex challenges. I thrive in senior technical roles where I can guide innovation while staying engaged in hands-on development.


Core Competencies

  • Programming Languages
    C#, C++, Python, Java, JavaScript, SQL
  • Cloud Platforms & DevOps
    Azure, AWS, GCP, Azure DevOps, CI/CD, ARM, CLI, DevOps
  • APIs & Integrations
    Restful services, Web API 2, WCF, Microsoft Graph API, oAuth2, ADFS, OKTA, Auth0
  • Search & AI Technologies
    Apache Solr, Elastic Search, Azure Cognitive Services, Spark, NLP, Big Data, Hadoop
  • Web & Front-End
    Node.js, React, Angular JS, jQuery, AJAX, JSON
  • Databases & Systems
    Azure/MS SQL, Oracle, DB2, SQLite, LDAP, Splunk, Zookeeper
  • Methodologies & Tools
    SOLID, OOD, SDLC, Agile, SCRUM, SaFe, Certified SCRUM Master

Domain Knowledge

  • Cloud Systems & Migration : Cloud architecture, migration strategies, security, and API integration in multi-cloud environments (Azure, AWS, GCP).
  • Financial Systems : Real-time trading, algorithmic trading systems, global banking systems.
  • AI & Blockchain : AI-driven solutions, machine learning, Azure Cognitive Services, blockchain technologies, and cryptocurrency applications.
  • Security & Compliance : Risk management, security best practices in cloud environments, and compliance standards.

 

Skill Set Matrix
Skill Name Years Experience Last Used
Certified Software Engineering / Development 20 2024
Certified Solutions Architecture (hands-on) 12 2024
Cloud Computing: Certified Azure Expert 13 2024
C#, C++, Java, Javascript, TSQL, YAML 22 2024
Razor; MVC; Blazor 22 2024
RDBMS: MSSQL; Azure SQLl TSQL; PSQL 9 2024
No SQL: Solr; Cosmos; Hadoop 9 2024
Javascript: JQuery; Chart JS; Angular; React 9 2024
.Net Core 9 2024
.Net Framework 12 2024
Micro-Services, Rest API’s 12 2024
Identity: Entra; OKTA; oAuth2; SAML 12 2024
Microsoft Graph API 8 2024
Plugins and Extensions 16 2024
CI/CD Azure DevOps 16 2024
AI, ML, NLP, ChatGPT 16 2024
Code Sample C# Azure Functional App to Get Entra Id Users and Groups using MS Graph API v5.x
Complete Code Sample on GitHub
You will need to setup a Functional App in Azure and register the app in Entra Id setting the permissions to Call the Graph API with User.Read and Groups.Read permissions. Then create an Azure KeyVault to store the secret Key.
  • Calls Microsoft Graph API v5.x
  • Azure Functional App in .Net Core V8
  • Multi-Tenant support
  • Async Methods to get Entra Id (AAD) User(s)
  • Async Methods to get Entra Id (AAD) Group(s)
  • Uses Azure Key Vault to secure Secrets
  • Uses Managed Identity

[Function("Groups")]
public async Task GetGroupsAsync([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
EntraGroups? entraGroups = null;

_logger.LogInformation("C# HTTP trigger function processed a request.");

var requestBody = await new StreamReader(req.Body).ReadToEndAsync();

var request = JsonConvert.DeserializeObject(requestBody);

var tenantUId = request?.TenantUId.ToString("D");

var clientId = Environment.GetEnvironmentVariable("ClientId");
var clientSecret = Environment.GetEnvironmentVariable("ClientSecret");

try
{
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

var clientSecretCredential = new ClientSecretCredential(
request?.TenantUId.ToString("D"), clientId, clientSecret, options);

var graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);

var groupList = new List();

var groupsResponse = await graphServiceClient
.Groups
.GetAsync(requestConfiguration => {
requestConfiguration.QueryParameters.Filter = $"groupTypes/any(c: c eq 'Unified')";
requestConfiguration.QueryParameters.Select = new string[] { "id", "displayName", "description", "Mail", "Members", "createdDateTime" }; requestConfiguration.QueryParameters.Top = 60;
requestConfiguration.Headers.Add("ConsistencyLevel", "eventual");
});
var grpIterator = PageIterator
.CreatePageIterator(graphServiceClient, groupsResponse, (group) => { groupList.Add(group); return true; });

await grpIterator.IterateAsync();

entraGroups = new EntraGroups();

foreach (var group in groupList)
{
var entraGroup = new EntraGroup
{
Id = new Guid(group.Id),
Name = group.DisplayName,
Description = group.Description,
Email = group.Mail
};

entraGroups.Items.Add(entraGroup);
}
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());

return new ObjectResult(new { statusCode = 500, Message = ex.Message });
}

return new OkObjectResult(entraGroups);
}