Category: Powershell Hub

  • Track Domain-Joined Devices by Join Date Using PowerShell

    When you’re managing hundreds of devices in an Active Directory environment, tracking when a machine joins the domain can help in everything from license compliance to forensic investigations.

    Recently, I needed to identify a laptop that joined our domain on a specific date to verify a SolidWorks license assignment — and these two PowerShell commands did the job flawlessly.


    🔹 1. Get the Most Recently Joined Computer

    Use this command to find the latest computer object added to Active Directory:

    powershellCopyEditImport-Module ActiveDirectory
    
    Get-ADComputer -Filter * -Property whenCreated |
    Sort-Object whenCreated -Descending |
    Select-Object Name, whenCreated -First 1
    

    Why this matters:
    This is especially useful when onboarding new machines or auditing join activity after reimaging.


    🔹 2. Find Devices Joined on a Specific Date

    To find any computer joined on a specific day — for example, April 25, 2025 — use:

    powershellCopyEdit$startDate = Get-Date "04/25/2025 00:00:00"
    $endDate = Get-Date "04/26/2025 00:00:00"
    
    Get-ADComputer -Filter * -Property whenCreated |
    Where-Object { $_.whenCreated -ge $startDate -and $_.whenCreated -lt $endDate } |
    Select-Object Name, whenCreated |
    Sort-Object whenCreated
    

    Why this helps:
    Perfect for license verification, asset tracking, or validating compliance windows. You can adapt the date range to capture entire weeks, weekends, or even off-hours join attempts.


    🔐 Final Thought

    Even a simple attribute like whenCreated becomes a powerful audit tool when combined with the right script. These commands now live in my PowerShell toolbox — and they just helped solve a license tracking challenge without any guesswork.


    ✅ Add these to your script collection.
    ✅ Automate the insight.
    ✅ Stay ahead of the curve.

  • PowerShell Script: Managing Shared Mailbox Access

    Overview

    This guide provides PowerShell commands to remove user access from shared mailboxes and verify access removal in Microsoft Exchange Online.

    Prerequisites

    • Administrator privileges in Exchange Online.
    • PowerShell module for Exchange Online installed.
    • Proper authentication to Exchange Online.

    Step 1: Connect to Exchange Online

    Connect-ExchangeOnline -UserPrincipalName [email protected]

    Step 2: Remove User Access from Shared Mailboxes

    $User = "[email protected]"
    $SharedMailboxes = @("[email protected]", "[email protected]")
    
    foreach ($Mailbox in $SharedMailboxes) {
        Remove-MailboxPermission -Identity $Mailbox -User $User -AccessRights FullAccess -Confirm:$false
        Remove-RecipientPermission -Identity $Mailbox -Trustee $User -AccessRights SendAs -Confirm:$false
    }

    Step 3: Verify Access Removal

    foreach ($Mailbox in $SharedMailboxes) {
        Get-MailboxPermission -Identity $Mailbox | Where-Object { $_.User -like "$User" }
        Get-RecipientPermission -Identity $Mailbox | Where-Object { $_.Trustee -like "$User" }
    }

    If no results are returned, the user no longer has access.

    Step 4: Disconnect from Exchange Online

    Disconnect-ExchangeOnline -Confirm:$false

    Notes

    Additional Considerations

    • If users report still having access, check cached credentials or ensure changes have propagated.
    • If access needs to be reinstated, use Add-MailboxPermission and Add-RecipientPermission commands.

    This script helps maintain security and manage mailbox access efficiently within Exchange Online.

    © 2012–2025 Jet Mariano. All rights reserved.
    For usage terms, please see the Legal Disclaimer.

  • 10 Essential PowerShell Commands for IT Administrators

    💻 PowerShell is an IT Admin’s best friend—whether you’re managing Active Directory, troubleshooting network issues, or automating daily tasks. These essential commands will help you work smarter, not harder.


    🔹 1. Find All Locked-Out Users in Active Directory

    🛑 Identify locked-out accounts instantly.

    powershellCopyEditSearch-ADAccount -LockedOut | Select-Object Name, SamAccountName, LockedOut
    

    Use Case: Quickly locate and assist locked-out users.


    🔹 2. Unlock a User’s Account in Active Directory

    🔓 Unlock a user’s account without using the GUI.

    powershellCopyEditUnlock-ADAccount -Identity jdoe
    

    Use Case: Enables IT admins to resolve lockouts in seconds.


    🔹 3. Force a Password Reset for a User

    🔄 Require a user to change their password at next login.

    powershellCopyEditSet-ADUser -Identity jdoe -PasswordNeverExpires $false -ChangePasswordAtLogon $true
    

    Use Case: Ensures security compliance without manual resets.


    🔹 4. Retrieve System Boot Time

    🖥️ Check how long a system has been running.

    powershellCopyEdit(Get-Date) - (gcim Win32_OperatingSystem).LastBootUpTime
    

    Use Case: Displays uptime in days, hours, and minutes.


    🔹 5. List Running Services with “Stopped” Status

    🚀 Check which services aren’t running.

    powershellCopyEditGet-Service | Where-Object { $_.Status -eq 'Stopped' } | Select-Object Name, DisplayName
    

    Use Case: Helps identify critical services that need restarting.


    🔹 6. Test Internet Connectivity

    🌐 Check if a machine has an active internet connection.

    powershellCopyEditTest-NetConnection -ComputerName google.com -InformationLevel Detailed
    

    Use Case: Quick and easy network diagnostics.


    🔹 7. Find the Last 10 Failed Login Attempts

    🚫 Track failed login attempts for security auditing.

    powershellCopyEditGet-EventLog -LogName Security -InstanceId 4625 -Newest 10
    

    Use Case: Detects brute-force attacks and failed password attempts.


    🔹 8. Get a List of Users with Expired Passwords

    🔑 Find all users with expired passwords in Active Directory.

    powershellCopyEditSearch-ADAccount -PasswordExpired | Select-Object Name, SamAccountName
    

    Use Case: Prevents user lockouts and ensures password updates.


    🔹 9. Get Disk Space Usage on a Server

    💾 Check available disk space across all drives.

    powershellCopyEditGet-PSDrive | Where-Object {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"} | 
    Select-Object Name, Used, Free
    

    Use Case: Helps avoid storage-related downtime before it happens.


    🔹 10. List & Stop Running Processes

    View active processes and terminate any misbehaving ones.

    powershellCopyEditGet-Process | Select-Object ProcessName, Id, CPU | Format-Table -AutoSize
    Stop-Process -Name "notepad" -Force
    

    Use Case: Quickly terminate resource-hogging processes without Task Manager.


    🚀 Conclusion: Work Smarter, Automate More!

    💡 PowerShell is a game-changer for IT admins, allowing faster troubleshooting, better automation, and enhanced security monitoring. Whether you’re managing user accounts, securing systems, or optimizing network performance, these commands will save time and effort.

    🖥️ Next Steps?
    📌 Bookmark this page and check back for more advanced PowerShell scripts!
    🔗 Need more automation tips? Visit the PowerShell Hub for deeper insights.

    © 2012–2025 Jet Mariano. All rights reserved.
    For usage terms, please see the Legal Disclaimer.

  • 10 Must-Have PowerShell Scripts for IT Troubleshooting

    PowerShell is a powerful tool for IT professionals, allowing automation, troubleshooting, and system management.
    Whether you’re handling system cleanup, retrieving Wi-Fi passwords, or managing processes, these PowerShell commands can be lifesavers.
    Here are five must-know PowerShell scripts to add to your IT arsenal.


    1. Extract All Installed Applications (For Inventory & Troubleshooting)

    Need to check what software is installed on a system? This script pulls a list of all installed applications along with their version, publisher, and installation date.

    Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
    Sort-Object DisplayName |
    Format-Table -AutoSize

    🔹 Bonus: Export the list to a CSV file for documentation:

    Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
    Export-Csv -Path "C:\InstalledApps.csv" -NoTypeInformation

    2. Find and Kill Stubborn Processes

    Have an unresponsive application? Use this script to forcefully close any running process by name.

    $processName = "Teams" # Change this to the process you want to kill
    Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process -Force

    🔹 Bonus: Convert it into a user-friendly GUI:

    Add-Type -TypeDefinition @"
    using System;
    using System.Windows.Forms;
    public class KillProcess {
        public static void Main() {
            string processName = Microsoft.VisualBasic.Interaction.InputBox("Enter process name to kill:", "Kill Process", "Teams");
            if (!string.IsNullOrEmpty(processName)) {
                System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName(processName);
                foreach (var proc in procs) {
                    proc.Kill();
                }
            }
        }
    }
    "@ -Language CSharp
    
    [KillProcess]::Main()

    3. Automate System Cleanup (Cache, Temp Files, Event Logs)

    Over time, systems accumulate temporary files that can slow them down. This command clears temporary files, cache, and event logs:

    Write-Host "Clearing Temp Files, Cache, and Event Logs..." -ForegroundColor Green
    Remove-Item -Path "$env:TEMP\*" -Recurse -Force -ErrorAction SilentlyContinue
    Remove-Item -Path "C:\Windows\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue
    Clear-EventLog -LogName Application, System, Security
    Write-Host "Cleanup Completed!" -ForegroundColor Cyan

    🔹 Bonus: Automate this cleanup by scheduling it in Task Scheduler.


    4. Retrieve Wi-Fi Passwords Saved on a PC

    Need to recover a saved Wi-Fi password? This script extracts the stored credentials for all previously connected networks:

    (netsh wlan show profile) | Select-String "\:(.+)$" | ForEach-Object { 
        $network = $_.Matches.Groups[1].Value.Trim()
        $password = (netsh wlan show profile name="$network" key=clear) | Select-String "Key Content\W+\:(.+)$"
        if ($password) { 
            Write-Host "Wi-Fi: $network | Password: $($password.Matches.Groups[1].Value.Trim())" -ForegroundColor Green 
        }
    }

    🔹 Use Case: If you’re connected to a Wi-Fi network but forgot the password, this script retrieves it instantly.


    5. Scan for Suspicious File Modifications (Forensic Command)

    This script performs a recursive scan on a target machine to find recently modified files with specific extensions and flag any that contain high-risk keywords. Ideal for forensic scenarios.

    $target = "RemoteComputerName"  # Replace with computer name or IP
    $extensions = @("*.ps1", "*.sql", "*.dll", "*.cs", "*.sln", "*.vbproj")
    $keywords = 'drop', 'truncate', 'remove', 'shutdown'
    
    $session = New-PSSession -ComputerName $target -ErrorAction SilentlyContinue
    if ($session) {
        Invoke-Command -Session $session -ScriptBlock {
            param($exts, $keywords)
            Get-ChildItem -Path "C:\" -Recurse -Include $exts -ErrorAction SilentlyContinue |
            Where-Object {
                $_.LastWriteTime -gt (Get-Date).AddDays(-90) -and
                ($_ | Select-String -Pattern ($keywords -join '|') -SimpleMatch -Quiet)
            } |
            Select-Object FullName, LastWriteTime, Length
        } -ArgumentList $extensions, $keywords | Export-Csv -Path "$env:USERPROFILE\Desktop\forensic-scan.csv" -NoTypeInformation
    
        Remove-PSSession $session
    } else {
        Write-Host "Unable to connect to $target"
    }
    

    Why it matters: This script was used during a forensic investigation while I was serving on a local government IT forensic team. Its purpose was to detect whether sensitive scripts or source code had been created, modified, or concealed on a colleague’s machine. By targeting specific file types and high-risk keywords (e.g., drop, truncate, remove, shutdown), the script helps identify signs of unauthorized automation, code tampering, or mismanagement of critical systems. It supported an internal review when key files were missing and operational stability was in question.


    6. Quick System Resource Snapshot

    # Display top 10 processes by CPU usage
    Get-Process | Sort CPU -Descending | Select -First 10
    
    # Show current CPU usage
    Get-Counter '\Processor(_Total)\% Processor Time'
    
    # Show available memory
    Get-Counter '\Memory\Available MBytes'
    
    # Summarize total, free, and used memory
    Get-WmiObject -Class Win32_OperatingSystem |
    Select-Object TotalVisibleMemorySize, FreePhysicalMemory |
    ForEach-Object {
        [PSCustomObject]@{
            'TotalMemoryMB' = [math]::Round($_.TotalVisibleMemorySize / 1024, 2)
            'FreeMemoryMB'  = [math]::Round($_.FreePhysicalMemory / 1024, 2)
            'UsedMemoryMB'  = [math]::Round(($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) / 1024, 2)
        }
    }
    

    Why it matters: This comprehensive snapshot is a go-to tool for on-the-fly diagnostics. Whether you’re troubleshooting performance issues, memory leaks, or high CPU usage, this command instantly reveals which processes are draining resources—without launching Task Manager or Performance Monitor. Ideal for quick triage during server slowdowns or SQL bottlenecks.

    7. Check System Uptime

    $uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
    Write-Host "System Uptime: $($uptime.Days) Days, $($uptime.Hours) Hours, $($uptime.Minutes) Minutes" -ForegroundColor Cyan
    

    Why it matters: Quickly see how long the system has been running—helpful in determining recent reboots or crashes.

    8. Check Disk Space

    Get-PSDrive -PSProvider FileSystem | Select-Object Name, Used, Free, @{Name="Free(GB)";Expression={"{0:N2}" -f ($_.Free / 1GB)}}
    

    Why it matters: Instantly assess available drive space and avoid unexpected application or SQL failures due to low disk capacity.

    9. Review Event Logs (System Errors Only)

    Get-EventLog -LogName System -EntryType Error -Newest 20 | Format-Table TimeGenerated, Source, EventID, Message -AutoSize
    

    Why it matters: Check for hardware, driver, or system errors logged in the last events—critical when troubleshooting.

    10. Forensic Script Scan – Local Machine Analysis

    This script performs a forensic scan of the local machine, identifying recently modified files with common scripting and development extensions. It’s ideal for monitoring changes or performing audits.

    $targetPath = "C:\"
    $extensions = '*.ps1', '*.php', '*.sql', '*.bat', '*.cmd', '*.vbs', '*.js', '*.dll', '*.config', '*.json'
    $outputPath = "C:\Temp\ScriptAuditReport.csv"
    
    Get-ChildItem -Path $targetPath -Include $extensions -Recurse -ErrorAction SilentlyContinue |
    Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-90) } |
    Sort-Object LastWriteTime -Descending |
    Select-Object FullName, LastWriteTime |
    Export-Csv $outputPath -NoTypeInformation
    
    

    Why it matters: Use this script when you suspect undocumented code changes, malicious automation, or hidden activity on a machine. It pinpoints recently altered files with extensions commonly used for scripting or system manipulation. Ideal for incident response or auditing newly repurposed systems.

    Final Thoughts

    PowerShell is a must-have tool for IT professionals. These scripts help automate tasks, troubleshoot issues, and improve system efficiency. Which of these commands do you find most useful? Let me know in the comments!

    🚀 Stay tuned for more PowerShell tips and tricks!

    © 2012–2025 Jet Mariano. All rights reserved.
    For usage terms, please see the Legal Disclaimer.

error: Content is protected !!