Category: Windows

  • User Account Audit with Net User Parsing PowerShell Script

    This PowerShell script audits local user accounts by listing each account’s enabled/disabled status and extracting detailed last logon information using the net user command. It outputs a neatly formatted table, providing system administrators with a clear snapshot of user account activity for easier monitoring and troubleshooting.

    Click to view script…
    <#
    .SYNOPSIS
        Audits local user accounts by listing their enabled/disabled status and last logon time.
    
    .DESCRIPTION
        This script retrieves local user accounts using Get-LocalUser and then obtains last logon information
        for each account by parsing the output of the "net user" command. It outputs a table showing each account's name,
        whether it is enabled, and its last logon time (or "Never" if the account has not logged on).
    
    .NOTES
        Run as Administrator if necessary.
    #>
    
    function Get-LastLogonNetUser {
        param (
            [Parameter(Mandatory = $true)]
            [string]$UserName
        )
    
        # Execute the "net user" command for the given user
        $netUserOutput = net user $UserName 2>&1
    
        # Look for a line that contains "Last logon"
        $lastLogonLine = $netUserOutput | Where-Object { $_ -match "Last logon" }
        if ($lastLogonLine) {
            # The expected format is something like:
            #   Last logon                   2/12/2021 3:45:30 PM
            # Remove the label text and trim spaces to isolate the date/time string.
            $logonValue = ($lastLogonLine -replace ".*Last logon\s+", "").Trim()
            if ($logonValue -match "Never") {
                return "Never"
            }
            else {
                # Attempt to parse the logon value as a DateTime.
                try {
                    $dt = [DateTime]::Parse($logonValue)
                    return $dt
                }
                catch {
                    return $logonValue
                }
            }
        }
        else {
            return "Unknown"
        }
    }
    
    # Retrieve local user accounts.
    try {
        $localUsers = Get-LocalUser
    } catch {
        Write-Error "Failed to retrieve local users. Ensure this is run on a supported version of Windows with appropriate permissions."
        exit
    }
    
    # Prepare an array to store the audit results.
    $result = @()
    
    foreach ($user in $localUsers) {
        $userName = $user.Name
        $lastLogon = Get-LastLogonNetUser -UserName $userName
    
        $result += [PSCustomObject]@{
            Name      = $userName
            Enabled   = $user.Enabled
            LastLogon = $lastLogon
        }
    }
    
    # Output the results in a formatted table.
    $result | Format-Table -AutoSize
  • Check Public IP with PowerShell Script

    A straightforward PowerShell script that lets you quickly determine your current public IP address in a simple and hassle-free way.

    Click to view script…
    # Get-PublicIP.ps1
    # This script retrieves and displays your public IP address
    
    # Query the API to get your public IP address in JSON format.
    $response = Invoke-RestMethod -Uri "https://api.ipify.org?format=json"
    
    # Display the IP address.
    Write-Host "Your public IP address is: $($response.ip)"

  • Retrieve Detailed Windows Network Information with PowerShell

    This PowerShell script gathers comprehensive network details from your Windows machine—including default route, local IP, subnet mask, broadcast address, MAC address, DNS servers, and public IP—while also performing a ping test to 8.8.8.8 for latency analysis. It’s a handy tool for troubleshooting and monitoring your network.

    Click to view script…
    # NetworkInfoDetailed.ps1 - Detailed network information for Windows
    
    # Helper function: Convert a CIDR prefix (e.g. 24) to a dotted-decimal subnet mask (e.g. 255.255.255.0)
    function Convert-PrefixToSubnetMask {
        param (
            [int]$PrefixLength
        )
        $max = [uint32]::MaxValue
        # For a given prefix, the netmask is: netmask = max - (2^(32 - prefix) - 1)
        $netmaskInt = $max - ([uint32]([math]::Pow(2, (32 - $PrefixLength)) - 1))
        $octet1 = ($netmaskInt -shr 24) -band 0xFF
        $octet2 = ($netmaskInt -shr 16) -band 0xFF
        $octet3 = ($netmaskInt -shr 8) -band 0xFF
        $octet4 = $netmaskInt -band 0xFF
        return "$octet1.$octet2.$octet3.$octet4"
    }
    
    # Helper function: Convert an IP string to a 32-bit unsigned integer.
    function Convert-IPStringToInt {
        param ([string]$ip)
        $bytes = $ip.Split('.') | ForEach-Object { [uint32]$_ }
        return ([uint32]($bytes[0] -shl 24)) -bor ([uint32]($bytes[1] -shl 16)) -bor ([uint32]($bytes[2] -shl 8)) -bor $bytes[3]
    }
    
    # Helper function: Convert a 32-bit unsigned integer to an IP string.
    function Convert-IntToIPAddress {
        param ([uint32]$ipInt)
        $a = ($ipInt -shr 24) -band 0xFF
        $b = ($ipInt -shr 16) -band 0xFF
        $c = ($ipInt -shr 8) -band 0xFF
        $d = $ipInt -band 0xFF
        return "$a.$b.$c.$d"
    }
    
    # Begin output with colored text using Write-Host.
    Write-Host "Gathering default route information..." -ForegroundColor Blue
    
    # Get the default route (DestinationPrefix "0.0.0.0/0") for IPv4.
    $defaultRoute = Get-NetRoute -DestinationPrefix "0.0.0.0/0" -ErrorAction SilentlyContinue | 
        Where-Object { $_.NextHop -ne "0.0.0.0" } | 
        Sort-Object -Property RouteMetric | 
        Select-Object -First 1
    
    if (-not $defaultRoute) {
        Write-Host "Error: No active network interface found. Are you connected to a network?" -ForegroundColor Red
        exit 1
    }
    
    $gateway    = $defaultRoute.NextHop
    $ifaceIndex = $defaultRoute.InterfaceIndex
    
    # Retrieve the network adapter based on InterfaceIndex.
    $interface = Get-NetAdapter -InterfaceIndex $ifaceIndex -ErrorAction SilentlyContinue
    if (-not $interface) {
        Write-Host "Error: Could not retrieve network adapter information." -ForegroundColor Red
        exit 1
    }
    $ifaceName = $interface.Name
    
    Write-Host "Default Interface: $ifaceName" -ForegroundColor Green
    Write-Host "Gateway: $gateway" -ForegroundColor Green
    
    # Get the IPv4 address information.
    $ipInfo = Get-NetIPAddress -InterfaceIndex $ifaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue |
        Where-Object { $_.IPAddress } |
        Select-Object -First 1
    if (-not $ipInfo) {
        Write-Host "Error: Could not retrieve IP address information." -ForegroundColor Red
        exit 1
    }
    $ip           = $ipInfo.IPAddress
    $prefixLength = $ipInfo.PrefixLength
    
    Write-Host "IP Address: $ip" -ForegroundColor Green
    
    # Convert the prefix length to a subnet mask.
    $netmask = Convert-PrefixToSubnetMask -PrefixLength $prefixLength
    Write-Host "Subnet Mask: $netmask" -ForegroundColor Green
    
    # Calculate the broadcast address.
    $ipInt = Convert-IPStringToInt -ip $ip
    
    $max = [uint32]::MaxValue
    # Compute the netmask integer as: max - (2^(32 - prefix) - 1)
    $netmaskInt = $max - ([uint32]([math]::Pow(2, (32 - $prefixLength)) - 1))
    # The inverse mask (host portion) is:
    $inv = $max - $netmaskInt
    
    # Calculate the broadcast integer: (IP AND netmask) OR inverse mask.
    $broadcastInt = ([uint32]($ipInt -band $netmaskInt)) -bor $inv
    
    $broadcast = Convert-IntToIPAddress -ipInt $broadcastInt
    Write-Host "Broadcast Address: $broadcast" -ForegroundColor Green
    
    # Get the MAC (hardware) address.
    $mac = $interface.MacAddress
    Write-Host "MAC Address: $mac" -ForegroundColor Green
    
    # Retrieve DNS servers for the interface.
    $dnsInfo = Get-DnsClientServerAddress -InterfaceIndex $ifaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
    $dnsServers = $dnsInfo.ServerAddresses -join ' '
    Write-Host "DNS Servers: $dnsServers" -ForegroundColor Green
    
    # Get the public IP address using an external service (api.ipify.org).
    try {
        $public_ip = Invoke-RestMethod -Uri "https://api.ipify.org"
        Write-Host "Public IP Address: $public_ip" -ForegroundColor Green
    } catch {
        Write-Host "Error retrieving public IP address." -ForegroundColor Red
    }
    
    # Perform a ping test to 8.8.8.8 and calculate the average latency.
    Write-Host "Performing ping test to 8.8.8.8..." -ForegroundColor Blue
    try {
        $pingResults = Test-Connection -ComputerName 8.8.8.8 -Count 3 -ErrorAction Stop
        if ($pingResults) {
            $avgLatency = ($pingResults | Measure-Object -Property ResponseTime -Average).Average
            Write-Host ("Average Latency (ping): {0:N2} ms" -f $avgLatency) -ForegroundColor Green
        } else {
            Write-Host "Ping test failed." -ForegroundColor Red
        }
    } catch {
        Write-Host "Ping test failed." -ForegroundColor Red
    }
    
    Write-Host "Detailed network information gathered successfully." -ForegroundColor Blue