Needed a quick “where did this user sign in from?” report without swapping modules. I used AzureADPreview to export a clean CSV (timestamp, IP, country/state/city, app, client, result). All identifiers below are redacted; mailbox shown as [email protected].
Intro
Security asked for a last-30-days sign-in report. I didn’t want to migrate the host that already had AzureADPreview, so I stayed on that and exported the fields they care about. Notes are redacted and portable.
Notes from {Speaker}
Context: Windows PowerShell 5.x (STA) + AzureADPreview.
Avoided Microsoft Graph SDK on this box.
Output: CSV with location + app/client details.
Perspective (direct quotes)
“Use Windows PowerShell (not PS7) so the AzureAD auth control behaves.” “If you change the date range, re-run the query—don’t reuse the old $logs.”
Practice (today, not someday)
Use this redacted snippet; replace only the UPN line if needed.
Sticking with AzureADPreview is fine when you only need sign-in logs—just remember: PowerShell 5.x, re-query after changing dates, and export only the fields the requester needs.
Pocket I’m Keeping
“Query fresh, then shape.” Most delays come from reusing an old $logs object after changing the date window.
Exchange Online sometimes reports mailbox sizes with “Unlimited” wrappers that break simple math. Today I built a one-liner-friendly PowerShell snippet that returns Used GB, Quota GB, and Available GB—even when EXO wraps values in Unlimited<T>.
Intro
I needed the available mailbox size for [mailbox]@[domain] without exposing tenant internals. The usual TotalItemSize parsing failed because EXO returned Unlimited<ByteQuantifiedSize>. Here’s the redacted approach that works reliably and falls back cleanly.
Notes from {Speaker}
Context: Exchange Online + PowerShell; target was [mailbox]@[domain].
Constraint: TotalItemSize and ProhibitSendQuota show Unlimited wrappers or localized strings.
Goal: Get UsedGB / QuotaGB / AvailableGB with no tenant secrets.
Perspective (direct quotes)
“If it’s Unlimited<T>, ask for .Value—and always guard with IsUnlimited.” “When objects don’t expose bytes, regex the (123,456 bytes) pattern as a fallback.”
Practice (today, not someday)
Use this redacted snippet. It works with Get-EXO* and falls back to classic cmdlets:
EXO’s objects are powerful but quirky. Guarding for IsUnlimited, using .Value.ToBytes(), and keeping a regex fallback turns a flaky one-off into a repeatable tool.
Pocket I’m Keeping
“Parse what’s there, not what you expect.” When APIs return wrapped or localized strings, a small fallback (regex for (#### bytes)) saves the day.
What I Hear Now (direct quotes)
“Measure in bytes, report in GB.” “Handle Unlimited first, then do math.” “One clean object out—every time.”
When the upgrade sits at 99%… don’t panic. Go offline and run the ISO upgrade the smart way
Windows 10 reaches end of life on Oct 5, 2025. After that, it won’t get security updates. If you stay on Win10, your machine is a sitting duck for malware and attackers. Don’t procrastinate.
If Windows Update keeps failing—or hangs forever at 99%—use this clean, offline upgrade that skips the flaky “checking for updates” step.
Important: The most common blockers are the CPU and motherboard (TPM 2.0, UEFI/Secure Boot). If your device doesn’t meet Windows 11 requirements, it’s unsupported after Oct 5, 2025. Treat that Windows 10 PC as unsafe for internet use—either upgrade/replace the hardware, reassign it to offline tasks, or retire it.
2) Prep (5–10 minutes)
Unplug non-essential USB devices (drives, printers, docks).
Ensure ≥30 GB free on C:.
Suspend BitLocker (if enabled): Control Panel → BitLocker → Suspend.
When you need to quickly spin up a test or lab machine, cloning an existing VM can save hours compared to building from scratch. VMware PowerCLI brings the full power of vSphere management into PowerShell. Here’s a simple walkthrough.
Pick the source VM, target VM names, host, and datastore. Example:
# Define source VM
$sourceVM = "Base-Win10-VM"
# Clone to new VM
New-VM -Name "Test-VM01" -VM $sourceVM `
-VMHost (Get-VMHost -Name <target-host>) `
-Datastore (Get-Datastore -Name <datastore-name>) `
-Location (Get-Folder -Name "VMs")
-VM points to the existing machine you’re cloning.
-VMHost pins the new VM to a specific ESXi host.
-Datastore chooses where to store the VM’s disks.
-Location defines the vCenter folder for organization.
Step 4 — Power On the New VM
Start-VM -VM "Test-VM01"
Final Reflection
PowerCLI makes cloning fast, repeatable, and scriptable. Instead of clicking through vSphere UI screens, you can prepare test VMs with a single command.
Excerpt Our all-hands list rejected internal senders after we allowed two external addresses. Here’s what happened, how to fix it cleanly in Exchange Online, and a PowerShell snippet you can reuse.
Intro Two days ago, I could email everyone@[redacted].com just fine. Today, my message bounced: “this group only accepts messages from people in its organization or on its allowed senders list.” We’d recently added two partner addresses (s@[partner].com, j@[partner].com) so they could email the DL. That change flipped the DL into strict allow-list mode—blocking even internal senders who weren’t explicitly listed. Here’s the minimal, durable fix.
Straight line (what happened) • Symptom: NDR when sending to everyone@[redacted].com from an internal account. • State check showed: – RequireSenderAuthenticationEnabled: False – AcceptMessagesOnlyFromSendersOrMembers: {} (and earlier, it contained only the two partner GUIDs). • Root cause: Delivery management was saved in “only these senders” mode; membership/ownership doesn’t matter in that state. • Goal: Let all internal, authenticated users send; allow only specific externals; block the rest.
Fix (clean model)
Let internal, authenticated users send to the DL (no hard allow-list on the group).
Enforce external restrictions with a transport rule that allows only the partner exceptions.
Commands (PowerShell — Exchange Online)
Connect
Connect-ExchangeOnline -ShowBanner:$false
Allow internal, authenticated senders (clear hard allow-list)
# add another partner
Set-TransportRule "Block external to Everyone (except allow-list)" `
-ExceptIfFrom @{Add="newuser@[partner].com"}
# remove a partner
Set-TransportRule "Block external to Everyone (except allow-list)" `
-ExceptIfFrom @{Remove="j@[partner].com"}
Smoke tests • Internal sender → everyone@[redacted].com: delivers. • External sender (not on list): NDR with “External senders are not allowed…” • Allowed partner (s@[partner].com or j@[partner].com): delivers.
Why not leave the DL in allow-list mode? Because it’s brittle. Every internal sender must be explicitly added, which guarantees future bounces and admin toil. Using RequireSenderAuthenticationEnabled for internal mail + a transport rule for externals gives you clarity and control.
Final reflection Small toggles can have outsized effects. DL delivery settings look simple, but one checkbox can silently change who’s “allowed.” The durable pattern is: authenticate inside, whitelist outside, and verify with a quick trace.
Pocket I’m keeping • Always snapshot DL settings before/after a change. • Prefer transport rules for external policy; don’t hard-gate internals via allow-lists. • Add a ready-to-run “add/remove external exception” snippet to the runbook.
What I hear now Clarity beats cleverness. Make the rule obvious enough that the next admin can read it and know exactly who can send and why.
Excerpt Quick, repeatable way to see CPU/RAM/vSAN headroom across hosts and choose where to place the next VM. Today it pointed us to vsan2.
Intro Before cloning a new Windows VM, I ran a fast PowerCLI sweep across three vSAN hosts to compare free CPU, free memory, and vSAN free space. All three had identical vSAN capacity; vsan2 had the most free RAM, so that’s the landing spot.
Straight line (what I did) • Pulled CPU and memory usage per host (MHz/MB) and calculated free. • Queried each host’s vSAN datastore(s) and summed free/total GB. • Printed a compact table to compare vsan1/2/3 at a glance. • Chose the host with the highest Mem_Free_GB (tie-break on vSAN free).
Result today • vsan2 showed the most free RAM, with CPU headroom similar across all three and identical vSAN free space. • Suggested placement: vsan2.
Pocket I’m keeping • Check host headroom before every clone—30 seconds now saves hours later. • Prefer RAM headroom for Windows VDI/worker VMs; CPU is usually similar across nodes. • Keep a one-liner that prints the table and the suggested host.
What I hear now Clone to vsan2, power up, then let DRS/vMotion rebalance after the build window. Repeat this check whenever adding workloads or after maintenance.
When a partner emailed our all-hands list, they got an NDR: “the group only accepts messages from people in its organization or on its allowed senders list… sender not allowed.”
We’d solved this once before and didn’t capture the steps. This time we did.
the group required authenticated (internal) senders only, and
the external wasn’t on the group’s allowed-senders list
gotcha we hit: New-MailContact failed with ProxyAddressExists — an existing MailUser already owned the external SMTP, so we reused it instead of creating a new contact
Straight line (what fixed it)
identify group by SMTP and check whether it’s a DL or a Microsoft 365 Group
locate the external as an existing MailContact/MailUser (include soft-deleted objects)
add that object to the group’s AcceptMessagesOnlyFromSendersOrMembers list
allow the group to accept external senders (keeps the allow-list in effect)
test and confirm with Message trace
Reusable runbook (PowerShell, redacted)
# 0) Connect
Connect-ExchangeOnline
# 1) Variables (edit these)
$GroupSmtp = "all@[corp-redacted].com"
$ExternalAddresses = @("firstname.lastname@[partner-redacted].com")
# 2) Resolve the group (works for DL or M365 Group)
$grp = Get-EXORecipient -Filter "PrimarySmtpAddress -eq '$GroupSmtp'"
$grp | fl Name,RecipientTypeDetails,PrimarySmtpAddress,Identity,ExternalDirectoryObjectId
# 3) Ensure each external exists as a recipient we can allow (MailContact/MailUser).
# If already present (or soft-deleted), reuse it.
$recips = @()
foreach ($addr in $ExternalAddresses) {
$r = Get-EXORecipient -ResultSize Unlimited -IncludeSoftDeletedRecipients `
-Filter "PrimarySmtpAddress -eq '$addr'"
if (-not $r) {
try { New-MailContact -Name $addr -ExternalEmailAddress $addr | Out-Null
$r = Get-EXORecipient -Filter "PrimarySmtpAddress -eq '$addr'" }
catch { Write-Host "Contact already exists somewhere: $addr" }
}
$recips += $r
}
$recips | ft Name,RecipientTypeDetails,PrimarySmtpAddress -AutoSize
# 4) Add externals to allow-list AND allow external senders
if ($grp.RecipientTypeDetails -eq "GroupMailbox") {
# Microsoft 365 Group (Unified Group)
foreach ($r in $recips) {
Set-UnifiedGroup -Identity $grp.ExternalDirectoryObjectId `
-AcceptMessagesOnlyFromSendersOrMembers @{Add=$r.Identity}
}
Set-UnifiedGroup -Identity $grp.ExternalDirectoryObjectId -AllowExternalSenders:$true
Get-UnifiedGroup -Identity $grp.ExternalDirectoryObjectId |
fl DisplayName,PrimarySmtpAddress,AllowExternalSenders,AcceptMessagesOnlyFromSendersOrMembers
} else {
# Distribution Group / Mail-enabled Security Group
foreach ($r in $recips) {
Set-DistributionGroup -Identity $grp.Identity `
-AcceptMessagesOnlyFromSendersOrMembers @{Add=$r.Identity}
}
Set-DistributionGroup -Identity $grp.Identity -RequireSenderAuthenticationEnabled:$false
Get-DistributionGroup -Identity $grp.Identity |
fl DisplayName,PrimarySmtpAddress,RequireSenderAuthenticationEnabled,AcceptMessagesOnlyFromSendersOrMembers
}
# 5) Message trace (adjust window)
Get-MessageTrace -SenderAddress $ExternalAddresses[0] -RecipientAddress $GroupSmtp `
-StartDate (Get-Date).AddHours(-2) -EndDate (Get-Date) |
ft Received,Status,RecipientAddress,MessageId
Common pitfalls we saw (and how we handled them)
ProxyAddressExists on New-MailContact → an existing MailUser/Contact already holds that SMTP; reuse it (or permanently remove the soft-deleted recipient first).
group can’t be found by display name → target by SMTP with Get-EXORecipient -Filter "PrimarySmtpAddress -eq '...'".
delivery still blocked after allow-list → the DL still required authenticated senders; set RequireSenderAuthenticationEnabled:$false (DL) or AllowExternalSenders:$true (M365 Group).
Click-path (EAC, if you don’t want PowerShell)
Recipients → Contacts → add/find the partner’s contact
Recipients → Groups → open the group → Delivery management → “Accept messages from” → add the contact
For DLs: turn off “Require sender authentication”
For M365 Groups: enable “Allow external senders”
Prevention / hygiene
keep an “Authorized External Senders — all” mail-enabled security group; allow that group on the DL/M365 Group, then just add/remove partner contacts over time
document the NDR verbatim and the message trace ID when you close an incident
Redaction note
All addresses and names are redacted. Replace with your real SMTPs when running the script.
PIMCO (Newport Beach HQ, CA) 🌍 — Global financial services supporting regions in NA, EMEA, APAC. Church (Riverton Office Building, UT) ⛪ — Worldwide infrastructure with 200k employees and over 80k missionaries. Monster Energy (Corona HQ, CA) ⚡ — Global enterprise IT operations across NA, EMEA, APAC. City National Bank (Downtown LA, CA) 🏙️ — U.S. banking systems at scale.
Every IT career tells a story, and mine has moved through three different scales of impact:
Company-Level Foundations → At PayForward, I migrated an entire OnPrem environment into AWS. That meant setting up VPCs, building HA Exchange clusters with load balancers, and proving the power of cloud for a fast-moving startup.
Regional / Global Scale → At Monster Energy and PIMCO, the work stretched across North America, EMEA, and APAC. The systems never slept. VMware clusters and M365 tenants had to function as one, even though users were scattered across time zones and continents.
Worldwide Reach → At the Church, the scale expanded beyond regions. Over 200,000 employees and over 80,000 missionaries, connected by systems that had to reach every corner of the globe, demanded both technical precision and spiritual responsibility.
This journey shows that the “cloud above us” isn’t just AWS, Azure, or GCP — it’s the ability to design, secure, and sustain systems at every possible scale.
A colleague once told me: “Automate, or eliminate.” In IT, that isn’t just a clever saying — it’s survival. At the scale of hundreds or even thousands of VMs, EC2 instances, or mailboxes, doing things manually is not just unrealistic — it’s risky. What automation can finish in under 10 minutes might take days or weeks by hand, and even then would be prone to errors.
That’s why Python, PowerShell, Bash, and automation frameworks became part of my daily toolkit. Not to flaunt, but because without automation, no single engineer could handle the demands of environments as large as PIMCO, Monster Energy, or the Church.
Snippet 1: AWS (My PayForward Days)
import boto3
# Connect to AWS S3
s3 = boto3.client('s3')
# List buckets
buckets = s3.list_buckets()
print("Your AWS buckets:")
for bucket in buckets['Buckets']:
print(f" {bucket['Name']}")
From racks of servers to a few lines of Python—that’s the power of AWS.
Snippet 2: PowerShell + Azure (My Church Years, CNB)
One line, and you can see every Azure resource group spread across the world. A task that once required data center visits and clipboards is now just a command away.
Snippet 3: PHP + GCP (Expanding Horizons)
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFilePath' => 'my-service-account.json'
]);
$buckets = $storage->buckets();
foreach ($buckets as $bucket) {
echo $bucket->name() . PHP_EOL;
}
# Connect to vCenter and list VMs across data centers
Connect-VIServer -Server vcenter.global.company.com -User admin -Password pass
Get-VM | Select Name, PowerState, VMHost, Folder
# Quick check of licensed users in M365 (global tenants)
Connect-MgGraph -Scopes "User.Read.All"
Get-MgUser -All -Property DisplayName, UserPrincipalName, UsageLocation |
Group-Object UsageLocation |
Select Name, Count
One script, and suddenly you’re seeing footprints of users spread across the globe — NA, EMEA, APAC, or even worldwide. That’s the reality of modern IT infrastructure.
The “cloud above us” is both a literal technology — AWS, Azure, and GCP that I’ve worked across — and a metaphor. It represents resilience, scalability, and unseen support. Just as automation carries workloads we could never handle by hand, life has storms we cannot carry alone.
From startups making their first move to the cloud, to global financial institutions, to worldwide organizations with hundreds of thousands of users, the lesson is the same: we are not meant to fight every battle manually.
We are given tools, teammates, and even unseen strength from above to keep moving forward. The same way a script can manage thousands of servers or accounts without error, trust and preparation help us navigate the storms of life with less fear.
☁️ Above every storm, there’s always a cloud carrying potential. And above that cloud, always light waiting to break through.
Before my cloud journey, I also spent nine years in forensic IT supporting law enforcement — a grounding reminder that technology isn’t only about systems and scale, but about accountability and truth.
Introduction: In enterprise environments, automation is only as secure as the credentials it uses. Hardcoding passwords into scripts is a security disaster waiting to happen. Enter PowerShell SecretManagement — a cross-platform module that allows IT professionals to store, retrieve, and manage credentials securely while keeping scripts clean, compliant, and automation-ready.
Description & Guide:
What is SecretManagement? The SecretManagement module provides a unified way to work with secrets across different vaults like Windows Credential Manager, Azure Key Vault, KeePass, or HashiCorp Vault — without locking you into a single storage provider.
Works seamlessly with CI/CD pipelines and scheduled tasks
Conclusion: Security and automation don’t have to be enemies. With PowerShell SecretManagement, you can protect sensitive credentials without sacrificing automation speed or flexibility. For IT pros managing hybrid environments, this module is a must-have in your PowerShell toolbox.
If you’d like to go beyond this post and see what Microsoft officially recommends, here are my go-to resources:
Introduction The AzureAD PowerShell module has served IT administrators for years, but it’s now officially deprecated in favor of the Microsoft Graph PowerShell SDK. While the change may feel like another “cloud shuffle,” migrating your scripts is not just a compliance move — it’s your ticket to a more powerful, secure, and future-proof automation toolkit. In this post, I’ll walk you through the essentials of converting your Azure AD scripts to Microsoft Graph, with clear side-by-side examples.
Why Migrate?
Future Support: Microsoft Graph is actively developed; AzureAD is on life support.
Unified Endpoint: Graph covers Azure AD, Intune, Exchange Online, Teams, and more in one API.
Security: Better authentication methods, including secure app registrations and least-privilege scopes.
Step 1 – Install Microsoft Graph PowerShell
# Install the module
Install-Module Microsoft.Graph -Scope CurrentUser
# Update if already installed
Update-Module Microsoft.Graph
# Connect with interactive sign-in
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"
# Confirm connection
Get-MgContext
Only request the scopes you actually need — this aligns with least privilege best practices.
Step 4 – Testing and Verification Before replacing scripts in production, run them in a test tenant or a non-production environment. Compare outputs from AzureAD and Graph to ensure parity.
Conclusion Migrating from AzureAD to Microsoft Graph PowerShell is more than just a rewrite — it’s a forward-looking investment. Once you adapt, you’ll unlock richer APIs, cross-service automation, and security benefits that AzureAD simply can’t match. My advice? Start small: pick one script, convert it, and test until you’re confident. Once you see the gains, the rest will follow naturally.
For official guidance and best practices from Microsoft, check out these resources:
Minutes before boarding at Salt Lake City International Airport, I received an urgent text about a disabled Azure AD account. I opened my laptop, tethered to my phone’s hotspot, connected to Cisco VPN, and got to work—resolving the issue securely without relying on public Wi-Fi
Introduction: Last Friday, just as I was getting ready to board my flight to JFK from the Salt Lake City airport, I received a message from an end user:
“I think I’m blocked. I can’t access Outlook, Teams, or OneDrive.”
Time was limited, and I was already seated at the gate with my laptop ready. Instead of panicking, I tethered through my phone’s personal hotspot and launched Cisco AnyConnect VPN. I deliberately avoided the airport’s public Wi-Fi to reduce the risk of a security breach.
Once I authenticated and connected securely, I logged into Azure. I discovered that the user’s account in portal.azure.com was disabled. Fortunately, there are two ways to quickly resolve this kind of issue:
✅ Method 1: PowerShell (Quickest & Most Efficient)
If you have the AzureAD or Microsoft Graph PowerShell module installed and proper permissions, this method is the fastest.
Step-by-step using Microsoft Graph PowerShell:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "User.ReadWrite.All"
# Re-enable the disabled account
Update-MgUser -UserId [email protected] -AccountEnabled $true
Note: Replace [email protected] with the actual UPN or Object ID of the affected user.
Advantages:
Fast (under 30 seconds)
No GUI needed
Can be scripted for multiple accounts
🧭 Method 2: Azure Portal (GUI Approach)
If you’re not ready to run PowerShell or don’t have the module available, the Azure Portal offers a visual way to fix it.
Both approaches—PowerShell and the Azure portal—get the job done. However, for IT professionals constantly on the move, PowerShell is king. It’s fast, efficient, and doesn’t rely on a graphical interface.
That said, having the flexibility to switch between GUI and scripting tools is essential. Some situations demand precision and speed; others might call for a visual confirmation or audit trail.
In the end, what matters most is being prepared. Whether you’re at your desk or at an airport gate, the ability to jump in and resolve an issue on the fly is what defines a reliable IT Engineer.
Intro: When internal emails from trusted coworkers suddenly stop showing up in your focused inbox or fail to trigger your Outlook rules, it’s easy to miss critical messages. In my case, one sender was previously blocked due to a spoofing incident, and although removed from the block list, her messages were still bypassing my folder rules—buried in the inbox. Message Trace confirmed the emails were delivered, but not filtered correctly. Here’s how I resolved the issue using PowerShell.
🔍 Problem Recap:
Despite the sender being trusted and allowed, her emails:
Skipped my Outlook inbox rules
Did not show up in Focused Inbox or designated folders
Were confirmed delivered via Message Trace
Were previously on the Blocked Sender List, but later removed
The Exchange Admin Center (EAC) didn’t offer the flexibility I needed to create an accurate spam bypass rule. So I switched to PowerShell.
🛠️ Solution: Create a Transport Rule via PowerShell
Instead of struggling with the limited dropdowns in the modern Exchange portal, I used the New-TransportRule cmdlet to create a spam filter bypass rule in just a few lines.
Conclusion: PowerShell remains the most powerful tool in any IT administrator’s arsenal—especially when the GUI can’t keep up. If you ever run into stubborn mail delivery or spam issues, consider creating targeted transport rules using PowerShell. It’s fast, clean, and gets the job done without frustration.
Confidence is earned — often forged in quiet moments when no one’s watching. Often, it’s forged in quiet moments when no one’s watching. Whether I’m at a blank PowerShell console or gripping a loaded barbell, the principle is the same: discipline, consistency, no shortcuts.
I’ve Always Been an ABC Person
I’ve always lived by three words: Always Be Curious.
That curiosity pulled me into IT. I lacked credentials, but I had grit and a drive to learn. I’ve never believed in shortcuts — not in spiritual growth, troubleshooting IIS, or transforming your body. Temporary fixes cover symptoms — but they rarely solve the root cause.
You don’t fix problems with assumptions, Google, and a quick prayer. You fix them with logs, tools, and patience. That’s what I’ve learned — the hard way — through years of trial, error, and persistence.
Why I Don’t Believe in Band-Aid Fixes
Quick fixes fade fast. They treat symptoms, not root problems. Take IIS, for example — a broken SSL binding or 503 error might vanish temporarily, but it usually comes back with greater risk.
That’s why I value discipline over speed. Precision over panic.
It’s the same principle my son applies as he preps for his first fitness competition. He doesn’t rely on shortcuts or crash diets. And definitely no “quick fixes” to look lean. Just clean eating, consistent training, and unwavering focus — day in and day out.
Watching him chase excellence reminds me of my early days — hungry, overlooked, and determined to make noise through results, not volume.
I didn’t wait for permission—I made my own path. I spoke up when others stayed silent, dove into neglected technologies…, and taught myself to harden and scale IIS in real-world, high-pressure environments. I wasn’t the loudest voice in the room, but I became the go-to problem solver—delivering solutions that worked the first time.
Triple D: Discipline. Dedication. Determination.
Tonight’s fuel: Baked Atlantic salmon with lemon, garlic, and power greens — topped with walnuts and 42g of clean protein. Discipline doesn’t stop at the keyboard — it continues at the dinner table.
Confidence isn’t found. It’s forged — through repetition, patience, and precision. Knowledge doesn’t come overnight. Much like getting fit, it takes what I call the Triple D: Discipline. Dedication. Determination.
Tonight’s early dinner? Fresh Atlantic salmon baked with lemon, garlic, and a bed of power greens. To boost nutrients, I topped it with walnuts and washed it down with 42g of Fairlife protein. I eat twice a day — every bite calculated, nutrient-packed, and designed for peak performance..
As for training, I’m in the zone six days a week — no shortcuts. Mostly bodyweight: push-ups, sit-ups, glute bridges, crab walks, planks, and shadow boxing. I train with intensity — until the burn says I’m done..
That’s how I’ve kept my edge for decades — by showing up, sweating, and sticking to the plan.
You train your body the way you train your mind. Log files are your feedback loop. Errors are your instructors. Study. Adapt. Try again.
That mindset shapes how I approach IT and life.
Bruce Lee Said It Best
“If you always put limits on everything you do — physical or anything else — it will spread into your work and into your life. There are no limits. There are only plateaus, and you must not stay there, you must go beyond them.” — Bruce Lee
I carry that with me daily. In both IT and fitness, mastery is a moving target — the moment you think you’ve arrived, growth demands a new challenge.
My Son’s Grit, My Quiet Pride
24 days out from competition.
“Starvation is at its highest for me… it feels like I’m crawling my way to survive all day long. This is the toughest sport I’ve ever experienced.”
Those are the words my son texted me as he prepares for his upcoming debut at TheFitExpo in Anaheim on August 2, 2025.
His commitment to clean eating, intense workouts, and honest prep — no shortcuts — mirrors the way I built my IT career: with sweat equity.
He used to dominate dance stages as a four-time All-Male hip-hop champion with West Covina High School. After college, he became a CNA and now works as a gym personal trainer — turning his passion for fitness into purpose. He’s carrying the torch of discipline — and I couldn’t be prouder.
From IIS to Iron: A Shared DNA
Take IIS — often dismissed as legacy tech, yet it powers critical internal systems beneath the buzzwords. But the reality is, it still powers critical internal applications..
When it breaks — when HTTP 500 errors fill your logs — assumptions won’t fix it. First, trace the issue. Dig through the logs. Slow down. Understand the root cause — then take action.
That’s the same mental muscle my son flexes in the gym. He logs his intake. Monitors results. Makes adjustments.
We train differently — I with bodyweight and discipline, he with prep meals and physique goals. The goals differ — but the grit is the same.
Here’s a script I wrote to search the most recent IIS log file for errors — the same kind of tool I use to avoid assumptions and find the real issue:
🧰 PowerShell Script: Digging Through IIS Logs
# Find the latest IIS log and search for error codes
$LogPath = "C:\inetpub\logs\LogFiles\W3SVC1"
$LatestLog = Get-ChildItem -Path $LogPath -Filter *.log | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Select-String -Path $LatestLog.FullName -Pattern " 500 " | Select-Object LineNumber, Line
If it’s worth fixing, it’s worth fixing the right way.
Conclusion: Carry On
This week’s Church hymn, “Carry On,” stirred something quiet in me — It reminded me that sometimes, the holiest thing we can do is simply hold our ground. It reminded me:
It reminded me:
“Firm as the mountains around us, Stalwart and brave we stand…”
We don’t walk this path alone. Others cleared the way — now it’s our turn to keep going.
This isn’t about spotlighting effort. It’s for the ones working in silence. In server rooms. In waiting rooms. In small spaces where no one claps.
The message doesn’t seek attention — it invites action: carry on.
They say when you see a man on top of the mountain, he didn’t fall there.
He planned the climb, stumbled on jagged trails, and kept going even when the sky turned gray.
This post isn’t just about photography, or starting a new role, or PowerShell scripts. It’s about finding your footing again when life shakes your routine—whether you’re debugging a script, chasing stars at 2AM, or collecting a laptop that brings back a hundred memories.
You’ll find stories about IT challenges, career shifts, Milky Way photography, emotional storms—and most of all, how to rise above the blues when everything feels heavy.
Carrying the gear, chasing the stars—because purpose isn’t found at the summit, it’s carried every step.
⛰️ New Job, New Mountain
They say starting a new job is like standing at the foot of a mountain. The view is exciting—but the climb? Uncertain.
No one really tells you what it feels like to start over. You’re learning people, process, and pace all at once. Even if you’re an expert, you’re blind on day one. And if you’re in IT, like me, the terrain can feel like a minefield.
Pros:
A fresh start
The chance to sharpen or add new skills
A clean slate to prove your value again
Cons:
Culture shock
Pressure to perform quickly
Emotional whiplash, especially when you’re still letting go of the last place
I’ve lived this cycle more than ten times—moving from job to job, project to project. From my first IT gig where I got fired after just a few days (yes, really), to roles in telecom, manufacturing, finance, education, government, and now infrastructure engineering—every restart brought unexpected lessons.
That early firing? It broke me. But it built me too. It taught me to expect the unknowns. It made this scripture real to me:
“For of him unto whom much is given much is required.” – Luke 12:48
And that’s what they don’t tell you: Starting a job doesn’t just mean you’re on probation— it means you’re learning the language, the culture, the personalities, and the systems. Sometimes you’re expected to run before you even learn where the shoes are.
So how do I handle it?
Soft skills. Empathy. Active listening. And above all, humility.
The technical side is always tough, but people are the real challenge. Knowing how to adapt, how to read the room, and when to ask versus when to figure it out—those are the survival tools.
“If ye are prepared ye shall not fear.” – D&C 38:30 That verse? It’s more than a motto. It’s how I show up—every first day, every new login, every fresh deployment.
I’ve seen people not make it past the 90-day mark. Sometimes they didn’t fit. Sometimes the job was the problem. Sometimes—let’s be honest—they oversold their résumé, got lucky at the interview, and then the real work revealed the truth.
Others just get carried by the blues—barely holding it together until their tank runs empty.
That’s why preparation matters. You don’t go to war without gear. You don’t climb a mountain without checking your boots. And you don’t start a new role without anchoring your mindset.
Finally, land where you love. A job shouldn’t just pay the bills — it should fuel your purpose. When you love what you do, it’s a win-win: You rise, and so does the company.
But if you’re stuck in a rut just to make ends meet… eventually, it drains more than your energy — it drains your spirit.
So don’t just look for a job. Climb toward work that gives you life.
A glimpse of the heavens through earthly shadows—chasing the Milky Way isn’t just about light, it’s about learning to see in the dark.
🌌 Chasing the Milky Way
There’s something sacred about standing in the desert with the Milky Way overhead.
I’ve chased it from Joshua Tree in California to Grand Canyon in Arizona, Monument Valley in Utah, and Moab—and every time, I feel the same awe.
My process is disciplined and deliberate. I survey the area in daylight, using the PhotoPills app to map the galactic core. Then I visualize my composition, mark the safest route from the car, and prep all my gear.
Primary lens: Nikon 14-24mm f/2.8G
Backup: Nikon 24mm f/1.4G
Tripod, remote shutter, red LED headlamp
Pre-focus and manual mode to avoid lens hunting
ISO, shutter speed, aperture—all dialed in
Everything is anticipated—just like in IT. One missed step, and the whole shot—or system—can fail. Just seeing the Milky Way with your own eyes is breathtaking—but to compose it meaningfully, that takes skill.
A great Milky Way shot is not just about stars— it’s about how you prepare in the dark.
🛠 When PowerShell Becomes Armor
It’s Monday morning. Your inbox is full. A user can’t log in, the SQL service is down, and your boss wants answers.
If you’re not ready, it feels like going to war without armor.
That’s where PowerShell becomes your weapon.
Let’s say you’re troubleshooting remote system uptime across 50 servers. Instead of logging in one by one:
📊 Real-time uptime scan across multiple servers using PowerShell – one script, instant clarity.
In just 10 seconds, you’ve got eyes on the entire server fleet. Who’s up. Who’s down. Who’s silent. The sharp tech doesn’t panic—he pinpoints, isolates, and executes. Fast. Focused. Fix deployed.
PowerShell isn’t just a tool—it’s your recon drone.
Like photographing the Milky Way, the best troubleshooting happens when everything is ready before chaos begins.
🎈 Rise Above the Blues
You’re not a machine. You weren’t built to be immune to fear, fatigue, or failure.
Unlike AI, we can’t predict everything. Life throws us emotional landmines—doubt, loneliness, weariness, fear and grief. And sometimes, it hits out of nowhere. A memory. A song. A walk past an empty office.
But here’s what I’ve learned:
You don’t need to erase the blues— you rise above them.
Just like launching a balloon skyward, it takes intention:
You eat clean even when you feel messy.
You work out even when your spirit is sore.
You create even when motivation lags.
And yes, you kneel—asking God for strength.
Whether you’re debugging a failed script, standing under a galaxy of stars, or simply trying to make it through a quiet night…
💪 The Endurance Factor
Endurance isn’t just for the gym — it’s a mindset I carry into every part of my life. Whether I’m hammering out code at 2AM or waiting patiently for the perfect light in photography, the principle is the same: lasting through the grind matters more than talent alone. Battle rope training reminds me that breakthroughs come after fatigue — in the gym, in IT, and behind the lens. Those who endure, evolve. Those who push past comfort zones, create lasting impact.
Each battle rope rep runs 180 seconds — just like a boxing round. I push through up to 6 rounds, simulating the intensity of a 12-round fight. It’s not just training — it’s conditioning for IT, for life, for the moments when quitting is easier. Endurance is the quiet strength behind every breakthrough.
🎯 Precision Under Pressure: Shooting, Striking, and Showing Up
Whether I’m at the range or on the mat, the ritual is the same: Prepare. Focus. Repeat.
When I train with my pistols, I practice daily with dummy rounds—loading, unloading, chamber checks, slide control. I break them down, clean them, reassemble them blindfolded—until every movement is instinctive.
It’s the same with MMA and air punching drills. My body is conditioned not just for strength, but discipline. Every strike, every stance, is deliberate. I don’t train to show off—I train to be ready.
You see, when it’s Monday morning and something breaks at work—your system is down, a PowerShell script fails, a teammate’s counting on you—that’s your moment. That’s your live fire.
You don’t rise to the occasion. You fall back on your training.
Whether I’m troubleshooting a crashed server, hiking a steep trail for that perfect Milky Way shot, or helping someone start their climb—discipline is the thread. I’ve learned that showing up prepared is half the victory.
Just like the range:
No second chances if you’re not ready.
Precision comes from practice.
And calm comes from confidence.
🏁 Conclusion
There are mountains I’ve climbed—in IT, in life, and in silence.
From my early days as a PC Support Specialist at USC, through roles in telecom (Verizon), manufacturing (Alcoa), local government (City of West Covina), law firms, education (The Claremont Colleges), our Worldwide Church, regional banking (City National Bank), fintech (Payforward), retail (Monster Energy), global finance (PIMCO), and now as an Infrastructure Engineer in Utah—none of those summits came easy.
Even when I chase the stars with my camera, it’s the climb that makes the view meaningful.
So to anyone out there starting over, picking up the pieces, or doubting their path:
You don’t fall on a mountaintop. You climb it. And you keep climbing. Even when you’re tired. Especially when you’re tired.