I'm an IT Systems Engineer with a philosophy built around one principle: infrastructure should work for the business, not against it. After earning a degree in Network and Telecommunications Management and spending years in enterprise support environments, I took on the role of sole IT engineer for a mid-size distribution company — and built the entire stack from there.
What started as a traditional sysadmin role evolved into something much broader. When the business needed an ERP system, I didn't outsource the implementation — I designed it, configured it, and integrated it with a SQL Server backend myself. When workflows were manual and error-prone, I automated them. When the network needed a complete redesign, I rebuilt it from the ground up with proper segmentation and security policies.
Today I manage the full enterprise IT stack: hybrid cloud identity, Microsoft 365, ERP systems, network infrastructure, backup and disaster recovery, and endpoint security — all while continuously pushing toward an automation-first approach where repetitive work runs itself and engineering time goes toward what actually matters.
I hold a Bachelor of Science in Network and Telecommunications Management from Illinois State University, and I've deliberately built broad depth across systems, networking, cloud, and enterprise applications — because in a complex environment, problems never fit neatly into one category.
Lately I've been exploring AI and agentic workflows with genuine curiosity — both for personal productivity and for what they mean for enterprise IT automation. From using AI tools to accelerate scripting and troubleshooting to experimenting with agentic task automation, I'm actively learning where this technology fits and how to put it to work. I see AI as the next layer of the automation stack, and I intend to be ready.
Organized by domain, not alphabet. Depth where it matters.
Case studies from real enterprise environments. Problems identified. Solutions engineered. Results delivered.
The Challenge: The business needed a full ERP system to manage finance, inventory, and operations across the organization. The conventional path was expensive external consultants with ongoing dependency and cost.
My Approach: I self-implemented SAP Business One with a Microsoft SQL Server backend — handling system design, configuration, data migration, user training, and ongoing administration entirely in-house. Built advanced custom reporting using SQL queries and SAP Crystal Reports, developed automation workflows integrating the ERP with operational processes, and created integrations between SAP and external business systems.
The Challenge: Growing cloud adoption required a reliable, secure identity bridge between on-premises Active Directory and Microsoft 365 — with seamless user experience and enforced access controls.
My Approach: Designed and implemented Azure AD Connect with Microsoft Entra ID, configuring hybrid join, password hash sync, and conditional access policies. Integrated Exchange Online, Teams Voice, SharePoint Online, and Intune for unified M365 administration.
The Challenge: Finance, inventory, and operational workflows were manual and time-intensive. Reporting required significant human effort. Administrative tasks like user provisioning were repetitive and inconsistent.
My Approach: Built a suite of automation across three layers — PowerShell for administrative and system tasks, SQL stored procedures and SQL Server Agent jobs for database-driven workflows, and Power Automate for cross-system business processes. Created automated reporting delivered directly to stakeholders on schedule.
The Challenge: Legacy flat network architecture created security exposure and performance bottlenecks. No segmentation meant a single compromise could propagate laterally across all systems.
My Approach: Designed and implemented a complete network redesign: VLAN segmentation across all traffic types, SD-WAN deployment for WAN optimization and reliability, VPN architecture for secure remote access, and full firewall policy rebuild with explicit deny-by-default rules and logging.
The Challenge: Business continuity required a robust, tested backup and recovery strategy covering both on-premises and cloud workloads — with documented procedures and known recovery times.
My Approach: Designed a layered backup architecture using Azure Backup for cloud-native workloads and Microsoft Azure Backup Server (MABS) for on-premises systems. Documented recovery procedures, defined RTO/RPO targets, and established a regular recovery testing cadence.
PowerShell is a primary tool in my automation stack. These samples reflect the kind of work I build and maintain in enterprise environments.
# New Employee Onboarding Automation
# Creates AD account, syncs to Entra ID, assigns M365 license
function New-EmployeeOnboarding {
param(
[Parameter(Mandatory)] [string]$FirstName,
[Parameter(Mandatory)] [string]$LastName,
[Parameter(Mandatory)] [string]$Department,
[string]$Manager,
[string]$Title
)
$Username = "$($FirstName.Substring(0,1).ToLower())$($LastName.ToLower())"
$UPN = "$Username@company.com"
$TempPass = ConvertTo-SecureString "TempPass$(Get-Random -Max 9999)!" -AsPlainText -Force
# Create Active Directory user
$ADParams = @{
Name = "$FirstName $LastName"
GivenName = $FirstName
Surname = $LastName
SamAccountName = $Username
UserPrincipalName = $UPN
Department = $Department
Title = $Title
Manager = $Manager
AccountPassword = $TempPass
Enabled = $true
ChangePasswordAtLogon = $true
Path = "OU=$Department,OU=Users,DC=company,DC=local"
}
New-ADUser @ADParams
Write-Host "✓ AD account created: $Username" -ForegroundColor Green
# Wait for Azure AD Connect sync cycle
Write-Host "Waiting for Entra ID sync..." -ForegroundColor Cyan
Start-ADSyncSyncCycle -PolicyType Delta
Start-Sleep -Seconds 45
# Assign Microsoft 365 license via Graph API
Connect-MgGraph -Scopes "User.ReadWrite.All", "Organization.Read.All"
$LicenseSku = Get-MgSubscribedSku | Where-Object { $_.SkuPartNumber -eq "ENTERPRISEPREMIUM" }
Set-MgUserLicense -UserId $UPN `
-AddLicenses @{ SkuId = $LicenseSku.SkuId } `
-RemoveLicenses @()
Write-Host "✓ M365 license assigned to $UPN" -ForegroundColor Green
Write-Host "✓ Onboarding complete. Temp password requires reset at first login." -ForegroundColor Green
}
# SQL Server Nightly Health Check
# Checks backup recency, index fragmentation, and database size
# Emails formatted report to IT and management
$SQLServer = "SQL-SERVER-01"
$Databases = @("CompanyDB", "SAPB1DB", "ReportingDB")
$Recipients = @("it@company.com", "manager@company.com")
function Get-DatabaseHealth {
param([string]$Server, [string[]]$Databases)
$Report = @()
foreach ($DB in $Databases) {
$Query = @"
SELECT
DB_NAME() AS DatabaseName,
SUM(size * 8 / 1024) AS SizeMB,
(SELECT COUNT(*) FROM sys.indexes
WHERE INDEXPROPERTY(object_id, name, 'IndexFragmentation') > 30)
AS FragmentedIndexes,
(SELECT TOP 1 backup_finish_date
FROM msdb.dbo.backupset
WHERE database_name = DB_NAME()
ORDER BY backup_finish_date DESC) AS LastBackup
FROM sys.database_files
"@
$Result = Invoke-Sqlcmd -ServerInstance $Server -Database $DB -Query $Query
$HoursSinceBackup = ((Get-Date) - $Result.LastBackup).TotalHours
$Report += [PSCustomObject]@{
Database = $DB
SizeMB = $Result.SizeMB
FragmentedIndexes = $Result.FragmentedIndexes
LastBackup = $Result.LastBackup
BackupStatus = if ($HoursSinceBackup -lt 24) { "OK" } else { "STALE" }
}
}
return $Report
}
$HealthData = Get-DatabaseHealth -Server $SQLServer -Databases $Databases
$HTMLReport = $HealthData | ConvertTo-Html -Title "SQL Server Health — $(Get-Date -Format 'yyyy-MM-dd')"
Send-MailMessage `
-To $Recipients `
-Subject "SQL Health Report: $(Get-Date -Format 'yyyy-MM-dd')" `
-BodyAsHtml $HTMLReport `
-SmtpServer "smtp.company.com"
# Azure Backup Job Verification
# Checks for failed/warned jobs in the past 48 hours and sends alerts
# Runs nightly via scheduled task
Import-Module Az.RecoveryServices
$VaultName = "CompanyBackupVault"
$ResourceGroup = "Company-RG-Backup"
# Connect using managed identity in production environments
Connect-AzAccount -Identity
$Vault = Get-AzRecoveryServicesVault -Name $VaultName -ResourceGroupName $ResourceGroup
Set-AzRecoveryServicesVaultContext -Vault $Vault
# Pull jobs from the last 48 hours
$Jobs = Get-AzRecoveryServicesBackupJob -From (Get-Date).AddHours(-48) -VaultId $Vault.ID
$FailedJobs = $Jobs | Where-Object { $_.Status -eq "Failed" }
$WarningJobs = $Jobs | Where-Object { $_.Status -eq "CompletedWithWarnings" }
$SuccessJobs = $Jobs | Where-Object { $_.Status -eq "Completed" }
Write-Host "Backup Summary (last 48h):"
Write-Host " Successful : $($SuccessJobs.Count)"
Write-Host " Warnings : $($WarningJobs.Count)"
Write-Host " Failed : $($FailedJobs.Count)"
if ($FailedJobs.Count -gt 0) {
$AlertBody = "BACKUP ALERT — $($FailedJobs.Count) job(s) failed.`n`n"
$AlertBody += ($FailedJobs | Select-Object WorkloadName, Status, StartTime, ErrorDetails |
Format-Table -AutoSize | Out-String)
Send-MailMessage `
-To "it@company.com" `
-Subject "ALERT: Azure Backup Failure — $(Get-Date -Format 'yyyy-MM-dd')" `
-Body $AlertBody `
-SmtpServer "smtp.company.com"
Write-Warning "Backup failures detected. Alert sent."
}
if ($WarningJobs.Count -gt 0) {
Write-Warning "$($WarningJobs.Count) job(s) completed with warnings. Review in Azure portal."
}
Open to senior systems engineering, infrastructure leadership, and IT architecture opportunities.