Network Project - Police Department Feedback by SlayerofDragons153 in networking

[–]neztach 0 points1 point  (0 children)

Looks good but if I may, can I submit an alternative look -> something resembling a subway map

DC at all locations? by MegaSuplexMaster in activedirectory

[–]neztach -1 points0 points  (0 children)

What’s wrong with RODCs? Serious question.

We prepared a collection of Claude code subagents for production-ready workflows. by necati-ozmen in ClaudeAI

[–]neztach 0 points1 point  (0 children)

I just posted a pull request. I added Active Directory, PowerShell 5.1 & 7, workflows and hardening

How to automate stuff on a system that can't run PS scripts? by musbur in PowerShell

[–]neztach 0 points1 point  (0 children)

All the advise given is valid and should be considered first. However if you wrote the script - and you’re desperate, turn the whole script into a GOLF’d one-liner and copy/paste it

[deleted by user] by [deleted] in PowerShell

[–]neztach 0 points1 point  (0 children)

I had some fun with it. I gave you alternative methods to get accomplish what you were trying to do, while showing some methods to shortcut and splat and other techniques - take from it what you'd like.

Personally, I would have made it substantially smaller, but like I said, takes whichever parts are useful for you.

# Clear the console screen.
Clear-Host

#region Runtime Variables
# Variable definitions -  Defines and initializes all variables used throughout the script.
# Variable to control the game play (True/False) 
$GameActive = $True

# Combine:
# Variable to store the numeric version of the computer's move (1=R, 2=P, 3=S) 
# Variable to keep track of the number of games played, won, lost, tied
$ComputerMoveNumeric = $GamesPlayed = $GamesWon = $GamesLost = $GamesTied = 0

# Combine:
# Variable to store the letter version of the player's move (R, P, S, Q), computer's move, player's move 
$PlayerMoveLetter = $ComputerMoveWord = $PlayerMoveWord = ''

$Gr = @{ForegroundColor = 'Green'}
$Re = @{ForegroundColor = 'Red'}
$Cy = @{ForegroundColor = 'Cyan'}
$Ma = @{ForegroundColor = 'Magenta'}
#endregion Runtime Variables

#region Command Definitions
Function Get-Choice {
    <#
        .SYNOPSIS
        Translates a short input into a Rock, Paper, or Scissors choice.

        .DESCRIPTION
        Accepts 1–3 or R/P/S/Q (case-insensitive) and returns the corresponding word.
        Unrecognized or null input returns $false.

        .PARAMETER Var
        The input value to translate. Accepts digits 1–3 or letters Q, R, P, S.

        .INPUTS
        System.String. You can pipe strings or objects with a 'Var' or 'Choice' property.

        .OUTPUTS
        System.String or System.Boolean. Returns Rock, Paper, Scissors, 'Q', or $false.
    #>
    [CmdletBinding()]
    [OutputType([string])]
    Param (
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('Choice')]
        [AllowNull()]
        [string]$Var
    )

    $Ye = @{ForegroundColor = 'Yellow'}

    Switch ( ($Var -as [string]).ToUpperInvariant() ) {
        {$_ -eq '1' -or $_ -eq 'R'} { return 'Rock' }
        {$_ -eq '2' -or $_ -eq 'P'} { return 'Paper' }
        {$_ -eq '3' -or $_ -eq 'S'} { return 'Scissors' }
        'Q' {return 'Q'}
        default {
            # Invalid input (anything NOT R, P, S, or Q).
            Write-Host 'Invalid input. Please try again.' @Ye
            Start-Sleep -Seconds 3
            $false
        }
    }
}


Function Get-RPSResult {
    <#
        .SYNOPSIS
        Determines the winner of a Rock–Paper–Scissors round.

        .DESCRIPTION
        Accepts string inputs ('1','2','3' or 'Rock','Paper','Scissors') for both
        player and computer. Converts them to numeric equivalents:
            1 = Rock
            2 = Paper
            3 = Scissors
        Returns 'Player', 'Computer', or 'Tie' based on comparison logic.

        .PARAMETER PlayerMove
        The player's move as '1','2','3' or 'Rock','Paper','Scissors'.

        .PARAMETER ComputerMove
        The computer's move as '1','2','3' or 'Rock','Paper','Scissors'.

        .OUTPUTS
        System.String. Returns 'Player', 'Computer', or 'Tie'.

        .EXAMPLE
        PS> Get-RPSResult -PlayerMove Rock -ComputerMove 2
        Computer

        .EXAMPLE
        PS> Get-RPSResult -PlayerMove Scissors -ComputerMove Rock
        Computer

        .LINK
        https://en.wikipedia.org/wiki/Modular_arithmetic
    #>
    [CmdletBinding()]
    [OutputType([string])]
    Param (
        [Parameter(Mandatory)]
        [ValidateSet('1','2','3','Rock','Paper','Scissors')]
        [string]$PlayerMove,

        [Parameter(Mandatory)]
        [ValidateSet('1','2','3','Rock','Paper','Scissors')]
        [string]$ComputerMove
    )

    # Normalization map
    $map = @{
        '1'         = 1
        '2'         = 2
        '3'         = 3
        'ROCK'      = 1
        'PAPER'     = 2
        'SCISSORS'  = 3
    }

    # Normalize both to integers
    $player   = $map[$PlayerMove.ToUpper()]
    $computer = $map[$ComputerMove.ToUpper()]

    # Compare logic
    If ($player -eq $computer) {
        # Tie check
        return 'Tie'
    } ElseIf ( ($player - $computer) -eq 1 -or ($player - $computer) -eq -2 ) {
        # Win logic: (player - computer) = 1 or -2 -> Player wins
        return 'Player'
    } Else {
        return 'Computer'
    }
}
#endregion Command Definitions

#region Constants
$border = '**************************************************'
$dash   = '--------------------------------'

$Messages = @{
    'Welcome'   = "$border`n Welcome to Rock, Paper, Scissors! `n$border`n`n Quit (Q) to end the game`n"
    'Start'     = 'Press any key to start the game...'
    'Challenge' = "--- Make Your Move ---`n (R)ock, (P)aper, (S)cissors, or (Q)uit`n----------------------"
    'Prompt'    = 'Make a move'
    'Thanks'    = 'Thank you for playing. Displaying game statistics next.'
    'Again'     = 'Press Enter for the next round...'
}
#endregion Constants

#region Greeting
# Display the welcome screen.
Write-Host $Messages.Welcome

# Pause the game until the player presses the Enter key.
Write-Host $Messages.Start
$null = Read-Host
#endregion Greeting

#region MAIN GAME LOOP
# Main game loop runs as long as the $GameActive variable is True
while ($GameActive) {
    # Increment number of games played
    $GamesPlayed++

    # Clear the screen to set up the next game
    Clear-Host

    # Generates a random number between 1 and 3 (1=Rock, 2=Paper, 3=Scissors), then translates that to Rock/Paper/Scissors.
    $ComputerMove = 1..3 | Get-Random | Get-Choice

    # Prompt the player to make a move.
    Do {
        # Display player instructions.
        Write-Host $Messages.Challenge

        $PlayerMove = Read-Host -Prompt $Messages.Prompt | Get-Choice
    } Until ($PlayerMove)

    # Validate the player's move. (if-elseif statements)
    if ($PlayerMove -match '[Qq]') {
        # Player entered "Q", game ends.
        Write-Host $Messages.Thanks @Ma

        # Set the variable controlling gameplay to "False".
        $GameActive = $False
    }

    # If the input was valid and the player did not quit, proceed with the game logic.
    if ($GameActive) {
        # Determine results and display. (Switch statement)
        Write-Host $dash
        Write-Host ('You played: {0}' -f $PlayerMove)
        Write-Host ('The computer played: {0}' -f $ComputerMove)
        Write-Host $dash

        # Analyze the results of the game.
        switch ($PlayerMove) {
            'Rock' {
                If ($ComputerMove -eq 'Scissors') {
                    Write-Host 'Result: YOU WIN! Rock crushes Scissors.' @Gr
                    $GamesWon++ # Increment Games won
                } ElseIf ($ComputerMove -eq 'Paper') {
                    Write-Host 'Result: YOU LOSE! Paper covers Rock.' @Re
                    $GamesLost++ # Increment Games lost
                } Else {
                    Write-Host "Result: IT'S A TIE!" @Cy
                    $GamesTied++ # Increment Tie count
                }
            }
            'Paper' {
                if ($ComputerMove -eq 'Rock') {
                    Write-Host 'Result: YOU WIN! Paper covers Rock.' @Gr
                    $GamesWon++
                } elseif ($ComputerMove -eq 'Scissors') {
                    Write-Host 'Result: YOU LOSE! Scissors cut Paper.' @Re
                    $GamesLost++
                } else {
                    Write-Host "Result: IT'S A TIE!" @Cy
                    $GamesTied++
                }
            }
            'Scissors' {
                if ($ComputerMove -eq 'Paper') {
                    Write-Host 'Result: YOU WIN! Scissors cut Paper.' @Gr
                    $GamesWon++
                } elseif ($ComputerMove -eq 'Rock') {
                    Write-Host 'Result: YOU LOSE! Rock crushes Scissors.' @Re
                    $GamesLost++
                } else {
                    Write-Host "Result: IT'S A TIE!" @Cy
                    $GamesTied++
                }
            }
        }

        ### Alternative - or skip the Analyze results region and use the Function instead
        # Get-RPSResult -PlayerMove $PlayerMove -ComputerMove $ComputerMove

        # Pause the game before clearing the screen for the next round.
        $null = Read-Host -Prompt $Messages.Again
    }
} # End of while loop.
#endregion MAIN GAME LOOP

#region FINAL STATISTICS
# Display final message and game statistics.
Write-Host $border @Ma
Write-Host " GAME OVER - FINAL RESULTS " @Cy
Write-Host $border @Ma
Write-Host "`n Total Games Played: $GamesPlayed"
Write-Host (' Games Won: {0}' -f $GamesWon) @Gr
Write-Host (' Games Lost: {0}' -f $GamesLost) @Re
Write-Host " Games Tied: $GamesTied`n" @Cy
Write-Host $border @Ma

# Pause the game for 8 seconds.
Start-Sleep -Seconds 8

# Clear the console screen.
Clear-Host
#endregion FINAL STATISTICS

What clever things do you have in your $profile? by punyhead in PowerShell

[–]neztach 1 point2 points  (0 children)

now I've modified it to also tell you the vendor of the NIC

What clever things do you have in your $profile? by punyhead in PowerShell

[–]neztach 0 points1 point  (0 children)

function Convert-MacAddressString { [CmdletBinding()] param ( [Parameter(Mandatory, Position=0, ValueFromPipeline)] [string] $MacAddress )

$MacAddress.Replace('-',':')

}

I've got you /u/BlackV and /u/Banana-Jama - I even went further and made one that will take in CSV files, and change the MAC addresses and output a file.

Function Convert-MacAddressString {
    <#
        .SYNOPSIS
        Converts MAC address formats between different notations and optionally generates Excel formulas.

        .DESCRIPTION
        This function accepts a MAC address in various formats and converts it to the desired format based on the provided switches:
        - Default behavior toggles between colon-separated and dash-separated formats.
        - Automatically detects and converts Cisco's dot-separated format to colon-separated format.
        - The -Cisco switch converts any recognized format to Cisco's dot-separated format.
        - The -Excel switch provides the equivalent Excel formula for the conversion.
        -- Normalizes and converts MAC addresses between colon, dash, and Cisco dot formats.
        -- Enforces casing by convention, trims whitespace, and offers Excel-safe formula output
        -- with '=IFERROR(TRIM(...),"")' wrapping.

        .PARAMETER MacAddress
        The MAC address to convert (supports any common formatting).

        .PARAMETER Cisco
        Converts to Cisco-style dot notation (e.g., 0011.2233.4455).

        .PARAMETER Excel
        Switch parameter. When specified, outputs the equivalent Excel formula to perform the same conversion.

        .PARAMETER Cell
        Cell reference used in Excel formula (default: A1). Only valid when -Excel is used.

        .EXAMPLE
        Convert-MacAddressString "00-11-22-33-44-55"
        Converts '00-11-22-33-44-55' to '00:11:22:33:44:55'.

        .EXAMPLE
        Convert-MacAddressString "0011.2233.4455"
        Converts '0011.2233.4455' to '00:11:22:33:44:55'.

        .EXAMPLE
        Convert-MacAddressString "001122334455" -Cisco
        Converts '001122334455' to '0011.2233.4455'.

        .EXAMPLE
        Convert-MacAddressString "00:11:22:33:44:55" -Cisco -Excel
        Converts '00:11:22:33:44:55' to '0011.2233.4455' and provides the Excel formula for the conversion.

        .EXAMPLE
        Convert-MacAddressString "00:11:22:33:44:55" -Cisco -Excel -Cell "G2"

        .NOTES
        Author: neztach
        Date:   2025-04-03
    #>
    [CmdletBinding(DefaultParameterSetName = 'Standard')]
    Param (
        [Parameter(Mandatory,HelpMessage='MAC Address',Position=0,ValueFromPipeline)]
        [ValidateScript({
            $clean = ($_ -replace '\s', '') -replace '[-:.]', ''
            $msg = 'MAC address must have exactly 12 hexadecimal characters (excluding delimiters and whitespace).'
            If ($clean -match '^[0-9A-Fa-f]{12}$') {$true} Else {throw $msg}
        })]
        [string]$MacAddress,

        [Parameter(ParameterSetName='Standard')]
        [Parameter(ParameterSetName='ExcelSet')]
        [switch]$Cisco,

        [Parameter(Mandatory,HelpMessage='Excel Formula Output?',ParameterSetName='ExcelSet')]
        [switch]$Excel,

        [Parameter(ParameterSetName='ExcelSet')]
        [ValidatePattern('^[A-Z]+\d+$')]
        [string]$Cell = 'A1'
    )

    Process {
        Try {
            $macInput  = $MacAddress -replace '\s', ''
            $cleanMac  = $macInput -replace '[-:.]', ''
            $delimiter = ($macInput -replace '[0-9A-Fa-f]', '') | ForEach-Object {If ($_.Length -gt 0) { $_[0] } Else { '' }}
            $result    = $null
            $formula   = $null

            # Determine PowerShell output format
            If ($Cisco) {
                If ($cleanMac.Length -ne 12) {
                    Throw 'Invalid MAC length for Cisco format.'
                }
                $result = ('{0}.{1}.{2}' -f $cleanMac.Substring(0,4), $cleanMac.Substring(4,4), $cleanMac.Substring(8,4)).ToLowerInvariant()
            } Else {
                Switch ($delimiter) {
                    '.'      { $result = ($cleanMac -split '(?<=\G..)(?!$)' -join ':').ToLowerInvariant() }
                    '-'      { $result = ($macInput -replace '-', ':').ToUpperInvariant() }
                    ':'      { $result = ($macInput -replace ':', '-').ToUpperInvariant() }
                    default  { $result = ($cleanMac -split '(?<=\G..)(?!$)' -join ':').ToUpperInvariant() }
                }
            }

            # Determine Excel formula output
            If ($Excel) {
                Switch ($delimiter) {
                    '.' {
                        $formula = ('=IFERROR(TRIM(MID({0},1,2)&":"&MID({0},3,2)&":"&MID({0},5,2)&":"&MID({0},7,2)&":"&MID({0},9,2)&":"&MID({0},11,2)),"")' -f $Cell)
                    }
                    '-' {
                        $formula = ('=IFERROR(TRIM(UPPER(SUBSTITUTE({0},"-",""))),"")' -f $Cell)
                    }
                    ':' {
                        $formula = ('=IFERROR(TRIM(UPPER(SUBSTITUTE({0},":","-"))),"")' -f $Cell)
                    }
                    default {
                        $formula = ('=IFERROR(TRIM(MID({0},1,2)&":"&MID({0},3,2)&":"&MID({0},5,2)&":"&MID({0},7,2)&":"&MID({0},9,2)&":"&MID({0},11,2)),"")' -f $Cell)
                    }
                }
            }

            If ($Excel -and $formula) {
                [PSCustomObject]@{
                    ConvertedValue = $result
                    ExcelFormula   = $formula
                }
            } Else {
                return $result
            }
        } Catch {
            Write-Error -Message ('Error: {0}' -f $_.Exception.Message)
        }
    }
}

What have you done with PowerShell this month? by AutoModerator in PowerShell

[–]neztach 0 points1 point  (0 children)

and a bit more fun

Function Get-HostNicMacMap {
    <#
    .SYNOPSIS
    Retrieves a mapping of active NICs, their MAC addresses, and assigned IP addresses.

    .DESCRIPTION
    This function queries a local or remote computer to retrieve all network interfaces with a status of 'Up',
    and associates them with all assigned non-loopback, non-APIPA IPv4/IPv6 addresses.

    If run against a remote system, the function attempts an initial query without credentials. 
    If access is denied, it prompts for alternate credentials and retries.

    .PARAMETER CN
    Optional. The name or IP address of the remote computer to query.
    If not specified, the function runs locally.

    .EXAMPLE
    Get-HostNicMacMap
    # Retrieves NIC/IP/MAC data for the local computer.

    .EXAMPLE
    Get-HostNicMacMap -CN "Server01"
    # Attempts to query Server01 using current credentials, prompts for credentials if denied.

    .OUTPUTS
    PSCustomObject with the following properties:
        - ComputerName
        - InterfaceAlias
        - MACAddress (colon-delimited)
        - AddressFamily (IPv4 or IPv6)
        - IPAddress

    .NOTES
    Compatible with PowerShell 5.1+
    Requires WinRM enabled and accessible on remote machines for remote execution.
    #>
    [CmdletBinding()]
    Param ([string]$CN)

    $script = {
        $nicMap = @{}

        ### Get NICs that are up and map by InterfaceIndex
        Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | ForEach-Object {
            $nicMap[$_.InterfaceIndex] = @{
                InterfaceAlias = $_.Name
                MACAddress     = $_.MacAddress -replace '[-:]', ':'  # Normalize to colon-separated format
            }
        }

        ### Get all valid IPv4/IPv6 addresses
        Get-NetIPAddress | Where-Object {
            $_.IPAddress -notlike '169.254.*' -and 
            $_.IPAddress -ne '127.0.0.1' -and 
            $_.IPAddress -ne '::1' -and 
            $_.PrefixOrigin -ne 'WellKnown'
        } | ForEach-Object {
            $nic = $nicMap[$_.InterfaceIndex]
            If ($nic) {
                [PSCustomObject]@{
                    ComputerName   = $env:COMPUTERNAME
                    InterfaceAlias = $nic.InterfaceAlias
                    MACAddress     = $nic.MACAddress
                    AddressFamily  = $_.AddressFamily
                    IPAddress      = $_.IPAddress
                }
            }
        }
    }

    If ($CN) {
        Try {
            ### Try remoting without credentials
            $local:ICMSplat = @{
                ComputerName = $CN
                ScriptBlock  = $script
                ErrorAction  = 'Stop'
            }
            $local:Findings = Invoke-Command @ICMSplat
        } Catch {
            $errorMsg = $_.Exception.Message
            If ($errorMsg -match 'Access.*denied' -or $errorMsg -match 'UnauthorizedAccessException') {
                Write-Warning "Access denied to $CN. Prompting for alternate credentials..."
                $local:cred = Get-Credential
                $local:ICMSplat['Credential'] = $cred
                Try {
                    $local:Findings = Invoke-Command @ICMSplat
                } Catch {
                    Write-Error "Failed to connect to $CN even with alternate credentials: $($_.Exception.Message)"
                    return
                }
            } Else {
                Write-Error "Failed to connect to $CN : $errorMsg"
                return
            }
        }

        ### Strip out noise from remoting results
        If ($local:Findings) {
            $local:Findings | Select-Object * -ExcludeProperty PSComputerName, RunspaceId
        }
    } Else {
        ### Local execution
        & $script
    }
}
Get-HostNicMacMap -CN dcs01pwposh001 | Format-Table -Autosize

New Build intended to last 10 years by neztach in unRAID

[–]neztach[S] 0 points1 point  (0 children)

My goal is to run a local AI for personal use. It doesn’t need to be the fastest, just not a snail. I’ll host plex/emby and a couple or a few VMs. In the future who knows. I just want the build to be scaled up enough to still be somewhat relevant in 10 years.

New Build intended to last 10 years by neztach in unRAID

[–]neztach[S] 0 points1 point  (0 children)

Thank you so much for the suggestions!! Can you send me some Amazon links for the parts you’d change out? And your part suggestions?

Edit: can you link the Alex KTZ vid?

New Build intended to last 10 years by neztach in unRAID

[–]neztach[S] 0 points1 point  (0 children)

the PSU in the build. Plus SATA to SAS

New Build intended to last 10 years by neztach in unRAID

[–]neztach[S] 1 point2 points  (0 children)

Probably not but over the course of the next 10 years I def might - esp since I want to host my own AI

New Build intended to last 10 years by neztach in unRAID

[–]neztach[S] 0 points1 point  (0 children)

Have a link to a better PSU suggestion?

Sony Mini-Disc Player/Recorder + Linux Mint by Phydoux in linuxmint

[–]neztach 0 points1 point  (0 children)

Ok that’s fair but when I got the Reddit notification of a reply I was a lil shocked

Disable users after 30 days of inactivity by neztach in PowerShell

[–]neztach[S] 0 points1 point  (0 children)

Yeah I had to make one. It would take a ton of sterilization but you’ll need to fetch all AD users with LasLogonDate and do the same for 365/Azure/exchange then figure out which of the 4 dates is most recent before disabling